3 fail () { echo >&2 "$0: $*"; exit 1; }
5 play=.git/tartree-edit-work
10 *.edit) fail "bad idea to run gitfetchinfo into a .edit tree!" ;;
16 gitfetchdiff_list () {
17 git for-each-ref --format '%(refname) %(objectname)' \
19 | sed 's/^refs\/remotes\/[^\/]*\///' \
29 rrab=refs/remotes/"$a+$b"
32 "delete refs/remotes/$a/%l
33 delete refs/remotes/$b/%l
37 git for-each-ref --format 'delete %(refname)' $rrab \
38 | git update-ref --stdin
46 fail "internal error bad how ($how)"
50 gitfetchdiff_list "$a" a
51 gitfetchdiff_list "$b" b
53 diff --old-line-format='' --new-line-format='' \
54 --unchanged-line-format="$ulf" \
55 $play/a $play/b >$play/updates \
58 git update-ref --stdin <$play/updates
63 2.edit|2.done) mode="$1"; arg="$2" ;;
64 3.gitfetchinfo) mode="$1"; arg="$2"; remote="$3" ;;
65 3.gitfetchinfo-diff) gitfetchdiff diff "$2" "$3" ;;
66 3.gitfetchinfo-merge) gitfetchdiff merge "$2" "$3" ;;
67 ?.-*) fail "no options understood" ;;
69 tartree-edit edit|done DIRECTORY|TARBALL
70 tartree-edit gitfetchinfo DIRECTORY|TARBALL REMOTE
71 tartree-edit gitfetchinfo-merge REMOTE-A REMOTE-B" ;;
72 # we don't document gitfetchinfo-diff because it's rather poor
76 *.tar) base=${arg%.tar} ;;
77 *.edit) base=${arg%.edit} ;;
84 if test -f "$b.tar" && test -f "$b.edit"; then
85 echo "$b.edit exists, deleting possibly-obsolete $b.tar"
92 if test -d "$b.edit"; then
93 echo "$b.edit already exists"
96 if test -f "$b.tar"; then
98 (set -e; cd "$b.tmp"; tar xf "$b.tar")
106 gitfetchinfo_perhaps_commit () {
109 git diff --cached --quiet --exit-code HEAD
114 1) git commit --allow-empty --author='tartree-edit <>' -m "$m" ;;
115 *) fail "git diff failed ($rc)" ;;
119 tryat_gitfetchinfo () {
122 if test -d "$b.edit"; then
123 cp -a "$b.edit"/. "$play"/.
126 tar -C $play -f - <&3 -x
130 local innerwd; innerwd="$(echo $play/*)"
132 git for-each-ref --format='%(refname)' refs/remotes >$play/l
137 next unless m#^refs/remotes/([^/]+)/#;
141 my @ab = split /\+/, $ab;
142 next unless @ab == 2;
143 next unless (grep { $_ eq "'"$remote"'" } @ab) == 1;
145 print "update refs/remotes/$_/$rhs $old\n" or die $! foreach @ab;
146 print "delete $old\n" or die $!;
148 open REMERGE, ">&3" or die $!;
149 print REMERGE "$_\n" or die $! foreach sort keys %remerge;
150 close REMERGE or die $!;
152 ' <$play/l >$play/unmerge 3>$play/remerge
153 git update-ref --stdin <$play/unmerge
155 git remote remove "$remote" 2>/dev/null ||:
156 git remote add "$remote" $innerwd
157 git fetch --no-tags -p "$remote" \
158 +"HEAD:refs/remotes/$remote/TT-HEAD"
160 GIT_AUTHOR_DATE=$(git log -n1 --pretty=format:'%ai')
161 GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE
162 export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
163 git checkout -b WORKTREE
164 gitfetchinfo_perhaps_commit 'UNCOMMITTED INDEX'
166 gitfetchinfo_perhaps_commit 'UNCOMMITTED WORKING TREE'
168 git fetch --no-tags "$remote" --refmap \
169 +"refs/*:refs/remotes/$remote/*" \
170 +"refs/*:refs/remotes/$remote/*"
173 # $play will be destroyed by what follows, but we have
174 # an fd open onto remerge, so this will work
175 while read <&3 a b; do
176 echo "Updating gitfetchinfo-merge $a $b"
177 "$0" gitfetchinfo-merge $a $b
185 if test -d "$b.edit"; then
186 (set -e; cd "$b.edit"; tar cf "$b.tmp" *)
188 mv "$b.edit" "$b.tmp"
190 echo "$b.tar regenerated"
193 if test -f "$b.tar"; then
194 echo "$b.tar already exists and $b.edit doesn't"
201 if ! test -f "$b.tar" && ! test -d "$b.edit"; then
206 fail "unexpected situation in $b.*"
215 tryat "$pwd/git-srcs/$base"
216 tryat "$pwd/tests/git-srcs/$base"
217 fail "could not find $base..."