| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056 |
- #! /usr/local/bin/bash
- #
- # neartool - a Clearcase emulator for working off-line.
- #
- # Usage:
- #
- # neartool mkelem [-c "comment"] [-nc] [-eltype type] filename
- # Marks a new file as a versioned element and checks it out.
- #
- # neartool mkdir [-c "comment"] [-nc] new_dir
- # Creates a new Clearcase directory.
- #
- # neartool mv old-file new-file
- # Renames or moves a versioned element.
- #
- # neartool mv file1 file2 file3 ... to-dir
- # Moves a number of versioned elements into a new directory.
- #
- # neartool (co|checkout) [-c "comment"] [-nc] filename
- # "checks out" a file by saving its current version and making a new
- # version writable. The file is also marked as "checked-out".
- #
- # neartool (unco|uncheckout) filename
- # Reverses the effect of the previous checkout.
- #
- # neartool (ci|checkin) [-c "comment"] [-nc] filename
- # Marks the file as "checked in" and finalizes its most recent
- # version, making it read-only.
- #
- # neartool revert filename
- # Backs up a version on a checked-in filename.
- #
- # neartool revertall filename
- # Reverts a filename all the way to its original state as extracted
- # from the Clearcase vobs.
- #
- # neartool collapse filename
- # Collapse all versioning information and mark the file as
- # "checked-in" and merged as is. Presumably this should only be
- # done after merging the changes back into the actual clearcase
- # vobs.
- #
- # neartool rmname filename
- # Removes a filename from a Clearcase directory.
- #
- # neartool find root [opts]
- # Finds all elements with versions at root or below. The options
- # are ignored. This is just a hack to support ctihave.
- #
- # neartool (lsco|lscheckout) [-l] file1 file2 file3...
- # Lists which of the files are currently checked out, if any. If no
- # filenames are given, lists all of the checked out files in the
- # current directory. The -l option is ignored.
- #
- # neartool diff [-pre] filename
- # Performs a diff between the indicated filename and its previous
- # version. The option -pre is ignored.
- #
- # neartool xdiff [-pre] filename
- # Performs an xdiff between the indicated filename and its previous
- # version. The option -pre is ignored.
- #
- #ENDCOMMENT
- #
- # get_nth_param ( param-no param1 param2 param3 ... )
- #
- # Sets the variable nth_param to the value of the parameter
- # corresponding to param-no.
- #
- function get_nth_param {
- local param_no=$1
- shift $param_no
- nth_param=$1
- }
- #
- # get_last_param ( param1 param2 param3 ... )
- #
- # Sets the variable last_param to the value of the last non-blank
- # parameter.
- #
- function get_last_param {
- last_param="$1"
- shift
- while [ ! -z "$*" ]; do
- last_param="$1"
- shift
- done
- }
- #
- # format_comment ( comment_str )
- #
- # Writes the parameter -c '$comment_str', or -nc if the comment is
- # empty, to the standard output. Handles nested quotes appropriately.
- #
- function format_comment {
- local comment="$*"
- if [ -z "$comment" ]; then
- echo "-nc"
- else
- # Escaping single quotes inside a single-quoted string doesn't
- # seem to work too reliably. Instead, we'll just remove single
- # quotes. So there.
- # This absurd number of backslashes is needed to output a single
- # backslash through all this nesting.
- # echo "-c '"`echo $comment | sed "s/'/\\\\\\\\'/g"`"'"
- echo "-c '"`echo $comment | sed "s/'//g"`"'"
- fi
- }
- #
- # list_comments ( dirname basename )
- #
- # Writes to stdout any comments associated with checked-out versions of
- # the indicated file, in order.
- #
- function list_comments {
- local dirname=$1
- local basename=$2
- local filename=$dirname/$basename
- local file comment version
- if [ -f $dirname/.ct0.$basename ]; then
- # Now look for comments, in version-number order.
- # We use a series of ls commands so we don't try to sort the
- # filenames between the one-, two-, and three-digit version
- # numbers.
- for file in `(cd $dirname; ls .ct[0-9].$basename; ls .ct[0-9][0-9].$basename; ls .ct[0-9][0-9][0-9].$basename) 2>/dev/null`; do
- version=`echo $file | sed "s/^\.ct\([0-9]*\).*$/\1/"`
- comment=$dirname/.ct${version}comment.$basename
- if [ -f $comment ]; then
- sed s'/^/ /' <$comment
- fi
- done
- fi
- }
- #
- # get_highest_version ( dirname basename )
- #
- # Sets the variable $version to the numeric value that is the highest
- # existing version number defined for the given filename. If the
- # filename has no previous version numbers, sets $version to -1.
- #
- function get_highest_version {
- local dirname=$1
- local basename=$2
- local filename=$dirname/$basename
- local last
- if [ -f $dirname/.ct0.$basename ]; then
- # If there are any versions at all, get the highest-numbered one
- # and return it.
- # We use a series of ls commands so we don't try to sort the
- # filenames between the one-, two-, and three-digit version
- # numbers.
- last=`(cd $dirname; ls .ct[0-9].$basename; ls .ct[0-9][0-9].$basename; ls .ct[0-9][0-9][0-9].$basename) 2>/dev/null | tail -1`
- version=`echo $last | sed "s/^\.ct\([0-9]*\).*$/\1/"`
- else
- # If there aren't any versions yet, the highest-numbered existing
- # version number is -1.
- version=-1
- fi
- }
-
- #
- # is_ctinternal ( basename )
- #
- # Returns success if the filename matches one of the internal filenames
- # generated by this script, failure if it is a perfectly ordinary
- # non-ct file.
- #
- function is_ctinternal {
- local basename=$1
- case $basename in
- .ct[0-9].*|ct[0-9][0-9].*|ct[0-9][0-9][0-9].*|\
- .ct[0-9]comment.*|.ct[0-9][0-9]comment.*|.ct[0-9][0-9][0-9]comment*|\
- .ctco.*|.ctnew.*)
- return 0;;
- esac
- return 1
- }
-
- #
- # is_install_dir ( dirname )
- #
- # Returns success if the directory is any of the directories known to
- # be install directories, such as inc, lib, lib/ss, etc.
- #
- function is_install_dir {
- local dirname=$1
- get_rel_dir $projroot $dirname
- case $rel_dir in
- inc) return 0;;
- inc/*) return 0;;
- include/*) return 0;;
- lib) return 0;;
- lib/*) return 0;;
- esac
- return 1
- }
- #
- # rm_all_ctinternals ( dirname basename )
- #
- # Removes all the ctinternal files associated with the indicated file.
- #
- function rm_all_ctinternals {
- local dirname=$1
- local basename=$2
-
- rm -f $dirname/.ct[0-9].$basename
- rm -f $dirname/.ct[0-9][0-9].$basename
- rm -f $dirname/.ct[0-9][0-9][0-9].$basename
- rm -f $dirname/.ct[0-9]comment.$basename
- rm -f $dirname/.ct[0-9][0-9]comment.$basename
- rm -f $dirname/.ct[0-9][0-9][0-9]comment.$basename
- rm -f $dirname/.ctnew.$basename
- rm -f $dirname/.ctco.$basename
- }
- #
- # sane_filename ( dirname basename )
- #
- # Performs some sanity checks on the filename. If the file is
- # unusable, exits the script with a status of 1.
- #
- function sane_filename {
- local dirname=$1
- local basename=$2
- local filename=$dirname/$basename
- if [ -z "$basename" ]; then
- echo "Filename unspecified." 1>&2
- exit 1
- fi
- if is_ctinternal $basename; then
- echo "$filename is an internal filename and should not be checked out." 1>&2
- exit 1
- fi
- # It's easy to accidentally attempt to check something out from the
- # inc directory. Let's detect this.
- if is_install_dir $dirname; then
- echo "$basename is in an install directory." 1>&2
- echo "It should probably not be checked out." 1>&2
- exit 1
- fi
- if [ -d $filename ]; then
- # Let's just quietly ignore directories. If we issue the warning
- # statement, it makes ctaddtgt and ctaddpkg seem like they're
- # failing.
- # echo "Cannot operate on directories." 1>&2
- exit 0
- fi
- }
- #
- # get_fullpath ( local_dir )
- #
- # Sets $fullpath to the fully-qualified pathname associated with $local_dir.
- #
- function get_fullpath {
- local local_dir=$1
- if [ -z "$local_dir" ]; then
- fullpath=`pwd`
- else
- if [ ! -d "$local_dir" ]; then
- echo "Invalid directory: $local_dir" 1>&2
- exit 1
- fi
- # If we use pwd instead of /bin/pwd, $PWD will be used, which will give
- # the wrong answer
- fullpath=`(cd $local_dir; /bin/pwd)`
- fi
- }
- #
- # get_rel_dir ( root_dir local_dir )
- #
- # Sets $rel_dir to the string which represents $local_dir relative to
- # $root_dir. This is a simple string-prefix operation, and could fail
- # in some obscure cases.
- #
- function get_rel_dir {
- get_fullpath $1
- local root_dir=$fullpath
- get_fullpath $2
- local local_dir=$fullpath
- # Now remove the initial prefix.
- if [ "$root_dir" = "$local_dir" ]; then
- rel_dir="."
- else
- rel_dir=`echo $local_dir | sed 's:^'$root_dir/'::'`
- if [ "$rel_dir" = "$local_dir" ]; then
- echo "$local_dir is not a directory within $root_dir." 1>&2
- exit 1
- fi
- fi
- }
- function ctmkelem {
- local filename dirname basename
- local comment eltype
- eltype=text_file
- while getopts c:n:e: flag; do
- case $flag in
- c) comment="$OPTARG";;
- n) comment="";;
- e) case $OPTARG in
- ltype) get_nth_param $OPTIND "$@"
- eltype=$nth_param
- OPTIND=`expr $OPTIND + 1`;;
- *) echo Invalid switch -e$OPTARG
- exit 1;
- esac;;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
- sane_filename $dirname $basename
- ctco=$dirname/.ctco.$basename
- if [ -f $ctco ]; then
- echo "$filename is already checked out." 1>&2
- exit 1
- fi
- if [ ! -f $filename ]; then
- # If the file doesn't exist, create it.
- echo -n "" >$filename
- fi
- get_highest_version $dirname $basename
-
- if [ $version -ne -1 ]; then
- echo "$filename already has versions." 1>&2
- exit 1
- fi
-
- if [ ! -w $filename ]; then
- echo "$filename has no write permission, it's probably already a versioned element." 1>&2
- exit 1
- fi
-
- # Create a ctnew file to indicate the file is newly created.
- ctnew=$dirname/.ctnew.$basename
- echo $eltype >$ctnew
- chmod uga-w $ctnew
-
- # Now "check out" the new filename by creating an empty first version.
-
- next=$dirname/.ct0.$basename
- nextcomment=$dirname/.ct0comment.$basename
-
- if [ ! -z "$comment" ]; then
- echo $comment >$nextcomment
- chmod uga-w $nextcomment
- fi
- echo -n "" > $next
-
- date >$ctco
- done
- }
- function ctmkdir {
- local filename dirname basename
- local comment
- while getopts c:n: flag; do
- case $flag in
- c) comment="$OPTARG";;
- n) comment="";;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
- if [ -z "$basename" ]; then
- echo "Filename unspecified." 1>&2
- exit 1
- fi
- if is_ctinternal $basename; then
- echo "$filename is an internal filename and should not be checked out." 1>&2
- exit 1
- fi
- if mkdir $filename; then
- # The directory is successfully made; record this in the
- # Clearcase instructions.
- get_rel_dir $projroot $dirname
- echo "ctco -nc $rel_dir" >>$projroot/.ctcmds
- echo "ctmkdir `format_comment $comment` $rel_dir/$basename" >>$projroot/.ctcmds
- else
- echo "Unable to create directory $filename." 1>&2
- fi
- done
- }
- #
- # do_ctmv ( oldname newname )
- #
- # The implementation of ctmv. This renames a single file, possibly
- # placing it in a new directory.
- #
- function do_ctmv {
- local oldfilename olddirname oldbasename
- local newfilename newdirname newbasename
- oldfilename=$1
- olddirname=`dirname $oldfilename`
- oldbasename=`basename $oldfilename`
- newfilename=$2
- newdirname=`dirname $newfilename`
- newbasename=`basename $newfilename`
- sane_filename $olddirname $oldbasename
- sane_filename $newdirname $newbasename
- if [ ! -f $oldfilename ]; then
- echo "$oldfilename does not exist." 1>&2
- exit 1
- fi
- if [ -f $newfilename ]; then
- echo "$newfilename already exists--remove it first." 1>&2
- exit 1
- fi
- oldctnew=$olddirname/.ctnew.$oldfilename
- if [ ! -f $oldctnew ]; then
- # The filename exists on the actual Clearcase vobs. We need to
- # record the renaming.
- get_rel_dir $projroot $olddirname
- local oldroot=$rel_dir
- get_rel_dir $projroot $newdirname
- local newroot=$rel_dir
- echo "ctco -nc $oldroot" >> $projroot/.ctcmds
- if [ "$oldroot" != "$newroot" ]; then
- echo "ctco -nc $newroot" >> $projroot/.ctcmds
- fi
- echo "ctmv $oldroot/$oldbasename $newroot/$newbasename" >> $projroot/.ctcmds
- fi
- # Now rename our local copy, and all of its version tracking stuff.
- get_fullpath $newdirname
- local newroot=$fullpath
- (cd $olddirname;
- for file in \
- `ls .ct[0-9].$oldbasename \
- .ct[0-9][0-9].$oldbasename \
- .ct[0-9][0-9][0-9].$oldbasename \
- .ct[0-9]comment.$oldbasename \
- .ct[0-9][0-9]comment.$oldbasename \
- .ct[0-9][0-9][0-9]comment.$oldbasename \
- .ctnew.$oldbasename \
- .ctco.$oldbasename \
- $oldbasename 2>/dev/null`; do
- ctprefix=`echo $file | sed 's:'$oldbasename'$::'`
- mv -i $file $newroot/$ctprefix$newbasename
- done)
- }
- function ctmv {
- local source destination
- while getopts "" flag; do
- case $flag in
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- get_last_param "$@"
- destination=$last_param;
- if [ ! -d "$destination" ]; then
- # If we're not moving to a directory, we are renaming a file--and
- # thus we can only allow two parameters.
- source=$1
- shift 2
- if [ ! -z "$*" ]; then
- echo Last filename must be a directory.
- exit 1
- fi
- do_ctmv $source $destination
- else
- # Otherwise, we're moving a slew of files to a directory. Get
- # each filename and move it.
- for source in "$@"; do
- if [ "$source" != "$destination" ]; then
- do_ctmv $source $destination/$source
- fi
- done
- fi
- }
- function ctco {
- local filename dirname basename
- while getopts c:n: flag; do
- case $flag in
- c) comment="$OPTARG";;
- n) comment="";;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
- okflag=y
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- okflag=
- else
- ctco=$dirname/.ctco.$basename
- if [ -f $ctco ]; then
- echo "$filename is already checked out." 1>&2
- okflag=
- else
- if [ -w $filename ]; then
- echo "$filename has write permission, it's probably not a versioned element." 1>&2
- echo "Try neartool mkelem $filename." 1>&2
- okflag=
- fi
- fi
- fi
- if [ ! -z "$okflag" ]; then
- get_highest_version $dirname $basename
- next=$dirname/.ct`expr $version + 1`.$basename
- nextcomment=$dirname/.ct`expr $version + 1`comment.$basename
-
- if [ ! -z "$comment" ]; then
- echo $comment >$nextcomment
- chmod uga-w $nextcomment
- fi
-
- mv $filename $next
- cp $next $filename
- chmod ug+w $filename
-
- date >$ctco
- fi
- done
- }
- function ctunco {
- local ignore filename dirname basename
- while getopts "r:" flag; do
- case $flag in
- r) ignore=;;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
-
- ctco=$dirname/.ctco.$basename
- if [ ! -f $ctco ]; then
- echo "$filename is not checked out." 1>&2
- exit 1
- fi
-
- get_highest_version $dirname $basename
- last=$dirname/.ct$version.$basename
- lastcomment=$dirname/.ct${version}comment.$basename
-
- mv -f $last $filename
- rm -f $lastcomment
- rm $ctco
- touch $filename # For emacs, and correct make behavior.
- done
- }
- function ctci {
- local filename dirname basename
- local comment
- while getopts c:n: flag; do
- case $flag in
- c) comment="$OPTARG";;
- n) comment="";;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
-
-
- ctco=$dirname/.ctco.$basename
- if [ ! -f $ctco ]; then
- echo "$filename is not checked out." 1>&2
- exit 1
- fi
-
- # We touch the file, so emacs will note that it has changed.
- touch $filename
- chmod uga-w $filename
-
- rm $ctco
- done
- }
- function ctrevert {
- local filename dirname basename
- while getopts "" flag; do
- case $flag in
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
-
- ctco=$dirname/.ctco.$basename
- if [ -f $ctco ]; then
- echo "$filename is currently checked out. Use neartool unco $filename." 1>&2
- exit 1
- fi
-
- get_highest_version $dirname $basename
-
- if [ $version -eq -1 ]; then
- echo "$filename has no versions." 1>&2
- exit 1
- fi
-
- last=$dirname/.ct$version.$basename
- lastcomment=$dirname/.ct${version}comment.$basename
-
- mv -f $last $filename
- rm -f $lastcomment
-
- if [ $version -eq 0 ]; then
- ctnew=$dirname/.ctnew.$basename
- if [ -f $ctnew ]; then
- echo "Removing newly created element $filename." 1>&2
- rm -f $ctnew $filename
- fi
- fi
- done
- }
- function ctrevertall {
- local filename dirname basename
- while getopts "" flag; do
- case $flag in
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
-
- ct0=$dirname/.ct0.$basename
- if [ ! -f $ct0 ]; then
- echo "$filename has no versions." 1>&2
- else
- ctnew=$dirname/.ctnew.$basename
- if [ ! -f $ctnew ]; then
- # If we didn't newly create this file, preserve its original version.
- mv -f $ct0 $filename
- fi
- rm_all_ctinternals $dirname $basename
- fi
- done
- }
- function ctcollapse {
- local filename dirname basename
- while getopts "" flag; do
- case $flag in
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
- rm_all_ctinternals $dirname $basename
-
- chmod uga-w $filename
- touch $filename # For Emacs' benefit.
- done
- }
- function ctrmname {
- local filename dirname basename
- while getopts "" flag; do
- case $flag in
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
-
- ctnew=$dirname/.ctnew.$basename
-
- if [ ! -f $ctnew ]; then
- # The filename exists on the actual Clearcase vobs. We need to
- # record the removing.
-
- get_rel_dir $projroot $dirname
- local root=$rel_dir
-
- echo "ctco -nc $root" >> $projroot/.ctcmds
- echo "ctrm $root/$basename" >> $projroot/.ctcmds
- fi
- # Now remove all of the versioned stuff.
- ctcollapse $filename
- # And remove the file itself.
- rm -f $filename
- done
- }
- function ctfind {
- local root=$1
- if [ -z "$root" ]; then
- echo "Specify a starting point of the find." 1>&2
- exit 1
- fi
- find $root -name .ct0.\* -print | sed 's/\.ct0\.//'
- }
- function ctdescribe {
- local filename dirname basename
- while getopts "" flag; do
- case $flag in
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in `ls "$@"`; do
- dirname=`dirname $filename`
- basename=`basename $filename`
- ctco=$dirname/.ctco.$basename
- get_highest_version $dirname $basename
- version=`expr $version + 1`
- if [ -f $ctco ]; then
- if [ $version -eq 0 ]; then
- echo "$filename is checked out with no versions."
- else
- echo "$filename is checked out as version $version."
- list_comments $dirname $basename
- fi
- else
- if [ $version -eq 0 ]; then
- echo "$filename has not been checked out and has no versions."
- else
- echo "$filename is checked in as version $version."
- list_comments $dirname $basename
- fi
- fi
- done
- }
- function ctlsco {
- local filename dirname basename
- local ignore
- while getopts "l" flag; do
- case $flag in
- l) ignore=;;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- for filename in `ls "$@"`; do
- dirname=`dirname $filename`
- basename=`basename $filename`
- ctco=$dirname/.ctco.$basename
- if [ -f $ctco ]; then
- ctdescribe $filename
- fi
- done
- }
- function ctdiff {
- local filename dirname basename
- local graphical
- local ignore
- local diff
- while getopts "gp:" flag; do
- case $flag in
- g) graphical=y;;
- p) ignore=;;
- \?) exit 1;
- esac
- done
- shift `expr $OPTIND - 1`
- diff=diff
- if [ $graphical ]; then
- # The user requested a graphical difference; use gdiff if we can
- # find it. Otherwise, fall back to diff.
- if which gdiff 2>/dev/null >/dev/null; then
- diff=gdiff
- fi
- fi
- if [ -z "$1" ]; then
- echo "No filenames given."
- exit 1
- fi
- for filename in "$@"; do
- dirname=`dirname $filename`
- basename=`basename $filename`
-
- sane_filename $dirname $basename
-
- if [ ! -f $filename ]; then
- echo "$filename does not exist." 1>&2
- exit 1
- fi
-
- get_highest_version $dirname $basename
-
- if [ $version -eq -1 ]; then
- echo "$filename has no versions." 1>&2
- exit 1
- fi
-
- last=$dirname/.ct$version.$basename
- # First, call diff (the real diff) just to see if the files are
- # different at all.
- if diff $last $filename >/dev/null; then
- echo Files are identical.
- else
- # If the files ARE different, then invoke diff again (which
- # might be gdiff, this time) to actually report the differences.
- # We must do it twice like this because gdiff might not return
- # non-zero if the files are different.
- $diff $last $filename
- fi
- done
- }
- function usage {
- sed '/#ENDCOMMENT/,$d' <$0 >&2
- exit 1
- }
- #
- # Main entry point
- #
- command=$1
- if [ -z "$command" ]; then
- usage
- fi
- shift
- projroot=`ctproj -r`
- if [ -z "$projroot" ]; then
- echo "Not currently in a project tree." 1>&2
- exit 1
- fi
- case $command in
- mkelem) ctmkelem "$@";;
- mkdir) ctmkdir "$@";;
- mv) ctmv "$@";;
- co|checkout) ctco "$@";;
- unco|uncheckout) ctunco "$@";;
- ci|checkin) ctci "$@";;
- revert) ctrevert "$@";;
- revertall) ctrevertall "$@";;
- collapse) ctcollapse "$@";;
- rmname) ctrmname "$@";;
- find) ctfind "$@";;
- lsco|lscheckout) ctlsco "$@";;
- describe) ctdescribe "$@";;
- diff) ctdiff "$@";;
- xdiff) ctdiff -g "$@";;
- h|help|-h) usage;;
- *) echo "Invalid option: $command" 1>&2
- exit 1;
- esac
|