git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/6] am --skip: revert changes introduced by failed 3way merge

From
Paul Tan <pyokagan@gmail.com>
Date
Jun 6, 2015, 11:46 UTC
Message-ID
<1433591172-27077-2-git-send-email-pyokagan@gmail.com>
In-Reply-To
<1433591172-27077-1-git-send-email-pyokagan@gmail.com>

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>
---
 git-am.sh           |  7 ++++++-
 t/t4151-am-abort.sh | 11 +++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/git-am.sh b/git-am.sh
index 761befb..df3c8f4 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -69,6 +69,8 @@ then
 	cmdline="$cmdline -3"
 fi
 
+empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+
 sq () {
 	git rev-parse --sq-quote "$@"
 }
@@ -502,7 +504,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 8d90634..e15acc8 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 &&
-- 
2.1.4
Previous: Paul TanNext: Paul Tan
Message 2 of 13 in “am --skip/--abort: improve index/worktree cleanup”
  1. 0/6 am --skip/--abort: improve index/worktree cleanupPaul Tan, Jun 6, 2015
  2. 1/6 am --skip: revert changes introduced by failed 3way mergePaul Tan, Jun 6, 2015
  3. 2/6 am -3: support 3way merge on unborn branchPaul Tan, Jun 6, 2015
  4. 3/6 am --skip: support skipping while on unborn branchPaul Tan, Jun 6, 2015
  5. 4/6 am --abort: revert changes introduced by failed 3way mergePaul Tan, Jun 6, 2015
  6. Junio C HamanoJun 8, 2015
  7. 5/6 am --abort: support aborting to unborn branchPaul Tan, Jun 6, 2015
  8. Junio C HamanoJun 8, 2015
  9. Paul TanJun 9, 2015
  10. 6/6 am --abort: keep unrelated commits on unborn branchPaul Tan, Jun 6, 2015
  11. Junio C HamanoJun 8, 2015
  12. Paul TanJun 9, 2015
  13. Stefan BellerJun 8, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.