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...]"
35 echo "usage: zit list"
36 echo "Show tracked files, with a one-letter prefix indicating their status:"
39 echo " R removed/deleted"
40 echo " C modified/changed"
41 echo " K to be killed"
45 echo "usage: zit import FILE"
46 echo "Import history from an RCS-tracked file. Requires rcs-fast-export."
49 echo "usage: zit view FILE"
50 echo "Browse FILE's history with gitk (if possible) or tig."
53 echo "usage: zit with FILE COMMAND..."
54 echo "Run COMMAND after setting up the git environment for FILE."
57 echo "usage: zit clone REPO [FILE]"
58 echo "Create and track FILE, retrieving its history from repository REPO."
59 echo "FILE is guessed by REPO by stripping the '.git' suffix from the last path component"
64 echo "Set up a git repository under .FILE.git to track changes for FILE."
65 echo "File must be a regular file and in the current directory."
68 echo " add Stage changes or start tracking changes to FILE"
69 echo " clone Clone and track a remote file"
70 echo " import Import RCS history for FILE"
71 echo " init Synonym for track"
72 echo " list Synonym for tracked"
73 echo " track Start tracking changes to FILE"
74 echo " tracked List tracked files in current directory"
75 echo " view Browse FILE's history with gitk or tig"
76 echo " with Run a command in FILE's context"
78 echo "See 'zit help git' or 'git help' for git commands."
81 echo "usage: zig FILE"
82 echo "Browse FILE's history with tig."
85 echo "usage: zik FILE"
86 echo "Browse FILE's history with gitk."
95 test "$ZIT_FILE" || abort "Please specify a file"
96 test -f "$ZIT_FILE" || abort "No such file $ZIT_FILE"
97 test "$ZIT_FILE" = $(basename "$ZIT_FILE") || abort "Sorry, Zit only works on files in the current directory"
99 export GIT_WORK_TREE=$(pwd)
101 # first, check if a repo exists already, looking for
102 # .zit/file.git or .file.git, in that order
103 # if neither is found, and .zit exists, set the repo dir
104 # to .zit/file.git, otherwise set it to .file.git
105 GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
106 if ! test -d "$GIT_DIR"; then
107 GIT_DIR=".$ZIT_FILE.git"
108 if ! test -d "$GIT_DIR"; then
109 test -d "$ZIT_DIR" && GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
115 # initialize the zitdir, without actually making the first commit
118 test -e "$GIT_DIR" && abort "$GIT_DIR exists, is $ZIT_FILE tracked already?"
119 mkdir "$GIT_DIR" && echo "Initializing Zit repository in $GIT_DIR"
120 test -d "$GIT_DIR" || abort "Failed to create $GIT_DIR"
121 git init || abort "Failed to initialize Git repository in $GIT_DIR"
122 rm -rf "$GIT_DIR"/{hooks,info,branches,refs/tags,objects/pack,description}
123 if test -d "$ZIT_DIR"; then
124 ZIT_EXCLUDE="$ZIT_DIR/exclude"
126 ZIT_EXCLUDE="$GIT_DIR/exclude"
128 if ! test -f "$ZIT_EXCLUDE"; then
129 touch "$ZIT_EXCLUDE" || abort "Cannot create $ZIT_EXCLUDE file"
130 echo "# Ignore patterns used by Zit repositories in the parent worktree." > "$ZIT_EXCLUDE"
131 echo "# By default it's the single '*' glob, since we want to ignore all" >> "$ZIT_EXCLUDE"
132 echo "# non-tracked files in the work-tree." >> "$ZIT_EXCLUDE"
133 echo "# This file is autogenerated and there's usually no need to edit it." >> "$ZIT_EXCLUDE"
134 echo "*" >> "$ZIT_EXCLUDE"
136 git config core.excludesfile "$ZIT_EXCLUDE"
140 if test -f "$ZIT_DIR"; then
141 abort "$ZIT_DIR exists but it's not a directory, cannot continue"
146 if test -n "$1"; then
148 git add -f "$ZIT_FILE" || abort "Failed to add $ZIT_FILE"
149 git commit "$@" || abort "Failed to make first commit for $ZIT_FILE"
151 if test -d "$ZIT_DIR"; then
152 echo "$ZIT_DIR exists already"
161 # add the file if it is tracked, otherwise zit init
165 if test -d "$GIT_DIR"; then
173 export GIT_WORK_TREE="$(pwd)"
175 for file in "$ZIT_DIR"/*.git .*.git; do
176 if ! test -e $file; then
179 export GIT_DIR="$file"
183 (git ls-files -m -d -t; git ls-files -t) | uniq -f 1
185 # if $GIT_DIR is empty, no files were found
186 test "$GIT_DIR" || echo "(no files tracked by zit)"
189 # import an RCS-tracked file using rcs-fast-export, if found
191 which rcs-fast-export || abort "rcs-fast-export not found, I can't import RCS-tracked files, sorry"
193 # git-fast-import creates a pack file, so (re)build the objects/pack dir
194 mkdir -p "$GIT_DIR/objects/pack"
195 rcs-fast-export "$1" | git-fast-import
196 # for some reason, rcs-fast-export | git-fast-import leaves the original
197 # file in 'deleted' state, a situation which is easily fixed by adding
204 test -n "$SRC" || abort "Where do you want to clone from?"
208 ZIT_FILE=$(basename "$SRC" .git)
210 test -e "$ZIT_FILE" && abort "File $ZIT_FILE exists already"
211 test "$ZIT_FILE" = $(basename $ZIT_FILE) || abort "Sorry, Zit only works on files in the current directory"
212 touch "$ZIT_FILE" # to make zit_setup happy
213 zitdir_init "$ZIT_FILE"
215 git remote add origin "$SRC"
218 git checkout -b master origin/master
226 echo "zit version $VERSION"
250 if test -n "$DISPLAY" -a -n "$(which gitk)" ; then
252 elif test -n "$(which tig)" ; then
255 abort "Neither gitk or tig could be launched"
273 # Most commands will work with the generic catch-all mechanism used
274 # below, but some of them require a more thorough analysis of the
275 # parameters to decide whether $ZIT_FILE should be put back into the
276 # parameter list or not. For example,
277 # $ zit commit somefile
278 # wouldn't do what one expects it to do, unless 'add' is run first, however
279 # $ zit commit somefile -a
280 # would work correctly. So we handle some commands separately (for the
281 # moment just commit)
285 git commit "$@" "$ZIT_FILE"
287 # the raw<command> method can be used to not replicate $ZIT_FILE in the