Skip to content

Commit 88d5072

Browse files
pyokagangitster
authored andcommitted
am --skip: revert changes introduced by failed 3way merge
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fdf96a2 commit 88d5072

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

git-am.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ then
6868
cmdline="$cmdline -3"
6969
fi
7070

71+
empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
72+
7173
sq () {
7274
git rev-parse --sq-quote "$@"
7375
}
@@ -492,7 +494,10 @@ then
492494
;;
493495
t,)
494496
git rerere clear
495-
git read-tree --reset -u HEAD HEAD
497+
head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
498+
git read-tree --reset -u $head_tree $head_tree &&
499+
index_tree=$(git write-tree) &&
500+
git read-tree -m -u $index_tree $head_tree
496501
orig_head=$(cat "$GIT_DIR/ORIG_HEAD")
497502
git reset HEAD
498503
git update-ref ORIG_HEAD $orig_head

t/t4151-am-abort.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ do
6363

6464
done
6565

66+
test_expect_success 'am -3 --skip removes otherfile-4' '
67+
git reset --hard initial &&
68+
test_must_fail git am -3 0003-*.patch &&
69+
test 3 -eq $(git ls-files -u | wc -l) &&
70+
test 4 = "$(cat otherfile-4)" &&
71+
git am --skip &&
72+
test_cmp_rev initial HEAD &&
73+
test -z $(git ls-files -u) &&
74+
test_path_is_missing otherfile-4
75+
'
76+
6677
test_expect_success 'am --abort will keep the local commits intact' '
6778
test_must_fail git am 0004-*.patch &&
6879
test_commit unrelated &&

0 commit comments

Comments
 (0)