3 # Zit: the git-based single-file content tracker
11 if test "$me" = zit ; then
18 USAGE="usage: zit COMMAND FILE [ARGS...]"
29 echo "usage: zit list"
30 echo "Show tracked files, with a one-letter prefix indicating their status:"
33 echo " R removed/deleted"
34 echo " C modified/changed"
35 echo " K to be killed"
39 echo "usage: zit import FILE"
40 echo "Import history from an RCS-tracked file. Requires rcs-fast-export."
43 echo "usage: zit view FILE"
44 echo "Browse FILE's history with gitk (if possible) or tig."
47 echo "usage: zit with FILE COMMAND..."
48 echo "Run COMMAND after setting up the git environment for FILE."
51 echo "usage: zit clone REPO [FILE]"
52 echo "Create and track FILE, retrieving its history from repository REPO."
53 echo "FILE is guessed by REPO by stripping the '.git' suffix from the last path component"
58 echo "Set up a git repository under .FILE.git to track changes for FILE."
59 echo "File must be a regular file and in the current directory."
62 echo " clone Clone and track a remote file"
63 echo " import Import RCS history for FILE"
64 echo " init Synonym for track"
65 echo " list Synonym for tracked"
66 echo " track Start tracking changes to FILE"
67 echo " tracked List tracked files in current directory"
68 echo " view Browse FILE's history with gitk or tig"
69 echo " with Run a command in FILE's context"
71 echo "See 'zit help git' or 'git help' for git commands."
74 echo "usage: zig FILE"
75 echo "Browse FILE's history with tig."
78 echo "usage: zik FILE"
79 echo "Browse FILE's history with gitk."
88 test "$ZIT_FILE" || abort "Please specify a file"
89 test -f "$ZIT_FILE" || abort "No such file $ZIT_FILE"
90 test "$ZIT_FILE" = $(basename "$ZIT_FILE") || abort "Sorry, Zit only works on files in the current directory"
92 export GIT_WORK_TREE=$(pwd)
94 # first, check if a repo exists already, looking for
95 # .zit/file.git or .file.git, in that order
96 # if neither is found, and .zit exists, set the repo dir
97 # to .zit/file.git, otherwise set it to .file.git
98 GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
99 if ! test -d "$GIT_DIR"; then
100 GIT_DIR=".$ZIT_FILE.git"
101 if ! test -d "$GIT_DIR"; then
102 test -d "$ZIT_DIR" && GIT_DIR="$ZIT_DIR/$ZIT_FILE.git"
108 # initialize the zitdir, without actually making the first commit
111 test -e "$GIT_DIR" && abort "$GIT_DIR exists, is $ZIT_FILE tracked already?"
112 mkdir "$GIT_DIR" && echo "Initializing Zit repository in $GIT_DIR"
113 test -d "$GIT_DIR" || abort "Failed to create $GIT_DIR"
114 git init || abort "Failed to initialize Git repository in $GIT_DIR"
115 rm -rf "$GIT_DIR"/{hooks,info,branches,refs/tags,objects/pack,description}
116 if test -d "$ZIT_DIR"; then
117 ZIT_EXCLUDE="$ZIT_DIR/exclude"
119 ZIT_EXCLUDE="$GIT_DIR/exclude"
121 if ! test -f "$ZIT_EXCLUDE"; then
122 touch "$ZIT_EXCLUDE" || abort "Cannot create $ZIT_EXCLUDE file"
123 echo "# Ignore patterns used by Zit repositories in the parent worktree." > "$ZIT_EXCLUDE"
124 echo "# By default it's the single '*' glob, since we want to ignore all" >> "$ZIT_EXCLUDE"
125 echo "# non-tracked files in the work-tree." >> "$ZIT_EXCLUDE"
126 echo "# This file is autogenerated and there's usually no need to edit it." >> "$ZIT_EXCLUDE"
127 echo "*" >> "$ZIT_EXCLUDE"
129 git config core.excludesfile "$ZIT_EXCLUDE"
133 if test -f "$ZIT_DIR"; then
134 abort "$ZIT_DIR exists but it's not a directory, cannot continue"
139 if test -n "$1"; then
141 git add -f "$ZIT_FILE" || abort "Failed to add $ZIT_FILE"
142 git commit "$@" || abort "Failed to make first commit for $ZIT_FILE"
144 if test -d "$ZIT_DIR"; then
145 echo "$ZIT_DIR exists already"
154 export GIT_WORK_TREE="$(pwd)"
156 for file in "$ZIT_DIR"/*.git .*.git; do
157 if ! test -e $file; then
160 export GIT_DIR="$file"
164 (git ls-files -m -d -t; git ls-files -t) | uniq -f 1
166 # if $GIT_DIR is empty, no files were found
167 test "$GIT_DIR" || echo "(no files tracked by zit)"
170 # import an RCS-tracked file using rcs-fast-export, if found
172 which rcs-fast-export || abort "rcs-fast-export not found, I can't import RCS-tracked files, sorry"
174 # git-fast-import creates a pack file, so (re)build the objects/pack dir
175 mkdir -p "$GIT_DIR/objects/pack"
176 rcs-fast-export "$1" | git-fast-import
177 # for some reason, rcs-fast-export | git-fast-import leaves the original
178 # file in 'deleted' state, a situation which is easily fixed by adding
185 test -n "$SRC" || abort "Where do you want to clone from?"
189 ZIT_FILE=$(basename "$SRC" .git)
191 test -e "$ZIT_FILE" && abort "File $ZIT_FILE exists already"
192 test "$ZIT_FILE" = $(basename $ZIT_FILE) || abort "Sorry, Zit only works on files in the current directory"
193 touch "$ZIT_FILE" # to make zit_setup happy
194 zitdir_init "$ZIT_FILE"
196 git remote add origin "$SRC"
199 git checkout -b master origin/master
207 echo "zit version $VERSION"
228 if test -n "$DISPLAY" -a -n "$(which gitk)" ; then
230 elif test -n "$(which tig)" ; then
233 abort "Neither gitk or tig could be launched"
251 # Most commands will work with the generic catch-all mechanism used
252 # below, but some of them require a more thorough analysis of the
253 # parameters to decide whether $ZIT_FILE should be put back into the
254 # parameter list or not. For example,
255 # $ zit commit somefile
256 # wouldn't do what one expects it to do, unless 'add' is run first,
259 # wouldn't work either), however
260 # $ zit commit somefile -a
261 # would work correctly. So we handle some commands separately (for the
262 # moment just add and commit)
266 git $cmd "$@" "$ZIT_FILE"
268 # the raw<command> method can be used to not replicate $ZIT_FILE in the