Skip to content

Commit

Permalink
am --skip: revert changes introduced by failed 3way merge
Browse files Browse the repository at this point in the history
Even when a merge conflict occurs with am --3way, the index will be
modified with the results of any succesfully merged files (such as a new
file). These changes to the index will not be reverted with a
"git read-tree --reset -u HEAD HEAD", as git read-tree will not be aware
of how the current index differs from HEAD.

To fix this, we first reset any conflicting entries from the index. The
resulting index will contain the results of successfully merged files.
We write the index to a tree, then use git read-tree -m to fast-forward
the "index tree" back to HEAD, thus undoing all the changes from the
failed merge.

Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Paul Tan authored and Junio C Hamano committed Jun 8, 2015
1 parent fdf96a2 commit 88d5072
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
7 changes: 6 additions & 1 deletion git-am.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ then
cmdline="$cmdline -3"
fi

empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904

sq () {
git rev-parse --sq-quote "$@"
}
Expand Down Expand Up @@ -492,7 +494,10 @@ then
;;
t,)
git rerere clear
git read-tree --reset -u HEAD HEAD
head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
git read-tree --reset -u $head_tree $head_tree &&
index_tree=$(git write-tree) &&
git read-tree -m -u $index_tree $head_tree
orig_head=$(cat "$GIT_DIR/ORIG_HEAD")
git reset HEAD
git update-ref ORIG_HEAD $orig_head
Expand Down
11 changes: 11 additions & 0 deletions t/t4151-am-abort.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ do

done

test_expect_success 'am -3 --skip removes otherfile-4' '
git reset --hard initial &&
test_must_fail git am -3 0003-*.patch &&
test 3 -eq $(git ls-files -u | wc -l) &&
test 4 = "$(cat otherfile-4)" &&
git am --skip &&
test_cmp_rev initial HEAD &&
test -z $(git ls-files -u) &&
test_path_is_missing otherfile-4
'

test_expect_success 'am --abort will keep the local commits intact' '
test_must_fail git am 0004-*.patch &&
test_commit unrelated &&
Expand Down

0 comments on commit 88d5072

Please sign in to comment.