From 9d9a2f4aba3650093bad952cd89e276cde4ed074 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 25 Dec 2009 10:08:04 -0800 Subject: resolve-undo: basic tests Make sure that resolving a failed merge with git add records the conflicted state, committing the result keeps that state, and checking out another commit clears the state. "git ls-files" learns a new option --resolve-undo to show the recorded information. Signed-off-by: Junio C Hamano --- t/t2030-unresolve-info.sh | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 t/t2030-unresolve-info.sh (limited to 't') diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh new file mode 100755 index 000000000..785c8b3fc --- /dev/null +++ b/t/t2030-unresolve-info.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +test_description='undoing resolution' + +. ./test-lib.sh + +check_resolve_undo () { + msg=$1 + shift + while case $# in + 0) break ;; + 1|2|3) die "Bug in check-resolve-undo test" ;; + esac + do + path=$1 + shift + for stage in 1 2 3 + do + sha1=$1 + shift + case "$sha1" in + '') continue ;; + esac + sha1=$(git rev-parse --verify "$sha1") + printf "100644 %s %s\t%s\n" $sha1 $stage $path + done + done >"$msg.expect" && + git ls-files --resolve-undo >"$msg.actual" && + test_cmp "$msg.expect" "$msg.actual" +} + +prime_resolve_undo () { + git reset --hard && + git checkout second^0 && + test_tick && + test_must_fail git merge third^0 && + echo merge does not leave anything && + check_resolve_undo empty && + echo different >file && + git add file && + echo resolving records && + check_resolve_undo recorded file initial:file second:file third:file +} + +test_expect_success setup ' + test_commit initial file first && + git branch side && + git branch another && + test_commit second file second && + git checkout side && + test_commit third file third && + git checkout another && + test_commit fourth file fourth && + git checkout master +' + +test_expect_success 'add records switch clears' ' + prime_resolve_undo && + test_tick && + git commit -m merged && + echo committing keeps && + check_resolve_undo kept file initial:file second:file third:file && + git checkout second^0 && + echo switching clears && + check_resolve_undo cleared +' + +test_expect_success 'rm records reset clears' ' + prime_resolve_undo && + test_tick && + git commit -m merged && + echo committing keeps && + check_resolve_undo kept file initial:file second:file third:file && + + echo merge clears upfront && + test_must_fail git merge fourth^0 && + check_resolve_undo nuked && + + git rm -f file && + echo resolving records && + check_resolve_undo recorded file initial:file HEAD:file fourth:file && + + git reset --hard && + echo resetting discards && + check_resolve_undo discarded +' + +test_done -- cgit v1.2.1 From 4a39f79d3482cd844443b4ef9a8ef9b3d72faa5b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 25 Dec 2009 10:31:26 -0800 Subject: resolve-undo: allow plumbing to clear the information At the Porcelain level, operations such as merge that populate an initially cleanly merged index with conflicted entries clear the resolve-undo information upfront. Give scripted Porcelains a way to do the same, by implementing "update-index --clear-resolve-info". With this, a scripted Porcelain may "update-index --clear-resolve-info" first and repeatedly run "update-index --cacheinfo" to stuff unmerged entries to the index, to be resolved by the user with "git add" and stuff. Signed-off-by: Junio C Hamano --- t/t2030-unresolve-info.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 't') diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh index 785c8b3fc..984480271 100755 --- a/t/t2030-unresolve-info.sh +++ b/t/t2030-unresolve-info.sh @@ -85,4 +85,16 @@ test_expect_success 'rm records reset clears' ' check_resolve_undo discarded ' +test_expect_success 'plumbing clears' ' + prime_resolve_undo && + test_tick && + git commit -m merged && + echo committing keeps && + check_resolve_undo kept file initial:file second:file third:file && + + echo plumbing clear && + git update-index --clear-resolve-undo && + check_resolve_undo cleared +' + test_done -- cgit v1.2.1 From 4421a8235783d0664faa9a1d45be114fd7ad8206 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 25 Dec 2009 11:57:11 -0800 Subject: resolve-undo: "checkout -m path" uses resolve-undo information Once you resolved conflicts by "git add path", you cannot recreate the conflicted state with "git checkout -m path", because you lost information from higher stages in the index when you resolved them. Since we record the necessary information in the resolve-undo index extension these days, we can reproduce the unmerged state in the index and check it out. Signed-off-by: Junio C Hamano --- t/t2030-unresolve-info.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 't') diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh index 984480271..ea65f391c 100755 --- a/t/t2030-unresolve-info.sh +++ b/t/t2030-unresolve-info.sh @@ -97,4 +97,15 @@ test_expect_success 'plumbing clears' ' check_resolve_undo cleared ' +test_expect_success 'add records checkout -m undoes' ' + prime_resolve_undo && + git diff HEAD && + git checkout --conflict=merge file && + echo checkout used the record and removed it && + check_resolve_undo removed && + echo the index and the work tree is unmerged again && + git diff >actual && + grep "^++<<<<<<<" actual +' + test_done -- cgit v1.2.1 From 8aa38563b22c84b06ea1fff9638cc1f44fda726f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 25 Dec 2009 13:40:02 -0800 Subject: resolve-undo: teach "update-index --unresolve" to use resolve-undo info The update-index plumbing command had a hacky --unresolve implementation that was written back in the days when merge was the only way for users to end up with higher stages in the index, and assumed that stage #2 must have come from HEAD, stage #3 from MERGE_HEAD and didn't bother to compute the stage #1 information. There were several issues with this approach: - These days, merge is not the only command, and conflicts coming from commands like cherry-pick, "am -3", etc. cannot be recreated by looking at MERGE_HEAD; - For a conflict that came from a merge that had renames, picking up the same path from MERGE_HEAD and HEAD wouldn't help recreating it, either; - It may have been Ok not to recreate stage #1 back when it was written, because "diff --ours/--theirs" were the only availble ways to review conflicts and they don't need stage #1 information. "diff --cc" that was invented much later is a lot more useful way but it needs stage #1. We can use resolve-undo information recorded in the index extension to solve all of these issues. Signed-off-by: Junio C Hamano --- t/t2030-unresolve-info.sh | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 't') diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh index ea65f391c..28e2eb1ce 100755 --- a/t/t2030-unresolve-info.sh +++ b/t/t2030-unresolve-info.sh @@ -108,4 +108,11 @@ test_expect_success 'add records checkout -m undoes' ' grep "^++<<<<<<<" actual ' +test_expect_success 'unmerge with plumbing' ' + prime_resolve_undo && + git update-index --unresolve file && + git ls-files -u >actual && + test $(wc -l Date: Fri, 25 Dec 2009 15:51:32 -0800 Subject: rerere forget path: forget recorded resolution After you find out an earlier resolution you told rerere to use was a mismerge, there is no easy way to clear it. A new subcommand "forget" can be used to tell git to forget a recorded resolution, so that you can redo the merge from scratch. Signed-off-by: Junio C Hamano --- t/t2030-unresolve-info.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 't') diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh index 28e2eb1ce..a38bd6df8 100755 --- a/t/t2030-unresolve-info.sh +++ b/t/t2030-unresolve-info.sh @@ -115,4 +115,29 @@ test_expect_success 'unmerge with plumbing' ' test $(wc -l actual && + echo "$rerere_id file" >expect && + test_cmp expect actual +' + test_done -- cgit v1.2.1