{"thread":{"id":"13240","subject":"[PATCH 3/5] Restructure git-merge.sh","startedAt":"2008-04-24T05:49:58Z","lastAt":"2008-04-24T05:49:58Z","messageCount":1,"participants":["Sverre Hvammen Johansen"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"75132","messageId":"402c10cd0804232249v41308796h986800dc4167a873@mail.gmail.com","threadId":"13240","inReplyTo":null,"subject":"[PATCH 3/5] Restructure git-merge.sh","fromName":"Sverre Hvammen Johansen","fromEmail":"hvammen@gmail.com","sentAt":"2008-04-24T05:49:58Z","receivedAt":"2008-04-24T05:49:58Z","isPatch":true,"sender":{"key":"hvammen@gmail.com","avatar":"https://gravatar.com/avatar/d1fc25ec327eea135af60fe7b56b2a2e21f711aa32167e7f505014ec88aa24bc?d=mp&s=160"},"body":"Restructure git-merge.sh for preparation of new feature:\n\n       Head reduction before selecting merge strategy\n\nSome aspects of this patch does not make much sense without\nthe next patch in this series.\n\nSigned-off-by: Sverre Hvammen Johansen <hvammen@gmail.com>\n---\n git-merge.sh |  186 +++++++++++++++++++++++++++++++++-------------------------\n 1 files changed, 105 insertions(+), 81 deletions(-)\n\ndiff --git a/git-merge.sh b/git-merge.sh\nindex 17f40f2..7c34b6c 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -207,6 +207,47 @@ parse_config () {\n        args_left=$#\n }\n\n+# Find reduced parents\n+# The following variables are set as follow:\n+#   reduced_parents: The reduced parents of those specified on the\ncommand line.\n+#                    However, the actual parents are included if we never ff.\n+#   common:          All common ancestors or not_queried\n+#   ff_head:         Head or an reduced parent that may be a\ncandidate for fast forward\n+find_reduced_parents () {\n+       if test $fast_forward = never\n+       then\n+               reduced_parents=$(git rev-parse \"$@\")\n+               ff_head=$head\n+               common=not_queried\n+       else\n+               if test $# = 1\n+               then\n+                       common=$(git merge-base --all $head \"$1\")\n+                       if test \"$common\" = $head\n+                       then\n+                               reduced_parents=\n+                               ff_head=$1\n+                       elif test \"$common\" = \"$1\"\n+                       then\n+                               reduced_parents=\n+                               ff_head=$head\n+                       else\n+                               reduced_parents=$1\n+                               ff_head=$head\n+\n+                       fi\n+               else\n+                       reduced_parents=$(git show-branch\n--independent $head \"$@\")\n+                       # Here we may actually lie about which bransh\nis ff of head.\n+                       # This will preserve the order the user gave.\n+                       ff_head=${reduced_parents%%$LF*}\n+                       reduced_parents=${reduced_parents#$ff_head}\n+                       reduced_parents=${reduced_parents#$LF}\n+                       common=not_queried\n+               fi\n+       fi\n+}\n+\n test $# != 0 || usage\n\n have_message=\n@@ -294,24 +335,28 @@ do\n done\n set x $remoteheads ; shift\n\n+find_reduced_parents \"$@\"\n+\n+actual_parents=$(git rev-parse \"$@\")\n+\n case \"$use_strategies\" in\n '')\n-       case \"$#\" in\n-       1)\n-               var=\"`git config --get pull.twohead`\"\n+       case \"$actual_parents\" in\n+       ?*\"$LF\"?*)\n+               var=\"`git config --get pull.octopus`\"\n                if test -n \"$var\"\n                then\n                        use_strategies=\"$var\"\n                else\n-                       use_strategies=\"$default_twohead_strategies\"\n+                       use_strategies=\"$default_octopus_strategies\"\n                fi ;;\n        *)\n-               var=\"`git config --get pull.octopus`\"\n+               var=\"`git config --get pull.twohead`\"\n                if test -n \"$var\"\n                then\n                        use_strategies=\"$var\"\n                else\n-                       use_strategies=\"$default_octopus_strategies\"\n+                       use_strategies=\"$default_twohead_strategies\"\n                fi ;;\n        esac\n        ;;\n@@ -339,87 +384,66 @@ do\n        done\n done\n\n-case \"$#\" in\n-1)\n-       common=$(git merge-base --all $head \"$@\")\n-       ;;\n-*)\n-       common=$(git show-branch --merge-base $head \"$@\")\n-       ;;\n-esac\n echo \"$head\" >\"$GIT_DIR/ORIG_HEAD\"\n\n-case \"$fast_forward,$#,$common,$no_commit\" in\n-*,*,'',*)\n-       # No common ancestors found. We need a real merge.\n-       ;;\n-*,1,\"$1\",*)\n-       # If head can reach all the merge then we are up to date.\n-       # but first the most common case of merging one remote.\n-       finish_up_to_date \"Already up-to-date.\"\n-       exit 0\n-       ;;\n-allow,1,\"$head\",*)\n-       # Again the most common case of merging one remote.\n-       echo \"Updating $(git rev-parse --short $head)..$(git rev-parse\n--short $1)\"\n-       git update-index --refresh 2>/dev/null\n-       msg=\"Fast forward\"\n-       if test -n \"$have_message\"\n+if test -z \"$reduced_parents\"\n+then\n+       if test $head = $ff_head\n        then\n-               msg=\"$msg (no commit created; -m option ignored)\"\n-       fi\n-       new_head=$(git rev-parse --verify \"$1^0\") &&\n-       git read-tree -v -m -u --exclude-per-directory=.gitignore\n$head \"$new_head\" &&\n-       finish \"$new_head\" \"$msg\" || exit\n-       dropsave\n-       exit 0\n-       ;;\n-*,1,?*\"$LF\"?*,*)\n-       # We are not doing octopus and not fast forward.  Need a\n-       # real merge.\n-       ;;\n-*,1,*,)\n-       # We are not doing octopus, not fast forward, and have only\n-       # one common.\n-       git update-index --refresh 2>/dev/null\n-       case \"$allow_trivial_merge\" in\n-       t)\n-               # See if it is really trivial.\n-               git var GIT_COMMITTER_IDENT >/dev/null || exit\n-               echo \"Trying really trivial in-index merge...\"\n-               if git read-tree --trivial -m -u -v $common $head \"$1\" &&\n-                  result_tree=$(git write-tree)\n-               then\n-                       echo \"Wonderful.\"\n-                       result_commit=$(\n-                               printf '%s\\n' \"$merge_msg\" |\n-                               git commit-tree $result_tree -p HEAD -p \"$1\"\n-                       ) || exit\n-                       finish \"$result_commit\" \"In-index merge\"\n-                       dropsave\n-                       exit 0\n-               fi\n-               echo \"Nope.\"\n-       esac\n-       ;;\n-*)\n-       # An octopus.  If we can reach all the remote we are up to date.\n-       up_to_date=t\n-       for remote\n-       do\n-               common_one=$(git merge-base --all $head $remote)\n-               if test \"$common_one\" != \"$remote\"\n+               finish_up_to_date \"Already up-to-date.\"\n+               exit 0\n+       elif test $fast_forward != never\n+       then\n+               echo \"Updating $(git rev-parse --short $head)..$(git\nrev-parse --short $ff_head)\"\n+               git update-index --refresh 2>/dev/null\n+               msg=\"Fast forward\"\n+               if test -n \"$have_message\"\n                then\n-                       up_to_date=f\n-                       break\n+                       msg=\"$msg (no commit created; -m option ignored)\"\n                fi\n-       done\n-       if test \"$up_to_date\" = t\n-       then\n-               finish_up_to_date \"Already up-to-date. Yeeah!\"\n+               new_head=$(git rev-parse --verify \"$ff_head^0\") &&\n+               git read-tree -v -m -u\n--exclude-per-directory=.gitignore $head \"$new_head\" &&\n+               finish \"$new_head\" \"$msg\" || exit\n+               dropsave\n                exit 0\n        fi\n+fi\n+\n+case \"$actual_parents\" in\n+?*\"$LF\"?*)\n+       # We have more than one actual parent\n+       common=$(git show-branch --merge-base $head $actual_parents)\n        ;;\n+*)\n+       # We have exactly one actual parent\n+       test \"$common\" != not_queried || common=$(git merge-base --all\n$head $actual_parents)\n+       case \"$common\" in\n+       ?*\"$LF\"?*)\n+               # We are not doing octopus and not fast forward.  Need a\n+               # real merge.\n+               ;;\n+       *)\n+               git update-index --refresh 2>/dev/null\n+               if test \"$allow_trivial_merge\" = t\n+               then\n+                       # See if it is really trivial.\n+                       git var GIT_COMMITTER_IDENT >/dev/null || exit\n+                       echo \"Trying really trivial in-index merge...\"\n+                       if git read-tree --trivial -m -u -v $common\n$head $actual_parents &&\n+                               result_tree=$(git write-tree)\n+                       then\n+                               echo \"Wonderful.\"\n+                               result_commit=$(\n+                                       printf '%s\\n' \"$merge_msg\" |\n+                                       git commit-tree $result_tree\n-p HEAD -p $actual_parents\n+                               ) || exit\n+                               finish \"$result_commit\" \"In-index merge\"\n+                               dropsave\n+                               exit 0\n+                       fi\n+                       echo \"Nope.\"\n+               fi ;;\n+       esac ;;\n esac\n\n # We are going to make a new commit.\n@@ -460,7 +484,7 @@ do\n     # Remember which strategy left the state in the working tree\n     wt_strategy=$strategy\n\n-    git-merge-$strategy $common -- \"$head_arg\" \"$@\"\n+    git-merge-$strategy $common -- \"$head_arg\" $actual_parents\n     exit=$?\n     if test \"$no_commit\" = t && test \"$exit\" = 0\n     then\n@@ -530,7 +554,7 @@ case \"$best_strategy\" in\n        echo \"Rewinding the tree to pristine...\"\n        restorestate\n        echo \"Using the $best_strategy to prepare resolving by hand.\"\n-       git-merge-$best_strategy $common -- \"$head_arg\" \"$@\"\n+       git-merge-$best_strategy $common -- \"$head_arg\" $actual_parents\n        ;;\n esac\n\n-- \nSverre Hvammen Johansen\n"}]}