3 # Zit: the git-based single-file content tracker
11 if test "$me" = zit ; then
18 USAGE="usage: zit COMMAND FILE [ARGS...]"
28 echo "usage: zit list"
29 echo "Show tracked files, with a one-letter prefix indicating their status:"
32 echo " R removed/deleted"
33 echo " C modified/changed"
34 echo " K to be killed"
38 echo "usage: zit import FILE"
39 echo "Import history from an RCS-tracked file. Requires rcs-fast-export."
42 echo "usage: zit view FILE"
43 echo "Browse FILE's history with gitk (if possible) or tig."
46 echo "usage: zit with FILE COMMAND..."
47 echo "Run COMMAND after setting up the git environment for FILE."
50 echo "usage: zit clone REPO [FILE]"
51 echo "Create and track FILE, retrieving its history from repository REPO."
52 echo "FILE is guessed by REPO by stripping the '.git' suffix from the last path component"
57 echo "Set up a git repository under .zit.FILE to track changes for FILE."
58 echo "File must be a regular file and in the current directory."
61 echo " clone Clone and track a remote file"
62 echo " import Import RCS history for FILE"
63 echo " init Synonym for track"
64 echo " list Synonym for tracked"
65 echo " track Start tracking changes to FILE"
66 echo " tracked List tracked files in current directory"
67 echo " view Browse FILE's history with gitk or tig"
68 echo " with Run a command in FILE's context"
70 echo "See 'zit help git' or 'git help' for git commands."
73 echo "usage: zig FILE"
74 echo "Browse FILE's history with tig."
77 echo "usage: zik FILE"
78 echo "Browse FILE's history with gitk."
87 test $ZIT_FILE || abort "Please specify a file"
88 test -f $ZIT_FILE || abort "No such file $ZIT_FILE"
89 test $ZIT_FILE = "`basename $ZIT_FILE`" || abort "Sorry, Zit only works on files in the current directory"
91 export GIT_WORK_TREE="`pwd`"
93 # first, check if a repo exists already, looking for
94 # .zit/file.git or .file.git, in that order
95 # if neither is found, and .zit exists, set the repo dir
96 # to .zit/file.git, otherwise set it to .file.git
97 GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
98 if ! test -d "$GIT_DIR"; then
99 GIT_DIR=".$ZIT_FILE.git"
100 if ! test -d "$GIT_DIR"; then
101 test -d "$ZIT_DIR" && GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
107 # initialize the zitdir, without actually making the first commit
110 test -e $GIT_DIR && abort "$GIT_DIR exists, is $ZIT_FILE tracked already?"
111 mkdir $GIT_DIR && echo "Initializing Zit repository in $GIT_DIR"
112 test -d $GIT_DIR || abort "Failed to create $GIT_DIR"
113 git init || abort "Failed to initialize Git repository in $GIT_DIR"
114 rm -rf $GIT_DIR/{hooks,info,branches,refs/tags,objects/pack,description}
115 if test -d "$ZIT_DIR"; then
116 ZIT_EXCLUDE="$ZIT_DIR/exclude"
118 ZIT_EXCLUDE="$GIT_DIR/exclude"
120 if ! test -f "$ZIT_EXCLUDE"; then
121 touch "$ZIT_EXCLUDE" || abort "Cannot create $ZIT_EXCLUDE file"
122 echo "# Ignore patterns used by Zit repositories in the parent worktree." > "$ZIT_EXCLUDE"
123 echo "# By default it's the single '*' glob, since we want to ignore all" >> "$ZIT_EXCLUDE"
124 echo "# non-tracked files in the work-tree." >> "$ZIT_EXCLUDE"
125 echo "# This file is autogenerated and there's usually no need to edit it." >> "$ZIT_EXCLUDE"
126 echo "*" >> "$ZIT_EXCLUDE"
128 git config core.excludesfile "$ZIT_EXCLUDE"
134 git add -f $ZIT_FILE || abort "Failed to add $ZIT_FILE"
135 git commit "$@" || abort "Failed to make first commit for $ZIT_FILE"
137 if test -d "$ZIT_DIR"; then
138 echo "$ZIT_DIR exists already"
141 test -e $ZIT_DIR && abort "$ZIT_DIR exists but it's not a directory, cannot continue"
147 export GIT_WORK_TREE="`pwd`"
149 for file in "$ZIT_DIR"/*.git .*.git; do
150 if ! test -e $file; then
153 export GIT_DIR="$file"
157 (git ls-files -m -d -t; git ls-files -t) | uniq -f 1
159 # if $GIT_DIR is empty, no files were found
160 test "$GIT_DIR" || echo "(no files tracked by zit)"
163 # import an RCS-tracked file using rcs-fast-export, if found
165 which rcs-fast-export || abort "rcs-fast-export not found, I can't import RCS-tracked files, sorry"
167 # git-fast-import creates a pack file, so (re)build the objects/pack dir
168 mkdir -p $GIT_DIR/objects/pack
169 rcs-fast-export $1 | git-fast-import
170 # for some reason, rcs-fast-export | git-fast-import leaves the original
171 # file in 'deleted' state, a situation which is easily fixed by adding
178 test -n "$SRC" || abort "Where do you want to clone from?"
182 ZIT_FILE=`basename $SRC .git`
184 test -e "$ZIT_FILE" && abort "File $ZIT_FILE exists already"
185 test "$ZIT_FILE" = "`basename $ZIT_FILE`" || abort "Sorry, Zit only works on files in the current directory"
186 touch "$ZIT_FILE" # to make zit_setup happy
187 zitdir_init "$ZIT_FILE"
189 git remote add origin "$SRC"
192 git checkout -b master origin/master
217 if test -n "$DISPLAY" -a -n "$(which gitk)" ; then
219 elif test -n "$(which tig)" ; then
222 abort "Neither gitk or tig could be launched"
240 # Most commands will work with the generic catch-all mechanism used
241 # below, but some of them require a more thorough analysis of the
242 # parameters to decide whether $ZIT_FILE should be put back into the
243 # parameter list or not. For example,
244 # $ zit commit somefile
245 # wouldn't do what one expects it to do, unless 'add' is run first,
248 # wouldn't work either), however
249 # $ zit commit somefile -a
250 # would work correctly. So we handle some commands separately (for the
251 # moment just add and commit)
255 git $cmd "$@" "$ZIT_FILE"
257 # the raw<command> method can be used to not replicate $ZIT_FILE in the