NAME
fhist - file history
SYNOPSIS
fhist filename... option...
fhist -Help
fhist -VERSion
DESCRIPTION
The fhist program is used to keep track of the successive versions of a
file. Using this program, you can remember all of your changes to a
file, and get back any one of the old versions. The uses of this
ability are:
1. You can make a series of tentative edits to the file, and if
necessary back up to the last "good" edit.
2. You can delete old subroutines and code from your file which are
obsolete, but still be able to get them back in the future in case
a need for them arises.
3. You can compare two versions of the file to see how you fixed some
old problem, so that you can check up on the correctness of the fix
at a later date.
4. You get a record of your remarks for each version, so that you can
quickly know what bugs were fixed, and what features were
implemented.
5. The date the file was last edited can be automatically stored in
the file.
The fhist program manipulates modules. A module is simply any text
file that you are interested in keeping versions of. For example, a
source file doit.c is a module, and so is a documentation file
howto.doc. The module name includes the suffix of the file (as in the
above examples). However, pathnames are not part of a module name, so
that /usr/dbell/bar.c cannot be a legal module name. A module name is
limited to 12 characters since the fhist program needs two extra
characters for its own purpose.
Keyword Substitution
It is possible to have information about the state of the file inserted
into the file. See the -Modify and -No‐Keywords options, below, for
more infromation.
OPTIONS
The following options are understood:
-Path pathname
Modules are stored in a directory, called the module storage
directory. The default directory is FHIST, and therefore is
located relative to your current directory. This is convenient
when you are in a directory containing many modules, and you
want a local storage directory to contain just those modules.
If you use the -p option, then you can locate the storage
directory anywhere you choose. This is useful if you choose to
have a common storage directory for all of your files,
independent of where they actually are used.
The files inside of the storage directory should not be changed
by you. Doing so will probably corrupt your edit history,
causing errors when you extract old revisions. For your
information, though, each module is stored as two files in the
directory. The one with the .s suffix is a copy of the newest
version of the module, with one extra line at the beginning.
The one with the .e suffix is the edit history of the module,
and contains the information needed to extract previous
revisions of the module. Thus if the edit history is ever
corrupted, you will at least have the most recent version of
the module.
-MaKe_Path
This option may be used to request that the path directory be
created automatically if it does not yet exist. This works for
both the directory specified by the -Path option, and for the
default. Intermediate directories will also be created if
necessary.
-BINary This option may be used to specify that the file is binary,
that it may contain NUL characters. It is essential that you
have consistent presence or absence of the -BINary option for
each file when combined with the -CReate, -Update,
-Conditional_Update and -Extract options. Failure to do so
will produce inconsistent results. Note: this is different
behaviour to the fcomp(1) option of the same name. Note: the
-BINary option does not imply the -No‐Keywords option.
-CReate
To use the fhist program for the first time, you need to create
your storage directory. Therefore, cd to the directory where
you want it to be, which is probably the directory containing
the modules you want to save the revisions of. Then create the
directory FHIST (or some other name if you don’t want to use
the default name).
To start using a module under fhist, you must first use the
-CReate option. This creates the initial edit for that module
in the storage directory, with the contents of the specified
module as the initial edit. Thus, if you have a source file
prog.c, then the command:
fhist prog.c -create
creates the initial edit of the module. As part of this
process, you are asked to provide remarks about the file.
These remarks can be seen later using the -List option
(described below). After the remarks have been typed, the
contents of the file are then saved. You can then delete the
file prog.c if desired, and fhist would be able to recreate it
later. Or you can leave it there as the working copy of the
module.
The -CReate option may be combined with the -Update or
-Conditional_Update options to create the file if required.
-Update
To save another revision of the module, you use the -Update
option. This updates the files in the storage directory to
include the latest changes. Remarks are again asked for so
that you can document why you made this edit. Thus, to
continue the example, after editing prog.c, the command:
fhist prog.c -u
will save the changes as a new edit. This command compares the
newest version of the module to the previous version, saves the
differences in the .e file, and copies the new source to the .s
file. At this point, you can once again delete the prog.c file
if desired, and later get back either of the two versions of
the program.
The fhist program handles quota or disk full problems during a
create or update operation without damage occurring to the edit
history files. If an edit cannot be completed because of such
problems, the edit is backed out completely, and you will get
an error message about the disk problem. There is no need for
any error recovery in this case, other than retrying the update
when more disk space is available. The fhist program also
disables signals during the critical file operations, so you do
not have to worry about damaging the edit history files because
of attempts to quit out of the program.
The -CReate option may be combined with the -Update or
-Conditional_Update options to create the file if required.
-Input filename
In either the -CReate or -Update options, the file containing
the new version of the module defaults to the same name as the
module. In the example, the module prog.c was created and
updated from the data in the file prog.c. When you wish the
data to come from some other file, you can use the -Input
option, which specifies the input file to use for the data.
For example, if you wanted to update prog.c, but from a
filename called newprog.c, then the command:
fhist prog.c -u -i newprog.c
would save a new revision of module prog.c, but with the data
that was in the file newprog.c. In this case, the file prog.c
does not have to exist, and isn’t referenced even if it did
exist. Again, once the update is complete, you could delete
the newprog.c file if desired and then later you can retrieve
its contents.
-Remarks
Remarks can be read from a file instead of from the terminal.
The -Remarks option can be used to specify a file name
containing the remarks. If there is no file name following the
-Remarks option, then no remarks at all are used. The command:
fhist prog.c -u -r
would create a new revision of prog.c without asking for or
saving any remarks about the edit.
-Remark_String text
It is also possible to specify the remarks directly on the
command line. You may only use this option once.
-Extract [ edit ]
To retrieve a previous revision of a module, you specify the
name of the module and use the -Extract option to specify the
edit number you want retrieved. Edit numbers are assigned
sequentially starting with 1. Thus the initial version of the
module has edit number 1, the first revision has edit number 2,
and so on until the latest revision. If the -Extract option is
not used, or if no edit number is supplied for it, then the
latest edit number is extracted. Therefore, this is the
default action if no options at all are specified.
Edit numbers can also be zero, negative, or be a name with an
optional offset. The number zero represents the latest edit
number, and negative numbers indicate edit numbers backwards
from the latest edit number. Edit names represent edit numbers
whose name had been set by using the -Name option. For
example, if edit number 10 was associated with the name foo,
then the edit name foo represents 10, foo4 represents edit
number6, and foo+2 represents edit number 12. The special
reserved names oldest and newest refer to the oldest and newest
versions of the module in the edit history.
As an example of retrievals, assume that you have saved ten
versions of the module prog.c. The following commands will
then extract the versions of the file with the specified edit
numbers:
fhist prog.c
version 10 (the latest)
fhist prog.c -e 9
version 9 (the version just prior)
fhist prog.c -e oldest
version 1 (the oldest version)
fhist prog.c -e -2
version 8 (latest version - 2)
The output filename is again defaulted to the module name. So
when the module prog.c is extracted, the specified version of
the module is written to the prog.c file.
In order to prevent accidental overwriting of a file, the fhist
program will by default ask you if overwriting is permitted if
that would occur. A common mistake is to edit prog.c, and then
try to update the module, but forget to specify the -u option.
Then the fhist program would try to extract the newest version
of the module, and thus overwrite the file with the new
changes. Asking the question allows you to notice your
mistake, and prevent the overwriting.
-Output filename
You can change the output filename using the -Output option.
Thus, the command:
fhist prog.c -o newprog.c
will extract the latest version of the module prog.c, and put
it into the file newprog.c. Once again, the file "prog.c" is
ignored, whether or not it existed.
-Force_Write
This option will force overwriting of the file, thus never
asking you if overwriting is permitted. This is often useful
in shell scripts, or when you are sure that you want to
overwrite any existing file.
-No_Write
This option is the no‐overwrite option, and will cause any
existing files to not be overwritten, again without asking you.
This is useful if you already have some of the modules in your
directory, and you want to extract the rest of the modules
without overwriting the ones you already have. Specifying both
-Fore_Write and -No_Write is an error.
-Terminal [ edit ]
This option is used to output an extracted module to the
standard output, instead of writing it to a file. This is
useful in order to view the beginning of a version of the file.
This can be interrupted if you do not want to see the whole
file.
-Modify number
When extracting a file, the fhist program looks for and updates
special character sequences in the first few lines of the file.
These special sequences are used for documentation purposes,
such as describing the edit number the file is from. For speed
of extraction and updating, these sequences are usually limited
to the first 25 lines of the file, since the fhist program then
does not have to examine the entire file. The -Modify option
can be used to change the number of lines to be modified from
the default value of 25. Specifying zero totally disables the
special character sequences, whereas specifying a very large
number will cause the sequences to be checked for each line of
the file (and thus slow the fhist program down).
Each special sequence is of the form [# keyword value, keyword
value, ..., keyword value #] , where each keyword describes an
item, and each value is the value for the preceding keyword.
The keywords can be in upper or lower case, or both. The
single space following the [#, following each comma, and
preceding the #] must be present. If the sequence is wrong, an
unknown keyword is used, the line is longer than 200
characters, or more than four keywords are used, then the whole
line will not be changed. The current keywords which can be
used are the following:
edit The edit number
date The date that the edit was created
user The user name of the user who created the edit
module The module name
In order to use this special character sequence, you simply
insert it into your module inside of a comment (within the
first few lines). When this is done, the value parts of the
sequence can be null. For example, if you want to put a
special sequence into a program called delete.c, then you could
edit the first few lines as follows:
/*
* Delete - program to delete files
* [# Edit, Date #]
*/
When an extract is done, the proper edit number and date are
automatically inserted as the new values. Thus, if you extract
edit 23 of the module delete.c which had been created on 8
August 89, then the resulting file would begin:
/*
* Delete - program to delete files
* [# Edit 23, Date 8‐Aug‐89 #]
*/
When updating a module, it is never necessary to edit these
sequences, as any old values will be removed and replaced with
the new ones. Also, when using the -d or -du options
(described below), lines with these sequences compare as if the
values were null, and thus will not cause spurious differences.
During an update, the special character sequences are read and
any edit value found is compared against the current edit
number of the module. If they differ, then the update fails.
This provides an interlock check for the case of two users
extracting the same version of a file, editing it, and then
both updating it without knowledge of each other. In this
case, the second user would fail, and then he can merge his
edits with the previous user’s edit and then retry the update.
This checking is disabled if there is no special character
sequence containing the edit keyword, the edit number value is
null, or if the -Forced_Update option is used to indicate that
the check is not needed.
-No_Keywords
This option may be used to disable the use of the keyword
special character sequences described above. Text containing
keyword sequences is treated as plain text. Note: the
-No_Keywords option does not imply the -BINary option.
-Name string
This option is used to associate a name for the newest version
of a module. It can be given along with the -CReate, -Update,
or -Difference_Update options, to specify a name for the new
version of the module. It can also be given by itself in order
to specify a name for the newest version of a module. Each
edit number can have many names associated with it, so this
will not remove any previously defined name for the edit. This
option is useful to correlate many modules together. For
example, when a new version of a program is ready to be
released, you could give each module of the program the same
name release1. Then in the future, you can recreate the
sources making up that release by extracting the edits with the
name release1 for every module. Edit names cannot begin with a
digit, and cannot contain plus or minus signs. These rules
prevent ambiguous parsing of edit numbers for the -Extract,
-Terminal, -ALL, and -List options.
-List [ edit1 [ edit2 ]]
This option prints a list of edits for the module, giving the
user name, date, user remarks, and names specified for the
edits. If no edit number is supplied, then all edits are
printed in reverse order. If a single edit number is supplied,
then only that edit number is printed. If two edit numbers are
supplied, then all edits in the specified range are printed.
The output from this option defaults to the terminal. You can
use the -Output option to save the results to a file.
-Difference [ edit1 [ edit2 ]]
This option is used to display the differences between two
versions of a module, or a file and a version of a module.
There are three modes for this action, depending on how many
edit numbers are supplied. These modes are illustrated by the
following examples:
fhist foo.c -d
Compare latest version against file "foo.c"
fhist foo.c -d 3
Compare version 3 against file "foo.c"
fhist foo.c -d 3 4
Compare version 3 against version 4
This option accepts the -Input option to specify the file to be
compared. When using the -Difference option, the output
defaults to the terminal. Therefore, you must use -Output if
you wish the differences saved to a file. Using -Quick with
-Difference will only output a quick summary of the changes,
instead of the detailed changes. This summary only supplies
the number of lines inserted, deleted, and unchanged between
the files. Using -What with -Difference will display all of
both files, showing in detail what the differences are using
change bars.
The -Difference option may need to write one or two temporary
files in order to extract old versions of a module to be
compared. These files have names like T$n_nnn . They are
deleted again just before differences are output, so that
stopping the output before it is complete will not leave these
files around. The temporary files are usually written to the
current directory. If this is not reasonable because of
permission or quota problems, then you can specify the
directory for writing the temporary files into. This is done
by defining the TMPDIR environment variable to be the path of
the directory.
-Difference_Update
This option combines the effects of the -Difference and -Update
options. It displays the differences between a file and the
latest version of a module. If there are any differences, it
then proceeds to perform an update of the module with that
file, asking for remarks as usual. This option is very useful
when used with wildcarded module names. Then you can update
just those modules which were changed by an edit session, and
see the changes for each module before typing the appropriate
remark for each module.
You may specify both of the -Difference and -Update options, or
you may use this option. The results are identical.
-Conditional_Update
This option conditionally updates a module. That is, it will
only do an update if there are any differences between a file
and the latest version of a module. This is convenient when
related changes are made to many modules in a directory, and
one command using wildcards can update just those modules that
were changed.
The -CReate option may be combined with the -Update or
-Conditional_Update options to create the file if required.
-CLean
This option is used to remove files which match the newest
versions of modules. If a file exists which matches the newest
version of a module, then the file is deleted, otherwise it is
kept. This option is used to clean up a work directory after
building a new version of a product. This option is especially
useful when used with the -ALL option. It will also accept the
-Input option to specify a directory containing the files to be
cleaned.
-CHeck
This option is used to find out if a file does not match the
latest version of a module. If so, a message is given. If the
file does match, no output occurs. This option is thus useful
to determine which files have been modified and in need of
updating. The -ALL option is defaulted for this option, since
it is usually used for all modules. For example,
fhist -CHeck
will report on all files which are different than the latest
modules. If -Quick is specified, then the output will consist
of the module names with no other output. This is useful for
the backquote operator in shell scripts for referencing the
modules which are out of date. The -CHeck option will also
accept the -Input option.
-PRune edit
This option is used to permanently remove early edits from an
edit history. This is useful if you wish to cut down on the
amount of disk space taken by an edit history file, or when you
want to start another release of a file, and want a copy of the
edit history file for that new release. The option takes an
edit number to preserve, and all edits in the edit history file
before that edit are deleted, and can no longer be referenced.
For example, to keep only the current edit plus the previous 10
edits of the module file, you could use the command:
fhist file -prune -10
Since the -PRune option is unrecoverable (unless backup files
are available), the fhist program asks the user to verify that
the prune is really wanted. The -Forced_Update option can be
used to bypass this verification.
-ALL
This option can be used with any of the action options. It
means perform the operation for all modules in the module
storage directory. Alternatively, you can specify multiple
module names on the command line, and the actions will be
performed with those modules. You cannot specify both -ALL and
module names.
When using multiple modules or the -ALL option, the -Input and
-Output options have a slightly different meaning. In these
cases, the -Input and -Output arguments are a directory name
which contains filenames with the same name as the module
names. If the argument is not a directory, then an error is
given. This feature is useful for example, to extract all the
modules and place them into some remote directory, as in:
fhist -all -e -o tempdir
You should be careful when specifying numeric edit numbers for
multiple modules. Most probably, a particular edit number is
not appropriate for multiple modules, since changes
corresponding to a particular edit number are not usually
related. Using named edits avoids these problems. As an
example, if you wanted to extract every module which had an
edit that was named rev3, then you could use the command:
fhist -all -e rev3
Some other useful examples of commands which use multiple
modules are:
fhist *.c -create
fhist -check -all
fhist -cu -all
-Verbose
This option can be specified with any other action, and outputs
status information about the progress of the action. This is
useful for debugging of problems, or just for amusement when
the system is slow or a large file is being processed. It
accepts a numeric argument to indicate the verbosity for
output. The levels are as follows:
0 No output at all (except for errors).
1 Single‐line output describing action (default).
2 Detailed status as action proceeds.
-Help
Give some help on how to use the fhist program.
-VERSion
Show what version of fhist is running.
All options may be abbreviated; the abbreviation is documented as the
upper case letters, all lower case letters and underscores (_) are
optional. You must use consecutive sequences of optional letters.
All options are case insensitive, you may type them in upper case or
lower case or a combination of both, case is not important.
For example: the arguments "-help, "-HELP" and "-h" are all interpreted
to mean the -Help option. The argument "-hlp" will not be understood,
because consecutive optional characters were not supplied.
Options and other command line arguments may be mixed arbitrarily on
the command line.
The GNU long option names are understood. Since all option names for
fhist are long, this means ignoring the extra leading ’-’. The
"-option=value" convention is also understood.
FILE NAME EXPANSION
As a convenience, if a pathname begins with a period and a environment
variable exists with that name, then the value of the environment
variable will be used as the actual pathname. For example, if a
environment variable of .FOO has the value this.is.a.long.name, then
the command
fhist -o .FOO
is actually equivilant to the command
fhist -o this.is.a.long.name
If you want to prevent the expansion of a pathname which begins with a
period, then you can use an alternate form for the pathname, as in:
fhist -o ./.FOO
BINARY FILES
In general, fhist can handle all text files you throw at it, even
international text with unusual encodings. However, fhist is unable to
cope elegantly with files which contain the NUL character.
The fcomp(1) program simply prints a warning, and continues, you need
to know that it converts NUL characters into an 0x80 value before
performing the comparison.
The fmerge(1) program also converts the NUL character to an 0x80 value
before merging, after a warning, and any output file will contain this
value, rather than the original NUL character.
The fhist(1) program, however, generates a fatal error if any input
file contains NUL characters. This is intended to protect your source
files for unintentional corruption. Use -BINary for files which
absolutely must contain NUL characters.
EXIT STATUS
The fhist program will exit with a status of 1 on any error. The fhist
program will only exit with a status of 0 if there are no errors.
REFERENCES
This program is based on the algorithm in
An O(ND) Difference Algorithm and Its Variations, Eugene W.
Myers, TR 85‐6, 10‐April‐1985, Department of Computer Science,
The University of Arizona, Tuscon, Arizona 85721.
See also:
A File Comparison Program, Webb Miller and Eugene W. Myers,
Software Practice and Experience, Volume 15, No. 11, November
1985.
COPYRIGHT
fhist version 1.18.D001
Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Peter Miller;
This program is derived from a work
Copyright (C) 1990 David I. Bell.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
AUTHORS
Peter Miller Web: http://miller.emu.id.au/pmiller/
/\/\* E‐Mail: pmiller@opensource.org.au
David I. Bell Web: http://www.canb.auug.org.au/~dbell
E‐Mail: dbell@canb.auug.org.au