{"thread":{"id":"19922","subject":"Could this be done simpler?","startedAt":"2009-06-24T21:35:13Z","lastAt":"2009-06-27T00:26:33Z","messageCount":15,"participants":["Linus Torvalds","Junio C Hamano","Randal L. Schwartz","Matthias Andree","Michael J Gruber","Christian Couder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"116885","messageId":"alpine.LFD.2.01.0906241426120.3154@localhost.localdomain","threadId":"19922","inReplyTo":null,"subject":"Could this be done simpler?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2009-06-24T21:35:13Z","receivedAt":"2009-06-24T21:35:13Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nOk, so I have a practice of occasionally doing octopus merges when I have \ntwo branches with trivial fixes from the same person.\n\nThat all works fine when they use the \"multiple branches in the same \nrepository\" approach (eg x86 \"tip\" tree), but other people tend to prefer \nto use multiple repositories for different features, rather than branches. \nAnd git generally lets you do things either way with no real difference.\n\nBut for the octopus case, it does make a difference. You can easily make \noctopus merges only from one repository.\n\nWhich is kind of sad. \n\nSo I did kernel commit c6223048259006759237d826219f0fa4f312fb47 by \nbasically doing the 'git pull\" logic by hand, and while this was just a \ntrial and maybe I'll never feel the urge to do it again, I'm wondering it \nmaybe we should make it easier to do.\n\nRight now the \"git pull\" syntax is\n\n\tgit pull <repo> <branch>*\n\nand you cannot specify multiple repositories, only multiple branches.\n\nBut at the same time, it should be pretty unambiguous whether an argument \nis a repository or a branch (':' in a remote repository, or \"/\" or \"..\" at \nthe beginning of a local one - all invalid in branch names).\n\nSo it _should_ be syntactically unambiguous to allow\n\n\tgit pull (<repo> <branch>*)+\n\nfor the octopus case. Hmm?\n\n\t\tLinus\n"},{"id":"116897","messageId":"7veit9m8cs.fsf@alter.siamese.dyndns.org","threadId":"19922","inReplyTo":"alpine.LFD.2.01.0906241426120.3154@localhost.localdomain","subject":"Re: Could this be done simpler?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-25T01:04:51Z","receivedAt":"2009-06-25T01:04:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> Ok, so I have a practice of occasionally doing octopus merges when I have \n> two branches with trivial fixes from the same person.\n>\n> That all works fine when they use the \"multiple branches in the same \n> repository\" approach (eg x86 \"tip\" tree), but other people tend to prefer \n> to use multiple repositories for different features, rather than branches. \n> And git generally lets you do things either way with no real difference.\n>\n> But for the octopus case, it does make a difference. You can easily make \n> octopus merges only from one repository.\n>\n> Which is kind of sad. \n>\n> So I did kernel commit c6223048259006759237d826219f0fa4f312fb47 by \n> basically doing the 'git pull\" logic by hand, and while this was just a \n> trial and maybe I'll never feel the urge to do it again, I'm wondering it \n> maybe we should make it easier to do.\n\nEvery once in a while I have this urge to see how it feels to be Linus\nby pretending to be him, trying what he did.\n\n(1) So where is he?\n\n    $ git pull\n    ...\n    From git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6\n       f234012..28d0325  master     -> linus\n     * [new tag]         v2.6.31-rc1 -> v2.6.31-rc1\n    Updating f234012..28d0325\n    Fast forward\n     ...\n\n(2) Let's pretend to be Linus, just before he made this merge.\n\n    $ git checkout c62230^\n\n(3) Let's see what he did with that thing.\n\n    $ git show c62230\n    commit c6223048259006759237d826219f0fa4f312fb47\n    Merge: bd453cd d5bb68a 3a6a6c1\n    Author: Linus Torvalds <torvalds@linux-foundation.org>\n    Date:   Wed Jun 24 14:17:14 2009 -0700\n\n        Merge branches 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/{vfs-2.6,audit-current}\n\n        * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:\n          another race fix in jfs_check_acl()\n          Get \"no acls for this inode\" right, fix shmem breakage\n          inline functions left without protection of ifdef (acl)\n\n        * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:\n          audit: inode watches depend on CONFIG_AUDIT not CONFIG_AUDIT_SYSCALL\n\n    Ah, so we know the two repositories and branches involved.\n\n(4) Let's pretend to be Linus.  Fetch the first branch and drop the\n    necessary information in FETCH_HEAD.\n\n    $ git fetch \\\n      git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 \\\n      for-linus\n\n(5) Continue pretending to be Linus, complete the octopus.  The key is to\n    let the \"fetch\" phase of this to append to the FETCH_HEAD, not\n    replacing it.\n\n    $ git pull --append \\\n      git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current \\\n      for-linus\n\n(6) Did I succeed?  Let's see.\n\n    $ git diff c62230\n\n    Yay, identical tree.\n\n(7) How does the log message look?\n\n    $ git show\n    commit cb1e4198421091ea5844d93624d5d5499537dbe0\n    Merge: bd453cd d5bb68a 3a6a6c1\n    Author: Junio C Hamano <gitster@pobox.com>\n    Date:   Wed Jun 24 17:45:09 2009 -0700\n\n        Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6; branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current into HEAD\n\n        * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:\n          another race fix in jfs_check_acl()\n          Get \"no acls for this inode\" right, fix shmem breakage\n          inline functions left without protection of ifdef (acl)\n\n        * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:\n          audit: inode watches depend on CONFIG_AUDIT not CONFIG_AUDIT_SYSCALL\n\n    Hmm, Linus's combined notation on the summary line that uses {} is\n    much nicer.\n\n> Right now the \"git pull\" syntax is\n>\n> \tgit pull <repo> <branch>*\n>\n> and you cannot specify multiple repositories, only multiple branches.\n>\n> But at the same time, it should be pretty unambiguous whether an argument \n> is a repository or a branch (':' in a remote repository, or \"/\" or \"..\" at \n> the beginning of a local one - all invalid in branch names).\n>\n> So it _should_ be syntactically unambiguous to allow\n>\n> \tgit pull (<repo> <branch>*)+\n>\n> for the octopus case. Hmm?\n\nStrictly speaking, you are not quite correct.  Arguments after <repo> can\nbe storing refspecs and they do come with colon.\n\nConclusion.  git-fmt-merge-msg may need to learn the trick of using {}.\nNo other changes needed.\n\nSide note.\n\nPeople sometimes say, and I am certain I agreed to them on more than one\noccasions, that Octopus hurt bisectability and does not have much value in\nreal life.  I've always thought this bisectability issue was a downside of\nOctopus merges, but now I think about it, perhaps \"git bisect\" can be\ntaught to dynamically decompose an Octopus merges into a sequence of\ntwo-head virtual merges while bisecting.  We strongly discourage and do\nnot allow conflicting Octopus merges, so when you need to bisect a history\nwith an Octopus that looks like this:\n\n    ---o---A\n            \\    \n  ---o---B---M---o\n            /    \n    ---o---C\n\nit should be able to mechanically decompose it, without conflicts, into\n\n\n    ---o---A\n            \\    \n  ---o---B---M1--M2--o\n                /    \n        ---o---C\n\nwhere the tree of M and the tree of M2 are identical.\n"},{"id":"116936","messageId":"863a9oz8lh.fsf@blue.stonehenge.com","threadId":"19922","inReplyTo":"7veit9m8cs.fsf@alter.siamese.dyndns.org","subject":"Re: Could this be done simpler?","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2009-06-25T14:33:30Z","receivedAt":"2009-06-25T14:33:30Z","isPatch":false,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"Junio\" == Junio C Hamano <gitster@pobox.com> writes:\n\nJunio> (5) Continue pretending to be Linus, complete the octopus.  The key is to\nJunio>     let the \"fetch\" phase of this to append to the FETCH_HEAD, not\nJunio>     replacing it.\n\nJunio>     $ git pull --append \\\nJunio>       git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current \\\nJunio>       for-linus\n\nThe relatively current doc of \"--append\" looks like this:\n\n       -a, --append\n           Append ref names and object names of fetched refs to the existing\n           contents of will be overwritten.\n\nI read this three times, and still don't know what it means (and it doesn't\neven scan well as English), so I would have never known to use this strategy.\nCan you explain this more in detail, or point at something in the mailing list\nthat does?\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nSmalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.\nSee http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion\n"},{"id":"116942","messageId":"4A43A6B3.5020407@gmx.de","threadId":"19922","inReplyTo":"863a9oz8lh.fsf@blue.stonehenge.com","subject":"Re: Could this be done simpler?","fromName":"Matthias Andree","fromEmail":"matthias.andree@gmx.de","sentAt":"2009-06-25T16:32:51Z","receivedAt":"2009-06-25T16:32:51Z","isPatch":false,"sender":{"key":"matthias.andree@gmx.de","avatar":null},"body":"Randal L. Schwartz schrieb:\n>>>>>> \"Junio\" == Junio C Hamano <gitster@pobox.com> writes:\n> \n> Junio> (5) Continue pretending to be Linus, complete the octopus.  The key is to\n> Junio>     let the \"fetch\" phase of this to append to the FETCH_HEAD, not\n> Junio>     replacing it.\n> \n> Junio>     $ git pull --append \\\n> Junio>       git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current \\\n> Junio>       for-linus\n> \n> The relatively current doc of \"--append\" looks like this:\n> \n>        -a, --append\n>            Append ref names and object names of fetched refs to the existing\n>            contents of will be overwritten.\n> \n> I read this three times, and still don't know what it means (and it doesn't\n> even scan well as English), so I would have never known to use this strategy.\n> Can you explain this more in detail, or point at something in the mailing list\n> that does?\n\nGreetings,\n\nIf I may: So the existing description is incomprehensible. I sort of believed I\nunderstood it, but apparently I didn't understand enough of it.\n\nCould we ditch the current git-pull --append description? Can then please\nsomebody rewrite this paragraph? This somebody must have completely understood\n\n(1) what this feature is good for (practically speaking)\n\n(2) how it works (technically speaking, to provide reference information)\n\nThat would be much more useful, and the use would last longer :-)\n\nI don't dare ask Junio directly.\n\nHowever, it appears to me that git-pull already does most of what Linus needs,\ncould take some final cosmetic touch-ups WRT logs. So could somebody please\nrewrite this?\n\nAnd if I may be so bold: Please rewrite before somebody starts polishing the\nbisect facilities WRT octopus merges. These seem unrelated, as in: you don't\nneed to make bisect more convenient to be able to fix the description of\ngit-pull --append...\n\nThanks for not slashing me to pieces. 8-)\n\nBest regards\nMA\n"},{"id":"116947","messageId":"4A43B187.7080509@drmicha.warpmail.net","threadId":"19922","inReplyTo":"863a9oz8lh.fsf@blue.stonehenge.com","subject":"Re: Could this be done simpler?","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-06-25T17:19:03Z","receivedAt":"2009-06-25T17:19:03Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Randal L. Schwartz venit, vidit, dixit 25.06.2009 16:33:\n>>>>>> \"Junio\" == Junio C Hamano <gitster@pobox.com> writes:\n> \n> Junio> (5) Continue pretending to be Linus, complete the octopus.  The key is to\n> Junio>     let the \"fetch\" phase of this to append to the FETCH_HEAD, not\n> Junio>     replacing it.\n> \n> Junio>     $ git pull --append \\\n> Junio>       git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current \\\n> Junio>       for-linus\n> \n> The relatively current doc of \"--append\" looks like this:\n> \n>        -a, --append\n>            Append ref names and object names of fetched refs to the existing\n>            contents of will be overwritten.\n> \n> I read this three times, and still don't know what it means (and it doesn't\n> even scan well as English), so I would have never known to use this strategy.\n> Can you explain this more in detail, or point at something in the mailing list\n> that does?\n\nUhm,\nmy version of git-fetch.1 has\n\n       -a, --append\n           Append ref names and object names of fetched refs to the\nexisting contents of .git/FETCH_HEAD. Without this option\n           old data in .git/FETCH_HEAD will be overwritten.\n\nThat at least scans better in English. It does not make it very clear\nwhat the consequences are, though.\n\nMichael\n"},{"id":"116948","messageId":"7v3a9ogr8f.fsf@alter.siamese.dyndns.org","threadId":"19922","inReplyTo":"4A43A6B3.5020407@gmx.de","subject":"Re: Could this be done simpler?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-25T17:25:52Z","receivedAt":"2009-06-25T17:25:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Andree <matthias.andree@gmx.de> writes:\n\n> Could we ditch the current git-pull --append description? Can then please\n> somebody rewrite this paragraph? This somebody must have completely understood\n\n> (1) what this feature is good for (practically speaking)\n>\n> (2) how it works (technically speaking, to provide reference information)\n>\n> That would be much more useful, and the use would last longer :-)\n>\n> I don't dare ask Junio directly.\n\nBut if you run blame and mailing list archive search, you would discover\nthat \"fetch --append\" was my invention.  After all, the entire Octopus\nidea originates from me at 211232b (Octopus merge of the following five\npatches., 2005-05-05).  It is interesting to realize that it was actually\na Pentapus made on the day of 5/5/5 ;-)\n\nI thought I was going to take blame on the incomprehensive documentation\nand pass it on to me being non-native speaker/writer of English, but the\nsituation is bit funny.  Documentation/fetch-options.txt says this:\n\n    -a::\n    --append::\n            Append ref names and object names of fetched refs to the\n            existing contents of `.git/FETCH_HEAD`.  Without this\n            option old data in `.git/FETCH_HEAD` will be overwritten.\n\nPerhaps there has a cut&paste error?  I haven't looked.\n\nNow answers to (1) and (2).\n\n (1) The feature was designed exactly for the use case Linus described.\n\n (2) \"git fetch\" leaves list of <commit object, repo, branch, flag> for\n     each ref fetched from repository in .git/FETCH_HEAD, where flag tells\n     if it is meant for merging.  \"git pull\" runs \"git fetch\", reads from\n     this file to learn which ones to pass to \"git merge\".  The\n     information also is given to \"git fmt-merge-msg\" to come up with the\n     message.\n\n     Usually \"git fetch\" first empties the existing contents of the file\n     and stores the list of refs it fetched.  With --append, it doesn't\n     empty the file; refs fetched by the previous invocation of \"git\n     fetch\" will be kept and the refs it fetched are appenede.\n\n     So:\n\n\t$ git fetch one a\n        $ git fetch --append two b\n        $ git pull --apend three c\n\n     will end up having all the three refs from different repositories in\n     .git/FETCH_HEAD.  I.e.\n\n\tbranch a, from repo one, to be merged\n\tbranch b, from repo two, to be merged\n\tbranch c, from repo three, to be merged\n\n     when \"git fetch\" run by the the last \"git pull\" returns.  \"git pull\"\n     reads the file and learn what to give to \"git fmt-merge-msg\" (to come\n     up with the message for the merge commit) and \"git merge\" (to create\n     the merge commit).\n"},{"id":"116953","messageId":"7vfxdocgg1.fsf@alter.siamese.dyndns.org","threadId":"19922","inReplyTo":"4A43A6B3.5020407@gmx.de","subject":"Re: Could this be done simpler?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-25T18:32:30Z","receivedAt":"2009-06-25T18:32:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Andree <matthias.andree@gmx.de> writes:\n\n> And if I may be so bold: Please rewrite before somebody starts polishing the\n> bisect facilities WRT octopus merges. These seem unrelated, as in: you don't\n> need to make bisect more convenient to be able to fix the description of\n> git-pull --append...\n\nLet's have a refresher course of how bisection works with a history with\nmerges.\n\nAssume that you have this history (time flows from left to right, recent\ncommits are known to be bad, old commits are known to be good).\n\n                       o---o---o---o---A\n                      /                 \\\n  ---o---o---o---o---F---o---o---o---B---M\n\nIn real life, you would start from a history with more commits on top of M\nand only know that the tip of that sequence is bad, but for brevity, let's\nassume we bisected and already know M is bad.\n\nIf B is good, the breakage was either introduced at M, or was on the side\nbranch leading to A, but not older than F where A and B forked from.\n\n    Side note.  As in all other discussion in this message, remember\n    that bisect is for finding a _single_ breakage that was left\n    unfixed til the tip of the history being bisected.  \"B is good\"\n    means \"the _single_ breakage is not in the commit that would\n    affect B, i.e. in B's ancestors\",\n\nIf B is bad, on the other hand, the branch leading to A since the fork\npoint F is exonerated and we do not have to look at the side branch that\nleads to A.\n\nWhich means that by seeing one the tip of a merged branch is good, you\ncan see that everything before the merge base is good and you need to only\nlook at _the other_ branch.\n\nWhat happens if M is an Octopus?\n\n                       o---o---o---o---A\n                      /                 \\\n  ---o---o---o---o---F---o---o---o---B---M\n                  \\       \\             /|\n                   \\       o---o---o---C |\n                    \\                    |\n                     o---o---o---o---o---D\n\nIf B is good, you still need to look at histories leading to A, C, and D\nindividually.  Of course if B is bad, then you do not have to look at \nthe histrories leading to A, C and D from their respective fork points,\nbut you still do have to look at the shared past.\n\nBut we could optimize further.  After knowing M, an Octopus merge, is bad,\nwhen we are tempted to test one of the tips of the branches that was\nmerged (say B), we can instead give a tree that is a result of merging\nonly A and B (i.e. excluding C and D) for testing.  If it is good, then\nthe histories leading to both A and B are good, and we only need to check\nside branches leading C and D since they forked from the shared common\nhistory.  If combination of A and B is bad, on the other hand, then we do\nnot have to check branch histories leading to C nor D.\n\nDoing so essentially shifts the balance between what happens if a single\ntest turns out to be good or bad.  If we test the tip of the branch, and\nif it is bad, we will eliminate other forks (but still need to test the\nshared history).  If it is good, we only eliminate that particular branch\nand shared history, but all the other forks remain suspect.  So it is a\ntradeoff between:\n\n - the size of all the other side branches since they forked == number of\n   commits we do not have to test if this round says \"bad\";\n\n - the size of this side branch and the shared history == number of\n   commits we do not have to test if this round says \"good\";\n\nThe current bisect algorithm makes this tradeoff, by computing the above\ntwo numbers and finding the point that makes them closest to each other.\nIt however does not let you test two commits at the same time (i.e.\ntesting the merge of A and B in the above example) which could make the\ntradeoff even more efficient.\n\nI see there is another window for optimization we could make from the\nabove observation.  Making the number of commits eliminated when the test\nis \"good\" and \"bad\" as close to equal as possible is the best strategy\nwhen the tested commit has a 50-50 chance of being \"good\" or \"bad\".  If we\nsomehow know that the tested commit is likely to be \"bad\", we would want\nto maximize the number of commits eliminated when the commit is indeed\n\"bad\" (and vice versa).\n\nI do not see an easy way to exploit this window offhand, though...\n"},{"id":"116970","messageId":"op.uv3ogqin1e62zd@merlin.emma.line.org","threadId":"19922","inReplyTo":"7v3a9ogr8f.fsf@alter.siamese.dyndns.org","subject":"Re: Could this be done simpler?","fromName":"Matthias Andree","fromEmail":"matthias.andree@gmx.de","sentAt":"2009-06-25T21:54:16Z","receivedAt":"2009-06-25T21:54:16Z","isPatch":false,"sender":{"key":"matthias.andree@gmx.de","avatar":null},"body":"Am 25.06.2009, 19:25 Uhr, schrieb Junio C Hamano <gitster@pobox.com>:\n\n> Matthias Andree <matthias.andree@gmx.de> writes:\n>\n>> Could we ditch the current git-pull --append description? Can then  \n>> please somebody rewrite this paragraph? This somebody must have  \n>> completely understood\n>\n>> (1) what this feature is good for (practically speaking)\n>>\n>> (2) how it works (technically speaking, to provide reference  \n>> information)\n>>\n>> That would be much more useful, and the use would last longer :-)\n>>\n>> I don't dare ask Junio directly.\n>\n> But if you run blame and mailing list archive search, you would discover\n> that \"fetch --append\" was my invention.  After all, the entire Octopus\n> idea originates from me at 211232b (Octopus merge of the following five\n> patches., 2005-05-05).  It is interesting to realize that it was actually\n> a Pentapus made on the day of 5/5/5 ;-)\n\nFair enough, but I hadn't looked at who wrote it because more people than  \njust the original author can be able to write it. In fact, I've drifted  \ninto doing that. Suggestions at the very end if you're not interested in  \nthe rationale, but if you are only interested the solution. :-)\n\nI've seen your later message on the octopus merges, and therefore suggest  \nthat we get this --append stuff documented first.\n\n> I thought I was going to take blame on the incomprehensive documentation\n> and pass it on to me being non-native speaker/writer of English, but the\n> situation is bit funny.  Documentation/fetch-options.txt says this:\n\nNeither am I a native writer, why bother… it's more important to write  \nthings clearly than to polish things, and writing something correctly from  \nthe beginning is a very hard problem. Writing something that works, and  \nlater polish, are two simpler problems.\nLanguage isn't the concern here, but understanding the feature is.\n\n>     -a::\n>     --append::\n>             Append ref names and object names of fetched refs to the\n>             existing contents of `.git/FETCH_HEAD`.  Without this\n>             option old data in `.git/FETCH_HEAD` will be overwritten.\n>\n> Perhaps there has a cut&paste error?  I haven't looked.\n\nNevermind, that's irrelevant. The key problem is that Linus could not tell  \n from this description that it was the feature he was looking for. So let's  \nfix that and make documentation clearer. Particularly: let's fix the  \ngit-fetch manpage, let's untangle it from git-pull, and let git-pull  \nreference the git-fetch description rather than copy it.\n\nThis quoted section \"Append ref... overwritten.\" explains how the beast  \nworks technically. So what? What is it good for?  What can I do with it?   \nYou made FETCH_HEAD the focus point of the description, but that's not the  \npoint. (It may be the point of the implementation, but I don't care).\n\nIn order for a reader to understand this feature from the docs, he must  \nknow what FETCH_HEAD is good for in the whole git context (as a  \nrequisite), but that is just a diversion, not the key point.\n\nThe point is that you can mark several branches for merge, or in other  \nwords, accumulate other tips/heads that you want to merge, before doing  \nthe merge. It is useful for merges of more than one branch at a time,  \n\"octopus merges\" or similar.\n\n\nPreface: the next comments don't mean to criticize what you are  \npresenting, but just to select which should and which shouldn't go in the  \nreference manual, and if yes, where. I think we've got the whole  \ndescription organized backwards, let's fix that, too.\n\n>  (2) \"git fetch\" leaves list of <commit object, repo, branch, flag> for\n>      each ref fetched from repository in .git/FETCH_HEAD, where flag  \n> tells\n>      if it is meant for merging.  \"git pull\" runs \"git fetch\", reads from\n>      this file to learn which ones to pass to \"git merge\".  The\n>      information also is given to \"git fmt-merge-msg\" to come up with the\n>      message.\n\nThis is a technical detail - this belongs into a separate FETCH_HEAD  \ndocument in section 5 (file formats).\n\n>      Usually \"git fetch\" first empties the existing contents of the file\n>      and stores the list of refs it fetched.  With --append, it doesn't\n>      empty the file; refs fetched by the previous invocation of \"git\n>      fetch\" will be kept and the refs it fetched are appenede.\n\nOK. Also for later, so I know how it differs from regular behaviour.\n\nSo, this is technically more comprehensive, but that leaves the old  \nquestion unanswered - what is FETCH_HEAD good for?\n\nLet's change roles (or perspective) for a moment, for the sake of clarity  \nand usability: I am just a Git user. I don't want to hack Git. I couldn't  \ncare less about implementation details such as FETCH_HEAD, I only need to  \nknow how I can tell Git to merge branches foo, bar, baz into master in one  \nsingle merge.\n\n>      So:\n>\n> \t$ git fetch one a\n>       $ git fetch --append two b\n>       $ git pull --apend three c\n>\n>      will end up having all the three refs from different repositories in\n>      .git/FETCH_HEAD.  I.e.\n>\n> \tbranch a, from repo one, to be merged\n> \tbranch b, from repo two, to be merged\n> \tbranch c, from repo three, to be merged\n>\n>      when \"git fetch\" run by the the last \"git pull\" returns.  \"git pull\"\n>      reads the file and learn what to give to \"git fmt-merge-msg\" (to  \n> come\n>      up with the message for the merge commit) and \"git merge\" (to create\n>      the merge commit).\n\nLet's leave git pull out of this picture. If you mention it, you must  \nexplain the interaction between pull and fetch, but you don't want this  \nhere. You only want to explain the interaction between fetching more than  \none branch and merging all of them.\n\n\"git pull\" (at bird eye's view) is just a short-cut for \"git fetch  \nsomething\" and \"git merge with somehow configured branch\" (somehow =  \nimplicitly through setting up tracking branches, or clone), or explicitly  \nthrough git branch, or git remote -- let's leave this aside.\n\nSo, here's my first stab at it (just content, not ASCIIDOC markup, as I'm  \nnot fluent in ASCIIDOC and you can easily do that when merging later) -  \nfeel free to correct edit, rewrite, amend to it...\n\nI'm not sure\n\n\nFETCH_HEAD(5)\n-------------------------------------------------\nThis file in the git directory records which heads have been downloaded,  \n from where, and for what purpose. Each line in this file is one  \nTAB-delimited record with three fields. From left to right, these fields  \ncontain:\n\n1 - the commit of the remote head\n2 - \"not-for-merge\" if the branch is not meant to be merged, otherwise,  \nthis field remains empty\n3 - branch 'xxx' of UUU, where xxx and UUU are the remote repository's  \nrefname and base URL, respectively.\n\nThis file is written by git-fetch and used by git-merge.\n-------------------------------------------------\n\n\n\ngit-fetch(1)\n-------------------------------------------------\n...\n      -a::\n      --append::\n\tThis option allows you to fetch and accumulate multiple remote refs for  \nfuture merging.  Normally, git-fetch records the latest fetch for a later  \nmerge, by writing them to .git/FETCH_HEAD (there can be multiple recorded  \nheads in FETCH_HEAD although the name suggests there were just one).  The  \n--append option lets git-fetch keep, rather than delete, prior contents of  \nthe file.  This can be ueful when consolidating multiple topic branches in  \none single merge (a so-called octopus merge, see git-merge(1)). Example:\n\n> \t$ git fetch one a\n>       $ git fetch --append two b\n>       $ git pull --append three c\n\n(git pull first runs git fetch --append three c, and then git merge with  \nall remotes that have been recorded for merging in .git/FETCH_HEAD).\n\n...\nYou can use git-pull as short-cut for the all too common  \n\"git-fetch\"-\"git-merge\" sequence.\n-------------------------------------------------\n\n\nNOTE: git-fetch accepts command lines without refspec. These mark fetched  \nheads as \"not-for-merge\". IOW, a refspec is needed that heads are marked  \nas for-merge. I haven't found this documented in git-fetch.\n\n-- \nMatthias Andree\n"},{"id":"116971","messageId":"200906260002.40531.chriscool@tuxfamily.org","threadId":"19922","inReplyTo":"7veit9m8cs.fsf@alter.siamese.dyndns.org","subject":"Re: Could this be done simpler?","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-06-25T22:02:40Z","receivedAt":"2009-06-25T22:02:40Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thursday 25 June 2009, Junio C Hamano wrote:\n> Side note.\n>\n> People sometimes say, and I am certain I agreed to them on more than one\n> occasions, that Octopus hurt bisectability and does not have much value\n> in real life.  I've always thought this bisectability issue was a\n> downside of Octopus merges, but now I think about it, perhaps \"git\n> bisect\" can be taught to dynamically decompose an Octopus merges into a\n> sequence of two-head virtual merges while bisecting.  We strongly\n> discourage and do not allow conflicting Octopus merges, so when you need\n> to bisect a history with an Octopus that looks like this:\n>\n>     ---o---A\n>             \\\n>   ---o---B---M---o\n>             /\n>     ---o---C\n>\n> it should be able to mechanically decompose it, without conflicts, into\n>\n>\n>     ---o---A\n>             \\\n>   ---o---B---M1--M2--o\n>                 /\n>         ---o---C\n>\n> where the tree of M and the tree of M2 are identical.\n\nIf someone creates a \"git decompose-octopus <commit>\" command then you only \nneed to do \"git replace M M2\" after that and you can bisect as usual. (Of \ncourse after that you can remove the replacement with \"git replace -d M\".)\n\nBest regards,\nChristian.\n"},{"id":"116972","messageId":"200906260023.03169.chriscool@tuxfamily.org","threadId":"19922","inReplyTo":"200906260002.40531.chriscool@tuxfamily.org","subject":"Re: Could this be done simpler?","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-06-25T22:23:02Z","receivedAt":"2009-06-25T22:23:02Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Friday 26 June 2009, Christian Couder wrote:\n> On Thursday 25 June 2009, Junio C Hamano wrote:\n> > Side note.\n> >\n> > People sometimes say, and I am certain I agreed to them on more than\n> > one occasions, that Octopus hurt bisectability and does not have much\n> > value in real life.  I've always thought this bisectability issue was a\n> > downside of Octopus merges, but now I think about it, perhaps \"git\n> > bisect\" can be taught to dynamically decompose an Octopus merges into a\n> > sequence of two-head virtual merges while bisecting.  We strongly\n> > discourage and do not allow conflicting Octopus merges, so when you\n> > need to bisect a history with an Octopus that looks like this:\n> >\n> >     ---o---A\n> >             \\\n> >   ---o---B---M---o\n> >             /\n> >     ---o---C\n> >\n> > it should be able to mechanically decompose it, without conflicts, into\n> >\n> >\n> >     ---o---A\n> >             \\\n> >   ---o---B---M1--M2--o\n> >                 /\n> >         ---o---C\n> >\n> > where the tree of M and the tree of M2 are identical.\n>\n> If someone creates a \"git decompose-octopus <commit>\" command then you\n> only need to do \"git replace M M2\" after that and you can bisect as\n> usual. (Of course after that you can remove the replacement with \"git\n> replace -d M\".)\n\n(Or if we make the \"refs/replace/bisect/\" directory special so that it is \nonly used when bisecting, and if the replace ref is created in this \ndirectory, then no need to remove the replacement ref. On the contrary it's \nbetter to leave it there so that people who fetch it benefit from it too.)\n\nBest regards,\nChristian.\n"},{"id":"116974","messageId":"7vprcsymjd.fsf@alter.siamese.dyndns.org","threadId":"19922","inReplyTo":"200906260023.03169.chriscool@tuxfamily.org","subject":"Re: Could this be done simpler?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-25T22:29:58Z","receivedAt":"2009-06-25T22:29:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <chriscool@tuxfamily.org> writes:\n\n>> If someone creates a \"git decompose-octopus <commit>\" command then ...\n\nI am afraid that misses the entire point of my discussion.\n\nSuch a decomposed octopus would _only_ be necessary during bisection, only\nwhen the user chooses to test two tips at once (instead of testing one by\none), _and_ only its tree is needed for that purpose.  In other words, we\nshould be able to do this _without_ creating an extra commit, let alone\nreplace mechanism.\n"},{"id":"116975","messageId":"alpine.LFD.2.01.0906251544030.3605@localhost.localdomain","threadId":"19922","inReplyTo":"7vprcsymjd.fsf@alter.siamese.dyndns.org","subject":"Re: Could this be done simpler?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2009-06-25T22:50:19Z","receivedAt":"2009-06-25T22:50:19Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 25 Jun 2009, Junio C Hamano wrote:\n> \n> Such a decomposed octopus would _only_ be necessary during bisection, only\n> when the user chooses to test two tips at once (instead of testing one by\n> one), _and_ only its tree is needed for that purpose.  In other words, we\n> should be able to do this _without_ creating an extra commit, let alone\n> replace mechanism.\n\nKeep in mind, though, that realistically, I don't think we've ever seen \nany bisection attempts that end at an octopus.\n\nSure, I suspect that being really clever about decomposing an octopus \nmerge might allow us to bisect things _faster_ to one of the branches \ninvolved in the merge, but the amount of smarts to do that just for that \nreason seems pretty outlandish.\n\nAnd if we ever do end up with an actual bug being bisected to the octopus \nmerge itself, at that point I don't think it's unreasonable to take the \nsame approach we do with any normal merge: just try to figure out what the \nconflict is all about (clearly it's not a data conflict, since the \noctopus wouldn't have succeeded in that case, but subtle merge errors can \nbe due to two branches each introducing their own assumptions without \nactually ever clashing on a source file level).\n\nWith regular merges, if you really don't see what the conceptual conflict \nis, you could try to do a temporary rebase to try to figure it out, and I \nsuspect that that is what you'd want to do with an octopus merge too - \nrather than try to decompose the octopus merge into multiple simpler \nmerges, you'd like to try to linearize history and then re-do the \nbisection attempt on that totally modified/simplified history.\n\n\t\t\tLinus\n"},{"id":"116977","messageId":"200906260055.23929.chriscool@tuxfamily.org","threadId":"19922","inReplyTo":"7vprcsymjd.fsf@alter.siamese.dyndns.org","subject":"Re: Could this be done simpler?","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-06-25T22:55:23Z","receivedAt":"2009-06-25T22:55:23Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Friday 26 June 2009, Junio C Hamano wrote:\n> Christian Couder <chriscool@tuxfamily.org> writes:\n> >> If someone creates a \"git decompose-octopus <commit>\" command then ...\n>\n> I am afraid that misses the entire point of my discussion.\n>\n> Such a decomposed octopus would _only_ be necessary during bisection,\n> only when the user chooses to test two tips at once (instead of testing\n> one by one), _and_ only its tree is needed for that purpose.  In other\n> words, we should be able to do this _without_ creating an extra commit,\n> let alone replace mechanism.\n\nBut suppose the result from the bisection tells that M1 is the first bad \ncommit, then the user will need to look at M1, and perhaps check it out or \nuse it in other ways after the bisection is finished. So why shouldn't it \nbe a real commit?\n\nIt's not like a few more commits are a big problem as they will be reclaimed \nby garbage collection anyway if the replace ref is deleted.\n\nBest regards,\nChristian.\n"},{"id":"116981","messageId":"7vljnfykcq.fsf@alter.siamese.dyndns.org","threadId":"19922","inReplyTo":"alpine.LFD.2.01.0906251544030.3605@localhost.localdomain","subject":"Re: Could this be done simpler?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-25T23:17:09Z","receivedAt":"2009-06-25T23:17:09Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> Sure, I suspect that being really clever about decomposing an octopus \n> merge might allow us to bisect things _faster_ to one of the branches \n> involved in the merge, but the amount of smarts to do that just for that \n> reason seems pretty outlandish.\n>\n> And if we ever do end up with an actual bug being bisected to the octopus \n> merge itself, at that point I don't think it's unreasonable to take the \n> same approach we do with any normal merge: just try to figure out what the \n> conflict is all about (clearly it's not a data conflict, since the \n> octopus wouldn't have succeeded in that case, but subtle merge errors can \n> be due to two branches each introducing their own assumptions without \n> actually ever clashing on a source file level).\n>\n> With regular merges, if you really don't see what the conceptual conflict \n> is, you could try to do a temporary rebase to try to figure it out, and I \n> suspect that that is what you'd want to do with an octopus merge too - \n> rather than try to decompose the octopus merge into multiple simpler \n> merges, you'd like to try to linearize history and then re-do the \n> bisection attempt on that totally modified/simplified history.\n\nAll true.\n\nThanks for thoughts.\n"},{"id":"117064","messageId":"7vtz22o72e.fsf@alter.siamese.dyndns.org","threadId":"19922","inReplyTo":"op.uv3ogqin1e62zd@merlin.emma.line.org","subject":"Re: Could this be done simpler?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-27T00:26:33Z","receivedAt":"2009-06-27T00:26:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Matthias Andree\" <matthias.andree@gmx.de> writes:\n\n> Neither am I a native writer, why bother… it's more important to write\n> things clearly than to polish things,...\n\nHey, calm down.\n\nThe current documentation was written back when everybody knew what git\nfetch internally did (e.g. left state in .git/FETCH_HEAD) and describing\nthings from the perspective of what is done internally was \"accepted\" back\nwhen the alternative was not describing anything in any form ;-)\n\nI took your two questions literally as they were.  That is, \n\n * You, like other people, realize that times have changed since then, and\n   noticed that even with the correct rendition (it appears the problem\n   Merlyn saw was primarily caused by Asciidoc toolchain), the bottom-up\n   description based on what is done internally is not sufficient.\n\n * You are volunteering to make things better, but you first need input to\n   make sure the result is not just readable but technically correct.\n\n * And I was among the few people who were around when .git/FETCH_HEAD and\n   \"git fetch --append\" were invented to give precise answers to these\n   questions.\n\nNo way I meant that these two answers should replace the current\ndocumentation.\n\n> Let's change roles (or perspective) for a moment, for the sake of\n> clarity  and usability: I am just a Git user. I don't want to hack\n> Git. I couldn't  care less about implementation details such as\n> FETCH_HEAD, I only need to  know how I can tell Git to merge branches\n> foo, bar, baz into master in one  single merge.\n\nYes, that is the good starting point.\n\n> \"git pull\" (at bird eye's view) is just a short-cut for \"git fetch\n> something\" and \"git merge with somehow configured branch\" (somehow =\n> implicitly through setting up tracking branches, or clone)\n\nActually the latter is \"with information somehow left by git-fetch\".\n\n> FETCH_HEAD(5)\n> -------------------------------------------------\n> This file in the git directory records which heads have been\n> downloaded,  from where, and for what purpose. Each line in this file\n> is one  TAB-delimited record with three fields. From left to right,\n> these fields  contain:\n>\n> 1 - the commit of the remote head\n> 2 - \"not-for-merge\" if the branch is not meant to be merged,\n> otherwise,  this field remains empty\n> 3 - branch 'xxx' of UUU, where xxx and UUU are the remote repository's\n> refname and base URL, respectively.\n>\n> This file is written by git-fetch and used by git-merge.\n> -------------------------------------------------\n\nIt is true that git-merge does use it, but not under its normal mode of\noperation.  Unless the reader of this paragraph is hacking git, I do not\nthink s/he needs to (nor wants to) know about it.  IIRC, it only triggers\nif you do\n\n\t$ git merge FETCH_HEAD\n\nThe more prominent user is git-pull.  git-fetch leaves the instructions to\ngit-pull so that the latter knows what to use when it drives git-merge in\nthis file.\n\n> git-fetch(1)\n> -------------------------------------------------\n> ...\n>      -a::\n>      --append::\n> \tThis option allows you to fetch and accumulate multiple remote\n> refs for  future merging.  Normally, git-fetch records the latest\n> fetch for a later  merge, by writing them to .git/FETCH_HEAD (there\n> can be multiple recorded  heads in FETCH_HEAD although the name\n> suggests there were just one).\n\nI personally find the parenthesized comment at the end just distracting\nand confusing.  You are explicitly saying \"by writing THEM\" so it is clear\nthat the file can and does record more than one when the user instructs\nthe command to.\n\n> ....  The  --append option lets git-fetch\n> keep, rather than delete, prior contents of  the file.  This can be\n> ueful when consolidating multiple topic branches in  one single merge\n> (a so-called octopus merge, see git-merge(1)). Example:\n\nThe description lacks one important point.  It can be useful only when\nconsolidating multiple topic branches _that come from more than one remote\nrepositories_\n\nOther than that, the above paragraph is perfect.\n\n> NOTE: git-fetch accepts command lines without refspec. These mark\n> fetched  heads as \"not-for-merge\". IOW, a refspec is needed that heads\n> are marked  as for-merge. I haven't found this documented in\n> git-fetch.\n\nSorry, I have no idea what you are talking about in these four lines.\n\nPerhaps \"DEFAULT BEHAVIOUR\" section in Documentation/git-pull.txt, the\nparagraph that begins with \"The rule to determine which remote branch to\nmerge ...\" may be what you are looking for?\n"}]}