Re: Handling merge conflicts a bit more gracefully..
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:41:59
quoted
quoted
quoted
quoted
"LT" == Linus Torvalds [off-list ref] writes:
LT> What happens now in the case of a merge conflict is: LT> - the merge is obviously not committed LT> - we do all the successful merges, and update the index file for them LT> - for the files that conflict, we force the index to contain the old LT> version of the file (ie we remove the merge from the index), and we LT> write the (failed) output of the merge into the working directory, and LT> we complain loudly: LT> Comments? It would be good to have people test this and maybe even write a LT> few automated tests that it all works as expected.. OK, I'll bite. Other than some minor details, the work tree seems to be updated with the result of the merge, either successful one or failed one. 2a68a8659f7dc55fd285d235ae2d19e7a8116c30 \ (from f9e7750621ca5e067f58a679caff5ff2f9881c4c)
diff --git a/git-merge-one-file-script b/git-merge-one-file-script
--- a/git-merge-one-file-script
+++ b/git-merge-one-file-script@@ -19,22 +19,25 @@ case "${1:-.}${2:-.}${3:-.}" in # Deleted in both. # "$1..") - echo "ERROR: $4 is removed in both branches." - echo "ERROR: This is a potential rename conflict." - exit 1;; + echo "WARNING: $4 is removed in both branches." + echo "WARNING: This is a potential rename conflict." + exec git-update-cache --remove -- "$4" ;;
Making sure that the path does not exist in the work tree with test -f "$4" would be more sensible, before running --remove. # # Deleted in one and unchanged in the other. # "$1.." | "$1.$1" | "$1$1.") echo "Removing $4" - exec git-update-cache --force-remove "$4" ;; + rm -f -- "$4" + exec git-update-cache --remove -- "$4" ;; Make sure "$4" is not a directory, perhaps? At least barf if that 'rm -f -- "$4"' fails? # # Modified in both, but differently. #
@@ -55,19 +60,21 @@ case "${1:-.}${2:-.}${3:-.}" in orig=`git-unpack-file $1` src1=`git-unpack-file $2` src2=`git-unpack-file $3` - merge "$src2" "$orig" "$src1" + merge -p "$src1" "$orig" "$src2" > "$4" ret=$? + rm -f -- "$orig" "$src1" "$src2" if [ "$6" != "$7" ]; then echo "ERROR: Permissions $5->$6->$7 don't match." + ret=1 fi if [ $ret -ne 0 ]; then - echo "ERROR: Leaving conflict merge in $src2." + # Reset the index to the first branch, making + # git-diff-file useful + git-update-cache --add --cacheinfo "$6" "$2" "$4" + echo "ERROR: Merge conflict in $4." exit 1 fi - sha1=`git-write-blob "$src2"` || { - echo "ERROR: Leaving conflict merge in $src2." - } - exec git-update-cache --add --cacheinfo "$6" $sha1 "$4" ;; + exec git-update-cache --add -- "$4" ;; *) echo "ERROR: Not handling case $4: $1 -> $2 -> $3" ;; esac
Again, make sure "$4" is not a directory before redirecting into it from merge, so that you can tell merge failures from it?