{"thread":{"id":"14544","subject":"[PATCH] git-merge -s theirs","startedAt":"2008-07-20T10:21:30Z","lastAt":"2008-07-28T09:18:24Z","messageCount":3,"participants":["Nanako Shiraishi","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"84014","messageId":"20080720192130.6117@nanako3.lavabit.com","threadId":"14544","inReplyTo":null,"subject":"[PATCH] git-merge -s theirs","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2008-07-20T10:21:30Z","receivedAt":"2008-07-20T10:21:30Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Sometimes people wonder why \"-s ours\" strategy exists but \"-s theirs\" does\nnot.  The reason was explained on the mailing list recently:\n\n  Quoting Junio C Hamano <gitster@pobox.com>:\n\n  > One big problem \"-s theirs\" has, compared to the \"reset to origin,\n  > discarding or setting aside the failed history\" is that your 'master'\n  > history that your further development is based on will keep your failed\n  > crap in it forever if you did \"-s theirs\".  Hopefully you will become a\n  > better programmer over time, and you may eventually have something worth\n  > sharing with the world near the tip of your master branch.  When that\n  > happens, however, you _cannot_ offer your master branch to be pulled by\n  > the upstream, as the wider world will not be interested in your earlier\n  > mistakes at all.\n\nThis patch steals much code from \"git-merge-resolve\" to add \"theirs\"\nstrategy.  Its purpose is to always fail and suggest using the preferred\ncommand \"git reset --hard the-other-commit\".\n\nSigned-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n---\n Makefile            |    3 ++-\n builtin-merge.c     |    1 +\n git-merge-theirs.sh |   34 ++++++++++++++++++++++++++++++++++\n 3 files changed, 37 insertions(+), 1 deletions(-)\n create mode 100755 git-merge-theirs.sh\n\ndiff --git a/Makefile b/Makefile\nindex 2b670d7..22f699a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -240,6 +240,7 @@ SCRIPT_SH += git-lost-found.sh\n SCRIPT_SH += git-merge-octopus.sh\n SCRIPT_SH += git-merge-one-file.sh\n SCRIPT_SH += git-merge-resolve.sh\n+SCRIPT_SH += git-merge-theirs.sh\n SCRIPT_SH += git-mergetool.sh\n SCRIPT_SH += git-parse-remote.sh\n SCRIPT_SH += git-pull.sh\n@@ -1433,7 +1434,7 @@ check-docs::\n \tdo \\\n \t\tcase \"$$v\" in \\\n \t\tgit-merge-octopus | git-merge-ours | git-merge-recursive | \\\n-\t\tgit-merge-resolve | git-merge-subtree | \\\n+\t\tgit-merge-resolve | git-merge-subtree | git-merge-theirs | \\\n \t\tgit-fsck-objects | git-init-db | \\\n \t\tgit-?*--?* ) continue ;; \\\n \t\tesac ; \\\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex edc6016..8ed815b 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -55,6 +55,7 @@ static struct strategy all_strategy[] = {\n \t{ \"octopus\",    DEFAULT_OCTOPUS },\n \t{ \"resolve\",    0 },\n \t{ \"ours\",       NO_FAST_FORWARD | NO_TRIVIAL },\n+\t{ \"theirs\",     NO_FAST_FORWARD | NO_TRIVIAL },\n \t{ \"subtree\",    NO_FAST_FORWARD | NO_TRIVIAL },\n };\n \ndiff --git a/git-merge-theirs.sh b/git-merge-theirs.sh\nnew file mode 100755\nindex 0000000..e228d2b\n--- /dev/null\n+++ b/git-merge-theirs.sh\n@@ -0,0 +1,34 @@\n+#!/bin/sh\n+\n+# The first parameters up to -- are merge bases; the rest are heads.\n+bases= head= remotes= sep_seen=\n+for arg\n+do\n+\tcase \",$sep_seen,$head,$arg,\" in\n+\t*,--,)\n+\t\tsep_seen=yes\n+\t\t;;\n+\t,yes,,*)\n+\t\thead=$arg\n+\t\t;;\n+\t,yes,*)\n+\t\tremotes=\"$remotes$arg \"\n+\t\t;;\n+\t*)\n+\t\tbases=\"$bases$arg \"\n+\t\t;;\n+\tesac\n+done\n+\n+# Give up if we are given two or more remotes -- not handling octopus.\n+case \"$remotes\" in\n+?*' '?*)\n+\texit 2 ;;\n+esac\n+\n+echo \"If you wanted to say the other history is better than your history,\" \n+echo \"use 'git reset --hard $remotes' instead.\" \n+echo \"If you want to keep a record of your failure, you can create a\" \n+echo \"new branch from the current HEAD before running the reset command.\" \n+\n+exit 2\n-- \n1.5.6.3\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"84071","messageId":"7vhcak45ez.fsf@gitster.siamese.dyndns.org","threadId":"14544","inReplyTo":"20080720192130.6117@nanako3.lavabit.com","subject":"Re: [PATCH] git-merge -s theirs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-20T21:22:28Z","receivedAt":"2008-07-20T21:22:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nanako Shiraishi <nanako3@lavabit.com> writes:\n\n> This patch steals much code from \"git-merge-resolve\" to add \"theirs\"\n> strategy.  Its purpose is to always fail and suggest using the preferred\n> command \"git reset --hard the-other-commit\".\n> ...\n> +echo \"If you wanted to say the other history is better than your history,\" \n> +echo \"use 'git reset --hard $remotes' instead.\" \n> +echo \"If you want to keep a record of your failure, you can create a\" \n> +echo \"new branch from the current HEAD before running the reset command.\" \n> +\n> +exit 2\n\nThat is certainly cute, but I do not like it for two reasons:\n\n - This advertizes \"theirs\" as available when you ask \"git merge -s whoa\",\n   and then the user is told \"don't use this stupid, go away\".  That is\n   not exactly a good diplomacy to earn friends.\n\n - The message gives a rather long hexdecimal string in its suggestion to\n   run \"git reset --hard\".  This is not exactly your fault, though. The\n   original refname the user gave to \"git-merge\" is not available to your\n   strategy.\n"},{"id":"85262","messageId":"7vfxpus6xr.fsf_-_@gitster.siamese.dyndns.org","threadId":"14544","inReplyTo":"7vhcak45ez.fsf@gitster.siamese.dyndns.org","subject":"Re* [PATCH] git-merge -s theirs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-28T09:18:24Z","receivedAt":"2008-07-28T09:18:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Nanako Shiraishi <nanako3@lavabit.com> writes:\n> ...\n> That is certainly cute, but I do not like it for two reasons:\n>\n>  - This advertizes \"theirs\" as available when you ask \"git merge -s whoa\",\n>    and then the user is told \"don't use this stupid, go away\".  That is\n>    not exactly a good diplomacy to earn friends.\n>\n>  - The message gives a rather long hexdecimal string in its suggestion to\n>    run \"git reset --hard\".  This is not exactly your fault, though. The\n>    original refname the user gave to \"git-merge\" is not available to your\n>    strategy.\n\nThis does not address the first point at all, but attempts to solve the\nsecond issue.  Strategies now get the remote in the symbolic form\noriginally used on the command line.\n\nAll strategies know that they need to expect that the refs can be given\nwith arbitrary SHA-1 expressions, so this change should be safe.\n\n builtin-merge.c |   20 +++++++++++++++-----\n 1 files changed, 15 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex e78fa18..1a9850f 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -22,6 +22,7 @@\n #include \"log-tree.h\"\n #include \"color.h\"\n #include \"rerere.h\"\n+#include \"decorate.h\"\n \n #define DEFAULT_TWOHEAD (1<<0)\n #define DEFAULT_OCTOPUS (1<<1)\n@@ -504,7 +505,7 @@ static void write_tree_trivial(unsigned char *sha1)\n }\n \n static int try_merge_strategy(const char *strategy, struct commit_list *common,\n-\t\t\t      const char *head_arg)\n+\t\t\t      const char *head_arg, struct decoration *symbolic)\n {\n \tconst char **args;\n \tint i = 0, ret;\n@@ -520,8 +521,12 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,\n \t\targs[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));\n \targs[i++] = \"--\";\n \targs[i++] = head_arg;\n-\tfor (j = remoteheads; j; j = j->next)\n-\t\targs[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));\n+\tfor (j = remoteheads; j; j = j->next) {\n+\t\tchar *name = lookup_decoration(symbolic, &j->item->object);\n+\t\tif (!name)\n+\t\t\tname = sha1_to_hex(j->item->object.sha1);\n+\t\targs[i++] = xstrdup(name);\n+\t}\n \targs[i] = NULL;\n \tret = run_command_v_opt(args, RUN_GIT_CMD);\n \tstrbuf_release(&buf);\n@@ -773,6 +778,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \tstruct commit_list *common = NULL;\n \tconst char *best_strategy = NULL, *wt_strategy = NULL;\n \tstruct commit_list **remotes = &remoteheads;\n+\tstruct decoration symbolic_remote_head;\n \n \tsetup_work_tree();\n \tif (unmerged_cache())\n@@ -870,6 +876,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\tstrbuf_addf(&buf, \" %s\", argv[i]);\n \tsetenv(\"GIT_REFLOG_ACTION\", buf.buf, 0);\n \tstrbuf_reset(&buf);\n+\tmemset(&symbolic_remote_head, 0, sizeof(symbolic_remote_head));\n \n \tfor (i = 0; i < argc; i++) {\n \t\tstruct object *o;\n@@ -877,6 +884,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\to = peel_to_type(argv[i], 0, NULL, OBJ_COMMIT);\n \t\tif (!o)\n \t\t\tdie(\"%s - not something we can merge\", argv[i]);\n+\t\tadd_decoration(&symbolic_remote_head, o, xstrdup(argv[i]));\n \t\tremotes = &commit_list_insert(lookup_commit(o->sha1),\n \t\t\tremotes)->next;\n \n@@ -1041,7 +1049,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\twt_strategy = use_strategies[i]->name;\n \n \t\tret = try_merge_strategy(use_strategies[i]->name,\n-\t\t\tcommon, head_arg);\n+\t\t\t\t\t common, head_arg,\n+\t\t\t\t\t &symbolic_remote_head);\n \t\tif (!option_commit && !ret) {\n \t\t\tmerge_was_ok = 1;\n \t\t\t/*\n@@ -1105,7 +1114,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\trestore_state();\n \t\tprintf(\"Using the %s to prepare resolving by hand.\\n\",\n \t\t\tbest_strategy);\n-\t\ttry_merge_strategy(best_strategy, common, head_arg);\n+\t\ttry_merge_strategy(best_strategy, common, head_arg,\n+\t\t\t\t   &symbolic_remote_head);\n \t}\n \n \tif (squash)\n"}]}