3 # Zit: the git-based single-file content tracker
5 # Copyright (C) 2008-2014 Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
6 # Licensed under the GNU GPL v2
7 # A full copy of the license text is not included with zit, because the
8 # program is self-contained.
9 # Refer to http://www.gnu.org/licenses/gpl-2.0.html for the full license terms
17 if test "$me" = zit ; then
24 USAGE="usage: zit COMMAND FILE [ARGS...]"
32 echo "usage: zit clone REPO [FILE]"
33 echo "Create and track FILE, retrieving its history from repository REPO."
34 echo "FILE is guessed by REPO by stripping the '.git' suffix from the last path component"
40 echo "usage: zit import FILE"
41 echo "Import history from an RCS-tracked file. Requires rcs-fast-export."
44 echo "usage: zit $cmd"
45 echo "Show tracked files, with a one-letter prefix indicating their status:"
48 echo " R removed/deleted"
49 echo " C modified/changed"
50 echo " K to be killed"
54 echo "usage: zit view FILE"
55 echo "Browse FILE's history with gitk (if possible) or tig."
58 echo "usage: zit with FILE COMMAND..."
59 echo "Run COMMAND after setting up the git environment for FILE."
62 echo "usage: zig FILE"
63 echo "Browse FILE's history with tig."
66 echo "usage: zik FILE"
67 echo "Browse FILE's history with gitk."
72 echo "Set up a git repository under .FILE.git to track changes for FILE."
73 echo "File must be a regular file and in the current directory."
76 echo " add Stage changes or start tracking changes to FILE"
77 echo " clone Clone and track a remote file"
78 echo " import Import RCS history for FILE"
79 echo " init Synonym for track"
80 echo " list Synonym for tracked"
81 echo " ls Synonym for tracked"
82 echo " track Start tracking changes to FILE"
83 echo " tracked List tracked files in current directory"
84 echo " view Browse FILE's history with gitk or tig"
85 echo " with Run a command in FILE's context"
87 echo "See 'zit help git' or 'git help' for git commands."
96 test "$ZIT_FILE" || abort "Please specify a file"
97 test -f "$ZIT_FILE" || abort "No such file $ZIT_FILE"
98 test "$ZIT_FILE" = $(basename "$ZIT_FILE") || abort "Sorry, Zit only works on files in the current directory"
100 export GIT_WORK_TREE=$(pwd)
102 # first, check if a repo exists already, looking for
103 # .zit/file.git or .file.git, in that order
104 # if neither is found, and .zit exists, set the repo dir
105 # to .zit/file.git, otherwise set it to .file.git
106 GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
107 if ! test -d "$GIT_DIR"; then
108 GIT_DIR=".$ZIT_FILE.git"
109 if ! test -d "$GIT_DIR"; then
110 test -d "$ZIT_DIR" && GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
116 # initialize the zitdir, without actually making the first commit
119 test -e "$GIT_DIR" && abort "$GIT_DIR exists, is $ZIT_FILE tracked already?"
120 mkdir "$GIT_DIR" && echo "Initializing Zit repository in $GIT_DIR"
121 test -d "$GIT_DIR" || abort "Failed to create $GIT_DIR"
122 git init || abort "Failed to initialize Git repository in $GIT_DIR"
123 rm -rf "$GIT_DIR"/{hooks,info,branches,refs/tags,objects/pack,description}
124 if test -d "$ZIT_DIR"; then
125 ZIT_EXCLUDE="$ZIT_DIR/exclude"
127 ZIT_EXCLUDE="$GIT_DIR/exclude"
129 if ! test -f "$ZIT_EXCLUDE"; then
130 touch "$ZIT_EXCLUDE" || abort "Cannot create $ZIT_EXCLUDE file"
131 echo "# Ignore patterns used by Zit repositories in the parent worktree." > "$ZIT_EXCLUDE"
132 echo "# By default it's the single '*' glob, since we want to ignore all" >> "$ZIT_EXCLUDE"
133 echo "# non-tracked files in the work-tree." >> "$ZIT_EXCLUDE"
134 echo "# This file is autogenerated and there's usually no need to edit it." >> "$ZIT_EXCLUDE"
135 echo "*" >> "$ZIT_EXCLUDE"
137 git config core.excludesfile "$ZIT_EXCLUDE"
141 if test -f "$ZIT_DIR"; then
142 abort "$ZIT_DIR exists but it's not a directory, cannot continue"
147 if test -n "$1"; then
149 git add -f "$ZIT_FILE" || abort "Failed to add $ZIT_FILE"
150 git commit "$@" || abort "Failed to make first commit for $ZIT_FILE"
152 if test -d "$ZIT_DIR"; then
153 echo "$ZIT_DIR exists already"
162 # add the file if it is tracked, otherwise zit init
166 if test -d "$GIT_DIR"; then
174 export GIT_WORK_TREE="$(pwd)"
176 for file in "$ZIT_DIR"/*.git .*.git; do
177 if ! test -e $file; then
180 export GIT_DIR="$file"
184 (git ls-files -m -d -t; git ls-files -t) | uniq -f 1
186 # if $GIT_DIR is empty, no files were found
187 test "$GIT_DIR" || echo "(no files tracked by zit)"
190 # import an RCS-tracked file using rcs-fast-export, if found
192 which rcs-fast-export || abort "rcs-fast-export not found, I can't import RCS-tracked files, sorry"
194 # git-fast-import creates a pack file, so (re)build the objects/pack dir
195 mkdir -p "$GIT_DIR/objects/pack"
196 rcs-fast-export "$1" | git-fast-import
197 # for some reason, rcs-fast-export | git-fast-import leaves the original
198 # file in 'deleted' state, a situation which is easily fixed by adding
205 test -n "$SRC" || abort "Where do you want to clone from?"
209 ZIT_FILE=$(basename "$SRC" .git)
211 test -e "$ZIT_FILE" && abort "File $ZIT_FILE exists already"
212 test "$ZIT_FILE" = $(basename $ZIT_FILE) || abort "Sorry, Zit only works on files in the current directory"
213 touch "$ZIT_FILE" # to make zit_setup happy
214 zitdir_init "$ZIT_FILE"
216 git remote add origin "$SRC"
219 git checkout -b master origin/master
227 echo "zit version $VERSION"
251 if test -n "$DISPLAY" -a -n "$(which gitk)" ; then
253 elif test -n "$(which tig)" ; then
256 abort "Neither gitk or tig could be launched"
274 # Most commands will work with the generic catch-all mechanism used
275 # below, but some of them require a more thorough analysis of the
276 # parameters to decide whether $ZIT_FILE should be put back into the
277 # parameter list or not. For example,
278 # $ zit commit somefile
279 # wouldn't do what one expects it to do, unless 'add' is run first, however
280 # $ zit commit somefile -a
281 # would work correctly. So we handle some commands separately (for the
282 # moment just commit)
286 git commit "$@" "$ZIT_FILE"
288 # the raw<command> method can be used to not replicate $ZIT_FILE in the