{"thread":{"id":"43434","subject":"[PATCH] git-merge: make it usable as the first class UI","startedAt":"2006-11-19T21:26:11Z","lastAt":"2006-11-22T23:02:45Z","messageCount":7,"participants":["Junio C Hamano","Jakub Narebski","linux@horizon.com"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"298071","messageId":"20061119212611.13038.qmail@science.horizon.com","threadId":"43434","inReplyTo":null,"subject":"Feature request: git-pull -e/--edit","fromName":"","fromEmail":"linux@horizon.com","sentAt":"2006-11-19T21:26:11Z","receivedAt":"2006-11-19T21:26:11Z","isPatch":false,"sender":{"key":"linux@horizon.com","avatar":null},"body":"The last end-user use I can think of for git-merge instead\nof git-pull is providing a custom commit message.\n\nWould it be possible to add -m and -e options to git-pull?\n\nThe problem I can see is that the latter would have to be added to\ngit-merge, and the guts there are a bit intricate; it uses git-commit-tree\ndirectly rather than git-commit, so I can't just pass through the\narguments.\n\nAssuming it's just as much of a pain for someone else, would it\nstill be worth the effort?  Can git-merge be cleaned up?\n\nThe manual option is to use \"git merge --no-commit\" and then supply the\narguments to git-commit in the usual way.\n\nBut I notice that --no-commit actually changes git's merging\ntechnique.  If it's specified, the trivial in-index merge doesn't\nappear to be attempted.  I don't think it makes a huge difference,\n"},{"id":"295452","messageId":"7vy7q67tf2.fsf@assigned-by-dhcp.cox.net","threadId":"43434","inReplyTo":"20061119212611.13038.qmail@science.horizon.com","subject":"Re: Feature request: git-pull -e/--edit","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-20T02:17:53Z","receivedAt":"2006-11-20T02:17:53Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"linux@horizon.com writes:\n\n> The last end-user use I can think of for git-merge instead\n> of git-pull is providing a custom commit message.\n>\n> Would it be possible to add -m and -e options to git-pull?\n>\n> The problem I can see is that the latter would have to be added to\n> git-merge, and the guts there are a bit intricate; it uses git-commit-tree\n> directly rather than git-commit, so I can't just pass through the\n> arguments.\n\nHow often is this desired, when the merge is clean?  \n\nIf the answer is \"not so often\", you can already use \"commit\n--amend\" after \"pull\" creates an automated merge commit.\n"},{"id":"295746","messageId":"20061120024308.18620.qmail@science.horizon.com","threadId":"43434","inReplyTo":"7vy7q67tf2.fsf@assigned-by-dhcp.cox.net","subject":"Re: Feature request: git-pull -e/--edit","fromName":"","fromEmail":"linux@horizon.com","sentAt":"2006-11-20T02:43:08Z","receivedAt":"2006-11-20T02:43:08Z","isPatch":false,"sender":{"key":"linux@horizon.com","avatar":null},"body":"> How often is this desired, when the merge is clean?  \n\nWell, if I could quote your own words:\n\n>> I use \"git pull . topicA topicB\" for a tetrapus, so that is not\n>> a reason for me, but when a topicA's older parts are worthy to\n>> be in 'next' while later parts are not yet, I often do (on 'next'):\n>> \n>>\tgit merge \"Merge early part of branch 'topicA'\" HEAD topicA~3\n\nI can't speak from personal experience, but a merge can bring in a lot\nof changes, and sometimes the auto-generated message doesn't say quite\nas much as you'd like.\n\nThe commits on the branch speak for themselves, of course, but sometimes\nit's nice to add the same sort of overview that appears in a [PATCH 0/13]\ne-mail.  We wouldn't have that convention if there wasn't a frequent\ndesire for it.\n\n(Indeed, it might be nice to come up with a way of including a piece of\nthe \"please pull\" e-mail, similar to the way that git-applypatch works.)\n\n> If the answer is \"not so often\", you can already use \"commit\n> --amend\" after \"pull\" creates an automated merge commit.\n\nIt's not done very often right now, but how much of that is due to\nthe awkwardness?  I agree it works perfectly, but \"commit --amend\"\nhas very much the feel of a workaround.\n\nI'm not going to besiege Troy for a decade over the idea, but it seemed\n"},{"id":"297083","messageId":"7v8xi67qhq.fsf@assigned-by-dhcp.cox.net","threadId":"43434","inReplyTo":"20061120024308.18620.qmail@science.horizon.com","subject":"Re: Feature request: git-pull -e/--edit","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-20T03:21:05Z","receivedAt":"2006-11-20T03:21:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"linux@horizon.com writes:\n\n>> How often is this desired, when the merge is clean?  \n>\n> Well, if I could quote your own words:\n>\n>>> I use \"git pull . topicA topicB\" for a tetrapus, so that is not\n>>> a reason for me, but when a topicA's older parts are worthy to\n>>> be in 'next' while later parts are not yet, I often do (on 'next'):\n>>> \n>>>\tgit merge \"Merge early part of branch 'topicA'\" HEAD topicA~3\n>\n> I can't speak from personal experience, but a merge can bring in a lot\n> of changes, and sometimes the auto-generated message doesn't say quite\n> as much as you'd like.\n\nThat is more or less irrelevant example.  I was only saying that\nit is a workaround to emulate \"git pull . topicA~3\"; if that\nform worked, I would keep the automated fmt-merge-msg output\nthat is currently recorded in the merge and I do not see any\nneed to edit it further.\n\n> (Indeed, it might be nice to come up with a way of including a piece of\n> the \"please pull\" e-mail, similar to the way that git-applypatch works.)\n\nThat is a lot more relevant example.  For example, I could\nimagine that Linus coming up with a wrapper that is fed a series\nof e-mails and:\n\n * if it is a patch, run git-applymbox on it as before,\n\n * if it is a pull request, then extract the URL and branch, run\n   \"git pull\" on that, match the \"diff ORIG_HEAD\" output against\n   what is in the pull request and,\n\n   - warn if there are huge discrepancies;\n\n   - otherwise annotate the commit message with the explanation\n     of the series taken from the pull request message.\n\nBut even in that workflow, \"annotate the commit\" comes after\npull happens and the merge result is verified, so I do not quite\nsee \"commit --amend\" as a \"workaround\" as you said.\n\nHaving said that, I think the real reason that the whole \"merge\"\nmessage generation feels awkward comes from the historical\ndivision of labor between pull and merge.\n\n\"git merge\" started its life as the first level command (with a\nfunny syntax that does not even take command line option -m,\nbecause you are supposed to give the whole merge message and\n\"git merge\" itself does not do anything to affect the merge\nmessage on its own).  When it was pushed further back to the\n\"worker behind the scene\" status, the task of coming up with a\nfancier automated merge message were still left to the \"git\npull\" command which (1) is the UI level command that the users\nare expected to use, and (2) knows much more about the context\nwhere the merge is generated than \"git merge\" itself.  As a\nresult, \"git merge\" still takes the whole message prepared and\nit does not do anything on its own.\n\nSo if we rename the current \"git merge\" to \"git-merge--record\"\n(or any name \"git pull\" uses internally to record the merge\ncommit), and make \"git merge\" a synonym to \"git pull .\", and\ngive a command line option -m to \"git pull\" to _affect_ the\nresulting merge message, I would think everybody would become\nquite happy.  It means:\n\n - People can say \"git merge this-branch\" (which is internally\n   translated to \"git pull . this-branch\");\n\n - People can say \"git pull -m 'I am doing this merge for such\n   and such reason' $URL $branch\" to _include_ that message in\n   the resulting merge commit;\n\n - The same can be said about \"git merge -m 'comment' $branch\".\n\nI said _affect_ and _include_ in the above because I suspect\nthat most of the time you do not want to _replace_ the\nautogenerated part (\"Merge branch of repo\", and if you are\npulling from your subordinate trees the merge summary message as\nwell).\n"},{"id":"295023","messageId":"ejrnbg$sg5$1@sea.gmane.org","threadId":"43434","inReplyTo":"7v8xi67qhq.fsf@assigned-by-dhcp.cox.net","subject":"Re: Feature request: git-pull -e/--edit","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-20T08:02:16Z","receivedAt":"2006-11-20T08:02:16Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> So if we rename the current \"git merge\" to \"git-merge--record\"\n\nor git-merge-driver\n\n> (or any name \"git pull\" uses internally to record the merge\n> commit), and make \"git merge\" a synonym to \"git pull .\", and\n> give a command line option -m to \"git pull\" to _affect_ the\n> resulting merge message, I would think everybody would become\n> quite happy.  It means:\n> \n>  - People can say \"git merge this-branch\" (which is internally\n>    translated to \"git pull . this-branch\");\n> \n>  - People can say \"git pull -m 'I am doing this merge for such\n>    and such reason' $URL $branch\" to _include_ that message in\n>    the resulting merge commit;\n> \n>  - The same can be said about \"git merge -m 'comment' $branch\".\n> \n> I said _affect_ and _include_ in the above because I suspect\n> that most of the time you do not want to _replace_ the\n> autogenerated part (\"Merge branch of repo\", and if you are\n> pulling from your subordinate trees the merge summary message as\n> well).\n\nI'm all for adding -m <msg> option to git-pull (and perhaps also common\nother message generation options: -F <file>, --edit). I'm even for adding\n-m option to git-merge. \n\nMaking \"git merge\" to be a synonym to \"git pull .\"... I'm not so sure.\nI'd rather we don't lose the ability to give arbitrary refs ar \"other\"\nheads like in\n\n  git merge \"Merge early part of branch 'topicA'\" HEAD topicA~3\n\nexample, and ability (if there is such ability) to not include HEAD (current\nversion of branch) as first parent like in\n\n  git checkout pu\n  git merge \"Merge branch 'topicA', 'topicB'\" topicA topicB\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"294768","messageId":"7vu00u4e2d.fsf@assigned-by-dhcp.cox.net","threadId":"43434","inReplyTo":"7v8xi67qhq.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] git-merge: make it usable as the first class UI","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-20T10:17:46Z","receivedAt":"2006-11-20T10:17:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> So if we rename the current \"git merge\" to \"git-merge--record\"\n> (or any name \"git pull\" uses internally to record the merge\n> commit), and make \"git merge\" a synonym to \"git pull .\", and\n> give a command line option -m to \"git pull\" to _affect_ the\n> resulting merge message, I would think everybody would become\n> quite happy.  It means:\n>\n>  - People can say \"git merge this-branch\" (which is internally\n>    translated to \"git pull . this-branch\");\n>\n>  - People can say \"git pull -m 'I am doing this merge for such\n>    and such reason' $URL $branch\" to _include_ that message in\n>    the resulting merge commit;\n>\n>  - The same can be said about \"git merge -m 'comment' $branch\".\n>\n> I said _affect_ and _include_ in the above because I suspect\n> that most of the time you do not want to _replace_ the\n> autogenerated part (\"Merge branch of repo\", and if you are\n> pulling from your subordinate trees the merge summary message as\n> well).\n\nI did a moral equivalent of the above without renaming the\ncommand \"git merge\" and will be pushing the result out in \"pu\"\nshortly.\n\nThe following is for commenting only -- it depends on an earlier\npatch in \"pu\".\n\n-- >8 --\n[PATCH] git-merge: make it usable as the first class UI\n\nThis teaches the oft-requested syntax\n\n\tgit merge $commit\n\nto implement merging the named commit to the current branch.\nThis hopefully would make \"git merge\" usable as the first class\nUI instead of being a mere backend for \"git pull\".\n\nMost notably, $commit above can be any committish, so you can\nsay for example:\n\n\tgit merge js/shortlog~2\n\nto merge early part of a topic branch without merging the rest\nof it.\n\nA custom merge message can be given with the new --message=<msg>\nparameter.  The message is prepended in front of the usual\n\"Merge ...\" message autogenerated with fmt-merge-message.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n Documentation/git-merge.txt |   18 +++++++++---\n git-merge.sh                |   61 ++++++++++++++++++++++++++++++++++++++-----\n 2 files changed, 67 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt\nindex bebf30a..e2954aa 100644\n--- a/Documentation/git-merge.txt\n+++ b/Documentation/git-merge.txt\n@@ -8,12 +8,14 @@ git-merge - Grand Unified Merge Driver\n \n SYNOPSIS\n --------\n-'git-merge' [-n] [--no-commit] [-s <strategy>]... <msg> <head> <remote> <remote>...\n-\n+[verse]\n+'git-merge' [-n] [--no-commit] [--squash] [-s <strategy>]...\n+\t[--reflog-action=<action>]\n+\t-m=<msg> <remote> <remote>...\n \n DESCRIPTION\n -----------\n-This is the top-level user interface to the merge machinery\n+This is the top-level interface to the merge machinery\n which drives multiple merge strategy scripts.\n \n \n@@ -27,13 +29,19 @@ include::merge-options.txt[]\n \tto give a good default for automated `git-merge` invocations.\n \n <head>::\n-\tour branch head commit.\n+\tOur branch head commit.  This has to be `HEAD`, so new\n+\tsyntax does not require it\n \n <remote>::\n-\tother branch head merged into our branch.  You need at\n+\tOther branch head merged into our branch.  You need at\n \tleast one <remote>.  Specifying more than one <remote>\n \tobviously means you are trying an Octopus.\n \n+--reflog-action=<action>::\n+\tThis is used internally when `git-pull` calls this command\n+\tto record that the merge was created by `pull` command\n+\tin the `ref-log` entry that results from the merge.\n+\n include::merge-strategies.txt[]\n \n \ndiff --git a/git-merge.sh b/git-merge.sh\nindex 84c3acf..25deb1e 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -3,7 +3,8 @@\n # Copyright (c) 2005 Junio C Hamano\n #\n \n-USAGE='[-n] [--no-commit] [--squash] [-s <strategy>]... <merge-message> <head> <remote>+'\n+USAGE='[-n] [--no-commit] [--squash] [-s <strategy>] [--reflog-action=<action>] [-m=<merge-message>] <commit>+'\n+\n . git-sh-setup\n \n LF='\n@@ -92,7 +93,7 @@ finish () {\n \n case \"$#\" in 0) usage ;; esac\n \n-rloga=\n+rloga= have_message=\n while case \"$#\" in 0) break ;; esac\n do\n \tcase \"$1\" in\n@@ -125,17 +126,63 @@ do\n \t--reflog-action=*)\n \t\trloga=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n \t\t;;\n+\t-m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)\n+\t\tmerge_msg=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'`\n+\t\thave_message=t\n+\t\t;;\n+\t-m|--m|--me|--mes|--mess|--messa|--messag|--message)\n+\t\tshift\n+\t\tcase \"$#\" in\n+\t\t1)\tusage ;;\n+\t\tesac\n+\t\tmerge_msg=\"$1\"\n+\t\thave_message=t\n+\t\t;;\n \t-*)\tusage ;;\n \t*)\tbreak ;;\n \tesac\n \tshift\n done\n \n-merge_msg=\"$1\"\n-shift\n-head_arg=\"$1\"\n-head=$(git-rev-parse --verify \"$1\"^0) || usage\n-shift\n+# This could be traditional \"merge <msg> HEAD <commit>...\"  and the\n+# way we can tell it is to see if the second token is HEAD, but some\n+# people might have misused the interface and used a committish that\n+# is the same as HEAD there instead.  Traditional format never would\n+# have \"-m\" so it is an additional safety measure to check for it.\n+\n+if test -z \"$have_message\" &&\n+\tsecond_token=$(git-rev-parse --verify \"$2^0\" 2>/dev/null) &&\n+\thead_commit=$(git-rev-parse --verify \"HEAD\" 2>/dev/null) &&\n+\ttest \"$second_token\" = \"$head_commit\"\n+then\n+\tmerge_msg=\"$1\"\n+\tshift\n+\thead_arg=\"$1\"\n+\tshift\n+else\n+\t# We are invoked directly as the first-class UI.\n+\thead_arg=HEAD\n+\n+\t# All the rest are the commits being merged; prepare\n+\t# the standard merge summary message to be appended to\n+\t# the given message.  If remote is invalid we will die\n+\t# later in the common codepath so we discard the error\n+\t# in this loop.\n+\tmerge_name=$(for remote\n+\t\tdo\n+\t\t\trh=$(git-rev-parse --verify \"$remote\"^0 2>/dev/null)\n+\t\t\tif git show-ref -q --verify \"refs/heads/$remote\"\n+\t\t\tthen\n+\t\t\t\twhat=branch\n+\t\t\telse\n+\t\t\t\twhat=commit\n+\t\t\tfi\n+\t\t\techo \"$rh\t\t$what '$remote'\"\n+\t\tdone | git-fmt-merge-msg\n+\t)\n+\tmerge_msg=\"${merge_msg:+$merge_msg$LF$LF}$merge_name\"\n+fi\n+head=$(git-rev-parse --verify \"$head_arg\"^0) || usage\n \n # All the rest are remote heads\n test \"$#\" = 0 && usage ;# we need at least one remote head.\n-- \n1.4.4.gbacc\n\n"},{"id":"296214","messageId":"7v3b8bozje.fsf@assigned-by-dhcp.cox.net","threadId":"43434","inReplyTo":"20061119212611.13038.qmail@science.horizon.com","subject":"Re: Feature request: git-pull -e/--edit","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-22T23:02:45Z","receivedAt":"2006-11-22T23:02:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"linux@horizon.com writes:\n\n> But I notice that --no-commit actually changes git's merging\n> technique.  If it's specified, the trivial in-index merge doesn't\n> appear to be attempted.  I don't think it makes a huge difference,\n> but is any difference desirable?\n\nThis was done in response to a specific request from the list\nbut I do not remember the details.  If I were to research the\nbackground I would\n\n (1) first, look at the authordate of the commit that introduced\n     the change.  For this, I would most likely use:\n\n\tgit log -p -S--no-commit -- git-pull.sh\n\n (2) go back to the list archive and find the thread that\n     predates that commit by a few days.\n"}]}