chiark / gitweb /
git-debrebase: merge: Save wreckage if desired
[dgit.git] / tests / tartree-edit
index 76e51b6..78f0e4f 100755 (executable)
@@ -5,7 +5,7 @@ fail () { echo >&2 "$0: $*"; exit 1; }
 play=.git/tartree-edit-work
 
 git_manip_play () {
-       local wd=$(pwd)
+       local wd; wd=$(pwd)
        case "$wd" in
        *.edit) fail "bad idea to run gitfetchinfo into a .edit tree!" ;;
        esac
@@ -17,7 +17,7 @@ gitfetchdiff_list () {
        git for-each-ref --format '%(refname) %(objectname)' \
                refs/remotes/"$1" \
        | sed 's/^refs\/remotes\/[^\/]*\///' \
-       | sort >"$play/$2"
+       | t-sort >"$play/$2"
 }
 
 gitfetchdiff () {
@@ -67,7 +67,9 @@ case "$#.$1" in
 ?.-*)  fail "no options understood"                    ;;
 *)     fail "usage:
     tartree-edit edit|done DIRECTORY|TARBALL
-    tartree-edit gitfetchinfo DIRECTORY|TARBALL REMOTE"        ;;
+    tartree-edit gitfetchinfo DIRECTORY|TARBALL REMOTE
+    tartree-edit gitfetchinfo-merge REMOTE-A REMOTE-B" ;;
+    # we don't document gitfetchinfo-diff because it's rather poor
 esac
 
 case "$arg" in
@@ -116,6 +118,7 @@ gitfetchinfo_perhaps_commit () {
 
 tryat_gitfetchinfo () {
        git_manip_play
+
        if test -d "$b.edit"; then
                cp -a "$b.edit"/. "$play"/.
        else
@@ -123,20 +126,57 @@ tryat_gitfetchinfo () {
                tar -C $play -f - <&3 -x
                exec 3<&-
        fi
-       local innerwd=$play/*
+
+       local innerwd; innerwd="$(echo $play/*)"
+
+       git for-each-ref --format='%(refname)' refs/remotes >$play/l
+       perl -w -ne '
+           our %remerge;
+           use strict;
+           chomp;
+           next unless m#^refs/remotes/([^/]+)/#;
+           my $old = $_;
+           my $ab = $1;
+           my $rhs = $'\'';
+           my @ab = split /\+/, $ab;
+           next unless @ab == 2;
+           next unless (grep { $_ eq "'"$remote"'" } @ab) == 1;
+           $remerge{"@ab"} = 1;
+           print "update refs/remotes/$_/$rhs $old\n" or die $! foreach @ab;
+           print "delete $old\n" or die $!;
+           END {
+               open REMERGE, ">&3" or die $!;
+               print REMERGE "$_\n" or die $! foreach sort keys %remerge;
+               close REMERGE or die $!;
+           }
+       ' <$play/l >$play/unmerge 3>$play/remerge
+       git update-ref --stdin <$play/unmerge
+
        git remote remove "$remote" 2>/dev/null ||:
        git remote add "$remote" $innerwd
        git fetch --no-tags -p "$remote" \
-               +"HEAD:refs/remotes/$remote/HEAD"
+               +"HEAD:refs/remotes/$remote/TT-HEAD"
        cd $innerwd
+       GIT_AUTHOR_DATE=$(git log -n1 --pretty=format:'%ai')
+       GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE
+       export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
        git checkout -b WORKTREE
-       gitfetchinfo_perhaps_commit INDEX
+       gitfetchinfo_perhaps_commit 'UNCOMMITTED INDEX'
        git add -Af .
-       gitfetchinfo_perhaps_commit WORKTREE
+       gitfetchinfo_perhaps_commit 'UNCOMMITTED WORKING TREE'
        cd ../../..
        git fetch --no-tags "$remote" --refmap \
                +"refs/*:refs/remotes/$remote/*" \
                +"refs/*:refs/remotes/$remote/*"
+
+       exec 3<$play/remerge
+       # $play will be destroyed by what follows, but we have
+       # an fd open onto remerge, so this will work
+       while read <&3 a b; do
+             echo "Updating gitfetchinfo-merge $a $b"
+             "$0" gitfetchinfo-merge $a $b
+       done
+
        exit 0
 }