summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Tan <pyokagan@gmail.com>2015-06-06 19:46:07 +0800
committerJunio C Hamano <gitster@pobox.com>2015-06-08 13:05:43 -0700
commit88d5072466de2e0ba256a283eaaa6a79e31735a5 (patch)
tree95b295e7faf8fd1c29a64f3aea7930d1e7a1ab9e
parentfdf96a20acf96a6ac538df8113b2aafd6ed71d50 (diff)
downloadgit-88d5072466de2e0ba256a283eaaa6a79e31735a5.tar.gz
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 <pyokagan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-xgit-am.sh7
-rwxr-xr-xt/t4151-am-abort.sh11
2 files changed, 17 insertions, 1 deletions
diff --git a/git-am.sh b/git-am.sh
index ee61a77d71..80a7fdbd24 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -68,6 +68,8 @@ then
cmdline="$cmdline -3"
fi
+empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+
sq () {
git rev-parse --sq-quote "$@"
}
@@ -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
diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh
index 1176bcccf3..5ac741a1ac 100755
--- a/t/t4151-am-abort.sh
+++ b/t/t4151-am-abort.sh
@@ -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 &&