{"thread":{"id":"36599","subject":"Beginner question on \"Pull is mostly evil\"","startedAt":"2014-05-07T15:40:28Z","lastAt":"2014-05-10T04:01:46Z","messageCount":11,"participants":["Jim Garrison","David Kastrup","Jeff King","Junio C Hamano","Stephen & Linda Smith","Stephen P. Smith","Stephen Smith"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"240915","messageId":"0C723FEB5B4E5642B25B451BA57E2730751C2642@S1P5DAG3C.EXCHPROD.USA.NET","threadId":"36599","inReplyTo":null,"subject":"Beginner question on \"Pull is mostly evil\"","fromName":"Jim Garrison","fromEmail":"jim.garrison@nwea.org","sentAt":"2014-05-07T15:40:28Z","receivedAt":"2014-05-07T15:40:28Z","isPatch":false,"sender":{"key":"jim.garrison@nwea.org","avatar":null},"body":"During my initial self-education I came across the maxim \"don't pull, fetch+merge instead\" and have been doing that.  I think I followed most of the \"pull is (mostly) evil\" discussion but one facet still puzzles me: the idea that pull will do a merge \"in the wrong direction\" sometimes.\n\nDo I understand correctly that this occurs only in the presence of multiple remotes?  \nCan someone provide a simple example of a situation where pull would do the \"wrong\" thing?\n\nThanks\n"},{"id":"240916","messageId":"87iophr26m.fsf@fencepost.gnu.org","threadId":"36599","inReplyTo":"0C723FEB5B4E5642B25B451BA57E2730751C2642@S1P5DAG3C.EXCHPROD.USA.NET","subject":"Re: Beginner question on \"Pull is mostly evil\"","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2014-05-07T16:20:01Z","receivedAt":"2014-05-07T16:20:01Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Jim Garrison <jim.garrison@nwea.org> writes:\n\n> During my initial self-education I came across the maxim \"don't pull,\n> fetch+merge instead\" and have been doing that.  I think I followed\n> most of the \"pull is (mostly) evil\" discussion but one facet still\n> puzzles me: the idea that pull will do a merge \"in the wrong\n> direction\" sometimes.\n>\n> Do I understand correctly that this occurs only in the presence of\n> multiple remotes?\n> Can someone provide a simple example of a situation where pull would\n> do the \"wrong\" thing?\n\nThat's basically unavoidable.  Two opposing directions are actually part\nof the same workflow usually handled by \"git pull\":\n\n\"Codeveloper X sends a pull request to Y who maintains the mainline.\nY executes git pull to merge X' sidebranch into the mainline.\"\n\n\"Codeveloper X executes git pull in order to merge the mainline from Y\nback into his private sidebranch.\"\n\n-- \nDavid Kastrup\n"},{"id":"240918","messageId":"20140507170405.GA6224@sigill.intra.peff.net","threadId":"36599","inReplyTo":"0C723FEB5B4E5642B25B451BA57E2730751C2642@S1P5DAG3C.EXCHPROD.USA.NET","subject":"Re: Beginner question on \"Pull is mostly evil\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-05-07T17:04:05Z","receivedAt":"2014-05-07T17:04:05Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 07, 2014 at 03:40:28PM +0000, Jim Garrison wrote:\n\n> During my initial self-education I came across the maxim \"don't pull,\n> fetch+merge instead\" and have been doing that.  I think I followed\n> most of the \"pull is (mostly) evil\" discussion but one facet still\n> puzzles me: the idea that pull will do a merge \"in the wrong\n> direction\" sometimes.\n> \n> Do I understand correctly that this occurs only in the presence of\n> multiple remotes?\n\nNo, it does not have to do with multiple remotes. It is about \"X merged\ninto Y\" versus \"Y merged into X\". The ordering of parents in a merge\ndoesn't matter for the merge result, but git must choose some order, and\nit always uses your current HEAD first, and then the commit you are\nmerging second (and so on, in an octopus merge).\n\nAs a result, you can use \"git log --first-parent\" to follow the line of\ndevelopment that always got merged into. In a strict topic-branch\nworkflow like git.git, this will show you just what happened on master:\na linear sequence of merges of topic branches, with occasional\ndirect-to-master commits like version bumps.\n\nFor an integrator who is pulling from other people, \"git pull bob topic\"\nfrom \"master\" does the right thing: master is the first parent, and\ntopic is the second parent.\n\nFor somebody with a centralized repo who follows the \"push was a\nnon-fastforward, so pull then push\" advice, the merge between their work\nand master will be \"backwards\". The merge commit will have upstream's\nwork (i.e., \"master\") merged into their topic. Following --first-parent\nwill walk down their work instead of the merge commits on master.\n\nDoes that explain it?\n\n-Peff\n"},{"id":"240943","messageId":"xmqq4n119wgk.fsf@gitster.dls.corp.google.com","threadId":"36599","inReplyTo":"0C723FEB5B4E5642B25B451BA57E2730751C2642@S1P5DAG3C.EXCHPROD.USA.NET","subject":"Re: Beginner question on \"Pull is mostly evil\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-07T20:15:39Z","receivedAt":"2014-05-07T20:15:39Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jim Garrison <jim.garrison@nwea.org> writes:\n\n> During my initial self-education I came across the maxim \"don't\n> pull, fetch+merge instead\" and have been doing that.  I think I\n> followed most of the \"pull is (mostly) evil\" discussion but one\n> facet still puzzles me: the idea that pull will do a merge \"in the\n> wrong direction\" sometimes.\n\n[administrivia: wrap your lines to reasonable length like ~70 cols,\nplease]\n\n> Do I understand correctly that this occurs only in the presence of\n> multiple remotes?\n\nNo.  This is most often true for people who use a single repository\nas a place for everybody to meet, in the same way as SVN.\n\nSuppose that that central repository has this history:\n\n    ---o---o---A\n\nwhich ends at commit A (time flows from left to right and each node\nin the graph is a commit, lines between them indicating parent-child\nrelationship).\n\nThen you clone it and work on your own commits, which leads you to\nhave this in *your* repository:\n\n    ---o---o---A---B---C\n\nImagine your coworker did the same and built on top of A in *his*\nrepository this history in the meantime, and then pushed it to the\ncentral repository:\n\n    ---o---o---A---X---Y---Z\n\nNow, if you \"git push\" at this point, beause your history that leads\nto C lack X, Y and Z, it will fail.  You need to somehow make the\ntip of your history a descendant of Z.\n\nOne way that \"mostly evil\" thread discusses is to \"pull\", which is\n\"fetch and then merge\" (note that I am saying \"don't pull, instead\nfetch and merge\" is not an advice to solve \"pull is mostly evil\"\nissue at all).  If you fetch, your repository will have a history\nlike this:\n\n    ---o---o---A---B---C\n                \\\n                 X---Y---Z\n\nAnd then if you did merge after that, while still on *your* branch,\ni.e. C, you will create a merge M and make the history look like\nthis:\n\n    ---o---o---A---B---C---M\n                \\         /\n                 X---Y---Z\n\nM is a descendant of Z, so you can push to update the central\nrepository.  Such a merge M does not lose any commit in both\nhistories, so in that sense it may not be wrong, but when people\nwould want to talk about \"the authoritative canonical history that\nis shared among the project participants\", i.e. \"the trunk\", the way\nthey often use is to do:\n\n    $ git log --first-parent\n\nFor all other people who observed the central repository after your\ncoworker pushed Z but before you pushed M, the commit on the trunk\nused to be \"o-o-A-X-Y-Z\".  But because you made M while you were on\nC, M's first parent is C, so by pushing M to advance the central\nrepository, you made X-Y-Z a side branch, not on the trunk.\n\nYou would rather want to have a history of this shape:\n\n    ---o---o---A---X---Y---Z---M'\n                \\             / \n                 B-----------C\n\nso that in the first-parent chain, it is clear that the project\nfirst did X and then Y and then Z and merged a change that consists\nof two commits B and C that achieves a single goal.  You may have\nworked on fixing the bug #12345 with these two patches, and the\nmerge M' with swapped parents can say in its log message \"Merge\n'fix-bug-12345'\".\n\nNote that I said \"achieves a single goal\" above, because this is\nimportant.  \"swapping the merge order\" only covers a special case\nwhere the project does not care too much about having unrelated\nthings done on a single merge but cares a lot about first-parent\nchain.\n\nThere are multiple schools of thought about the \"trunk\" management.\n\n 1. Some projects want to keep a completely linear history without\n    any merges.  Obviously, swapping the merge order would not help\n    their taste.  You would need to flatten your history on top of\n    the updated upstream to result in a history of this shape\n    instead:\n\n    ---o---o---A---X---Y---Z---B---C\n\n    with \"git pull --rebase\" or something.\n\n 2. Some projects tolerate merges in their history, but do not worry\n    too much about the first-parent order, and allows fast-forward\n    merges.  To them, swapping the merge order does not hurt, but\n    it is unnecessary.\n\n 3. Some projects want each commit on the \"trunk\" to do one single\n    thing.  The output of \"git log --first-parent\" in such a project\n    would show either a merge of a side branch that completes a\n    single theme, or a single commit that completes a single theme\n    by itself.  If your two commits B and C (or they may even be two\n    groups of commits) were solving two independent issues, then the\n    merge M' we made in the earlier example by swapping the merge\n    order is still not up to the project standard.  It merges two\n    unrelated efforts B and C at the same time.\n\nFor projects in the last category (git itself is one of them),\nindividual developers would want to prepare a history more like\nthis:\n\n                 C0--C1--C2     topic-c\n                /\n    ---o---o---A                master\n                \\\n                 B0--B1--B2     topic-b\n\nThat is, keeping separate topics on separate branches, perhaps like\nso:\n\n    $ git clone $URL work && cd work\n    $ git checkout -b topic-b master\n    $ ... work to create B0, B1 and B2 to complete one theme\n    $ git checkout -b topic-c master\n    $ ... same for the theme of topic-c\n\nAnd then\n\n    $ git checkout master\n    $ git pull --ff-only\n\nwould grab X, Y and Z from the upstream and advance your master\nbranch:\n\n                 C0--C1--C2\n                /\n    ---o---o---A---X---Y---Z\n                \\\n                 B0--B1--B2\n\nAnd then you would merge these two branches separately:\n\n    $ git merge topic-b\n    $ git merge topic-c\n\nto result in\n\n                 C0--C1---------C2\n                /                 \\\n    ---o---o---A---X---Y---Z---M---N\n                \\             /   \n                 B0--B1-----B2\n\nand push it back to the central repository.\n\nIt is very much possible that while you are merging topic-b and\ntopic-c, somebody again advanced the history in the central\nrepository to put W on top of Z, and make your \"git push\" fail.\n\nIn such a case, you would rewind to discard M and N, update the tip\nof your 'master' again and redo the two merges:\n\n    $ git reset --hard origin/master\n    $ git pull --ff-only\n    $ git merge topic-b\n    $ git merge topic-c\n\n                 C0--C1--------------C2\n                /                     \\\n    ---o---o---A---X---Y---Z---W---M'--N\n                \\                 /\n                 B0--B1---------B2\n\n\nSo one part of the solution to \"pull is mostly evil\" has to involve\nmaking this \"recreating your work on top of the updated upstream\"\neasier for users.  Otherwise, even if people *know* that rewinding\nand rebuilding is the right thing to do, they will find it too\ncumbersome and end up pushing merges in random order.\n\nFor another way to put this, see\n\n    http://git-blame.blogspot.com/2012/03/fun-with-first-parent.html\n\nHTH.\n"},{"id":"240947","messageId":"0C723FEB5B4E5642B25B451BA57E2730751C2AB2@S1P5DAG3C.EXCHPROD.USA.NET","threadId":"36599","inReplyTo":"xmqq4n119wgk.fsf@gitster.dls.corp.google.com","subject":"RE: Beginner question on \"Pull is mostly evil\"","fromName":"Jim Garrison","fromEmail":"jim.garrison@nwea.org","sentAt":"2014-05-07T20:30:32Z","receivedAt":"2014-05-07T20:30:32Z","isPatch":false,"sender":{"key":"jim.garrison@nwea.org","avatar":null},"body":"> -----Original Message-----\n> From: Junio C Hamano\n> Sent: Wednesday, May 07, 2014 1:16 PM\n> Subject: Re: Beginner question on \"Pull is mostly evil\"\n> \n> No.  This is most often true for people who use a single repository as a\n> place for everybody to meet, in the same way as SVN.\n[snip lots of excellent detail]\n> HTH.\n\nWow.  That helps tremendously, and should be incorporated somewhere in the\nGit documentation.  Thank you for your immensely detailed response.\n\nApologies about not breaking lines... I'll remember that in future.\n\t\n"},{"id":"240957","messageId":"xmqqeh058g93.fsf@gitster.dls.corp.google.com","threadId":"36599","inReplyTo":"0C723FEB5B4E5642B25B451BA57E2730751C2AB2@S1P5DAG3C.EXCHPROD.USA.NET","subject":"Re: Beginner question on \"Pull is mostly evil\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-07T20:51:04Z","receivedAt":"2014-05-07T20:51:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jim Garrison <jim.garrison@nwea.org> writes:\n\n>> -----Original Message-----\n>> From: Junio C Hamano\n>> Sent: Wednesday, May 07, 2014 1:16 PM\n>> Subject: Re: Beginner question on \"Pull is mostly evil\"\n>> \n>> No.  This is most often true for people who use a single repository as a\n>> place for everybody to meet, in the same way as SVN.\n> [snip lots of excellent detail]\n>> HTH.\n>\n> Wow.  That helps tremendously, and should be incorporated somewhere in the\n> Git documentation.  Thank you for your immensely detailed response.\n\nWe used to collect useful list postings in Documentation/howto/;\nperhaps somebody wants to do the minimum copyediting of the message\nand send a patch?\n"},{"id":"240985","messageId":"1484962.u3Uah1apFn@thunderbird","threadId":"36599","inReplyTo":"0C723FEB5B4E5642B25B451BA57E2730751C2AB2@S1P5DAG3C.EXCHPROD.USA.NET","subject":"Re: Beginner question on \"Pull is mostly evil\"","fromName":"Stephen & Linda Smith","fromEmail":"ischis2@cox.net","sentAt":"2014-05-08T00:45:30Z","receivedAt":"2014-05-08T00:45:30Z","isPatch":false,"sender":{"key":"ishchis2@gmail.com","avatar":null},"body":"I'll create a patch.\n\nOn Wednesday, May 07, 2014 01:51:04 PM Junio C Hamano wrote:\n> Jim Garrison <jim.garrison@nwea.org> writes:\n> \n> >> -----Original Message-----\n> >> From: Junio C Hamano\n> >> Sent: Wednesday, May 07, 2014 1:16 PM\n> >> Subject: Re: Beginner question on \"Pull is mostly evil\"\n> >> \n> >> No.  This is most often true for people who use a single repository as a\n> >> place for everybody to meet, in the same way as SVN.\n> > [snip lots of excellent detail]\n> >> HTH.\n> >\n> > Wow.  That helps tremendously, and should be incorporated somewhere in the\n> > Git documentation.  Thank you for your immensely detailed response.\n> \n> We used to collect useful list postings in Documentation/howto/;\n> perhaps somebody wants to do the minimum copyediting of the message\n> and send a patch?\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"241103","messageId":"1399615721-566-1-git-send-email-ischis2@cox.net","threadId":"36599","inReplyTo":"xmqq4n119wgk.fsf@gitster.dls.corp.google.com","subject":"[PATCH] How to keep a project's canonical history correct.","fromName":"Stephen P. Smith","fromEmail":"ischis2@cox.net","sentAt":"2014-05-09T06:08:41Z","receivedAt":"2014-05-09T06:08:41Z","isPatch":true,"sender":{"key":"ishchis2@gmail.com","avatar":null},"body":"During the mail thread about \"Pull is mostly evil\" a user asked how\nthe first parent could become reversed.\n\nThis howto explains how the first parent can get reversed when viewed\nby the project and then explains a method to keep the history correct.\n\nSigned-off-by: Stephen P. Smith <ischis2@cox.net>\n---\n Documentation/Makefile                             |   1 +\n .../howto/keep-canonical-history-correct.txt       | 213 +++++++++++++++++++++\n 2 files changed, 214 insertions(+)\n create mode 100644 Documentation/howto/keep-canonical-history-correct.txt\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex fc6b2cf..cea0e7a 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -59,6 +59,7 @@ SP_ARTICLES += howto/recover-corrupted-blob-object\n SP_ARTICLES += howto/recover-corrupted-object-harder\n SP_ARTICLES += howto/rebuild-from-update-hook\n SP_ARTICLES += howto/rebase-from-internal-branch\n+SP_ARTICLES += howto/keep-canonical-history-correct\n SP_ARTICLES += howto/maintain-git\n API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))\n SP_ARTICLES += $(API_DOCS)\ndiff --git a/Documentation/howto/keep-canonical-history-correct.txt b/Documentation/howto/keep-canonical-history-correct.txt\nnew file mode 100644\nindex 0000000..927154c\n--- /dev/null\n+++ b/Documentation/howto/keep-canonical-history-correct.txt\n@@ -0,0 +1,213 @@\n+From: Junio C Hamano <gitster@pobox.com>\n+Date: Wed, 07 May 2014 13:15:39 -0700\n+Subject: Beginner question on \"Pull is mostly evil\"\n+Abstract: This how-to explains a method for keeping a \n+ project's history correct when using git pull.\n+Content-type: text/asciidoc\n+\n+Keep authoritative canonical history correct with git pull\n+==========================================================\n+\n+Sometimes a new project integrator will end up with project history\n+that appears to be \"backwards\" from what other project developers\n+expect. This howto presents a suggested integration workflow for\n+maintaining a central repository.\n+\n+Suppose that that central repository has this history:\n+\n+------------\n+    ---o---o---A\n+------------\n+\n+which ends at commit `A` (time flows from left to right and each node\n+in the graph is a commit, lines between them indicating parent-child\n+relationship).\n+\n+Then you clone it and work on your own commits, which leads you to\n+have this history in *your* repository:\n+\n+------------\n+    ---o---o---A---B---C\n+------------\n+\n+Imagine your coworker did the same and built on top of `A` in *his*\n+repository in the meantime, and then pushed it to the\n+central repository:\n+\n+------------\n+    ---o---o---A---X---Y---Z\n+------------\n+\n+Now, if you \"git push\" at this point, beause your history that leads\n+to `C` lacks `X`, `Y` and `Z`, it will fail.  You need to somehow make\n+the tip of your history a descendant of `Z`.\n+\n+One suggested way to solve the problem is \"fetch and then merge\", aka\n+\"git pull\". When you fetch, your repository will have a history like\n+this:\n+\n+------------\n+    ---o---o---A---B---C\n+                \\\n+                 X---Y---Z\n+------------\n+\n+Once you run merge after that, while still on *your* branch, i.e. `C`,\n+you will create a merge `M` and make the history look like this:\n+\n+------------\n+    ---o---o---A---B---C---M\n+                \\         /\n+                 X---Y---Z\n+------------\n+\n+`M` is a descendant of `Z`, so you can push to update the central\n+repository.  Such a merge `M` does not lose any commit in both\n+histories, so in that sense it may not be wrong, but when people want\n+to talk about \"the authoritative canonical history that is shared\n+among the project participants\", i.e. \"the trunk\", the way they often\n+use is to do:\n+\n+------------\n+    $ git log --first-parent\n+------------\n+\n+For all other people who observed the central repository after your\n+coworker pushed `Z` but before you pushed `M`, the commit on the trunk\n+used to be `o-o-A-X-Y-Z`.  But because you made `M` while you were on\n+`C`, `M`'s first parent is `C`, so by pushing `M` to advance the\n+central repository, you made `X-Y-Z` a side branch, not on the trunk.\n+\n+You would rather want to have a history of this shape:\n+\n+------------\n+    ---o---o---A---X---Y---Z---M'\n+                \\             /\n+                 B-----------C\n+------------\n+\n+so that in the first-parent chain, it is clear that the project first\n+did `X` and then `Y` and then `Z` and merged a change that consists of\n+two commits `B` and `C` that achieves a single goal.  You may have\n+worked on fixing the bug #12345 with these two patches, and the merge\n+`M'` with swapped parents can say in its log message \"Merge\n+'fix-bug-12345'\". Having a way to tell \"git pull\" to create a merge\n+but record the parents in reverse order may be a way to do so.\n+\n+Note that I said \"achieves a single goal\" above, because this is\n+important.  \"swapping the merge order\" only covers a special case\n+where the project does not care too much about having unrelated\n+things done on a single merge but cares a lot about first-parent\n+chain.\n+\n+There are multiple schools of thought about the \"trunk\" management.\n+\n+ 1. Some projects want to keep a completely linear history without any\n+    merges.  Obviously, swapping the merge order would not match their\n+    taste.  You would need to flatten your history on top of the\n+    updated upstream to result in a history of this shape instead:\n++\n+------------\n+    ---o---o---A---X---Y---Z---B---C\n+------------\n++\n+    with `git pull --rebase` or something.\n+\n+ 2. Some projects tolerate merges in their history, but do not worry\n+    too much about the first-parent order, and allow fast-forward\n+    merges.  To them, swapping the merge order does not hurt, but\n+    it is unnecessary.\n+\n+ 3. Some projects want each commit on the \"trunk\" to do one single\n+    thing.  The output of `git log --first-parent` in such a project\n+    would show either a merge of a side branch that completes a single\n+    theme, or a single commit that completes a single theme by itself.\n+    If your two commits `B` and `C` (or they may even be two groups of\n+    commits) were solving two independent issues, then the merge `M'`\n+    we made in the earlier example by swapping the merge order is\n+    still not up to the project standard.  It merges two unrelated\n+    efforts `B` and `C` at the same time.\n+\n+For projects in the last category (Git itself is one of them),\n+individual developers would want to prepare a history more like\n+this:\n+\n+------------\n+                 C0--C1--C2     topic-c\n+                /\n+    ---o---o---A                master\n+                \\\n+                 B0--B1--B2     topic-b\n+------------\n+\n+That is, keeping separate topics on separate branches, perhaps like\n+so:\n+\n+------------\n+    $ git clone $URL work && cd work\n+    $ git checkout -b topic-b master\n+    $ ... work to create B0, B1 and B2 to complete one theme\n+    $ git checkout -b topic-c master\n+    $ ... same for the theme of topic-c\n+------------\n+\n+And then\n+\n+------------\n+    $ git checkout master\n+    $ git pull --ff-only\n+------------\n+\n+would grab `X`, `Y` and `Z` from the upstream and advance your master\n+branch:\n+\n+------------\n+                 C0--C1--C2     topic-c\n+                /\n+    ---o---o---A---X---Y---Z    master\n+                \\\n+                 B0--B1--B2     topic-b\n+------------\n+\n+And then you would merge these two branches separately:\n+\n+------------\n+    $ git merge topic-b\n+    $ git merge topic-c\n+------------\n+\n+to result in\n+\n+------------\n+                 C0--C1---------C2\n+                /                 \\\n+    ---o---o---A---X---Y---Z---M---N\n+                \\             /\n+                 B0--B1-----B2\n+------------\n+\n+and push it back to the central repository.\n+\n+It is very much possible that while you are merging topic-b and\n+topic-c, somebody again advanced the history in the central repository\n+to put `W` on top of `Z`, and make your \"git push\" fail.\n+\n+In such a case, you would rewind to discard `M` and `N`, update the\n+tip of your 'master' again and redo the two merges:\n+\n+------------\n+    $ git reset --hard origin/master\n+    $ git pull --ff-only\n+    $ git merge topic-b\n+    $ git merge topic-c\n+------------\n+\n+------------\n+                 C0--C1--------------C2\n+                /                     \\\n+    ---o---o---A---X---Y---Z---W---M'--N'\n+                \\                 /\n+                 B0--B1---------B2\n+------------\n+\n+See http://git-blame.blogspot.com/2012/03/fun-with-first-parent.html\n-- \n2.0.0.rc1\n"},{"id":"241145","messageId":"BB377FC6-CE4A-4A7F-BAC7-7141BD9776C5@gmail.com","threadId":"36599","inReplyTo":"1399615721-566-1-git-send-email-ischis2@cox.net","subject":"Re: [PATCH] How to keep a project's canonical history correct.","fromName":"Stephen Smith","fromEmail":"ishchis2@gmail.com","sentAt":"2014-05-09T13:41:57Z","receivedAt":"2014-05-09T13:41:57Z","isPatch":true,"sender":{"key":"ishchis2@gmail.com","avatar":null},"body":"\n\n> On May 8, 2014, at 11:08 PM, \"Stephen P. Smith\" <ischis2@cox.net> wrote:\n> \n> During the mail thread about \"Pull is mostly evil\" a user asked how\n> the first parent could become reversed.\n> \n> This howto explains how the first parent can get reversed when viewed\n> by the project and then explains a method to keep the history correct.\n> \n> Signed-off-by: Stephen P. Smith <ischis2@cox.net>\n> ---\n\nThe reason I resubmitted as a brand new patch was because I was using the message ID from the original topic as requested. \n\nIn my repository I did a \"git merge --squash\" then the format patch.  \n"},{"id":"241226","messageId":"xmqqk39uwtlj.fsf@gitster.dls.corp.google.com","threadId":"36599","inReplyTo":"1399615721-566-1-git-send-email-ischis2@cox.net","subject":"Re: [PATCH] How to keep a project's canonical history correct.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-05-09T21:05:44Z","receivedAt":"2014-05-09T21:05:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Stephen P. Smith\" <ischis2@cox.net> writes:\n\n> During the mail thread about \"Pull is mostly evil\" a user asked how\n> the first parent could become reversed.\n>\n> This howto explains how the first parent can get reversed when viewed\n> by the project and then explains a method to keep the history correct.\n>\n> Signed-off-by: Stephen P. Smith <ischis2@cox.net>\n> ---\n\nI needed a few tweaks on top while queuing.  You will find the\nresult on 'pu' after I push it out.\n\nIn addition to one typofix (\"because\" lacking \"c\"), here are what I\ndid:\n\n - Typeset concrete command e.g. `git pull` in monospace.\n\n - The second and subsequent paragraphs continued with \"+\" need to\n   be flushed to the left; leaving them indented will format them in\n   monospace (see \"with `git pull --rebase` or something\").\n\n - Be more explicit in describing 'trunk' being 'the first-parent\n   chain' in the text.\n\n - Refer to a newer article that discusses this exact topic.\n\n - De-emphasize 'fix-bug-12345' in \"Merge fix-bug-12345\" log message.\n\n - Describe what the final history illustration shows.\n\n\nUnless you have objections to the below (or suggestions for better\nalternatives), there is no need to resend the patch.\n\nThanks.\n\ndiff --git a/Documentation/howto/keep-canonical-history-correct.txt b/Documentation/howto/keep-canonical-history-correct.txt\nindex 5979a79..35d48ef 100644\n--- a/Documentation/howto/keep-canonical-history-correct.txt\n+++ b/Documentation/howto/keep-canonical-history-correct.txt\n@@ -38,12 +38,12 @@ central repository:\n     ---o---o---A---X---Y---Z\n ------------\n \n-Now, if you \"git push\" at this point, beause your history that leads\n+Now, if you `git push` at this point, because your history that leads\n to `C` lacks `X`, `Y` and `Z`, it will fail.  You need to somehow make\n the tip of your history a descendant of `Z`.\n \n One suggested way to solve the problem is \"fetch and then merge\", aka\n-\"git pull\". When you fetch, your repository will have a history like\n+`git pull`. When you fetch, your repository will have a history like\n this:\n \n ------------\n@@ -65,8 +65,9 @@ you will create a merge `M` and make the history look like this:\n repository.  Such a merge `M` does not lose any commit in both\n histories, so in that sense it may not be wrong, but when people want\n to talk about \"the authoritative canonical history that is shared\n-among the project participants\", i.e. \"the trunk\", the way they often\n-use is to do:\n+among the project participants\", i.e. \"the trunk\", they often view\n+it as \"commits you see by following the first-parent chain\", and use\n+this command to view it:\n \n ------------\n     $ git log --first-parent\n@@ -91,11 +92,11 @@ did `X` and then `Y` and then `Z` and merged a change that consists of\n two commits `B` and `C` that achieves a single goal.  You may have\n worked on fixing the bug #12345 with these two patches, and the merge\n `M'` with swapped parents can say in its log message \"Merge\n-'fix-bug-12345'\". Having a way to tell \"git pull\" to create a merge\n+fix-bug-12345\". Having a way to tell `git pull` to create a merge\n but record the parents in reverse order may be a way to do so.\n \n Note that I said \"achieves a single goal\" above, because this is\n-important.  \"swapping the merge order\" only covers a special case\n+important.  \"Swapping the merge order\" only covers a special case\n where the project does not care too much about having unrelated\n things done on a single merge but cares a lot about first-parent\n chain.\n@@ -111,7 +112,7 @@ There are multiple schools of thought about the \"trunk\" management.\n     ---o---o---A---X---Y---Z---B---C\n ------------\n +\n-    with `git pull --rebase` or something.\n+with `git pull --rebase` or something.\n \n  2. Some projects tolerate merges in their history, but do not worry\n     too much about the first-parent order, and allow fast-forward\n@@ -190,7 +191,7 @@ and push it back to the central repository.\n \n It is very much possible that while you are merging topic-b and\n topic-c, somebody again advanced the history in the central repository\n-to put `W` on top of `Z`, and make your \"git push\" fail.\n+to put `W` on top of `Z`, and make your `git push` fail.\n \n In such a case, you would rewind to discard `M` and `N`, update the\n tip of your 'master' again and redo the two merges:\n@@ -202,6 +203,8 @@ tip of your 'master' again and redo the two merges:\n     $ git merge topic-c\n ------------\n \n+The procedure will result in a history that looks like this:\n+\n ------------\n \t\t C0--C1--------------C2\n \t\t/                     \\\n@@ -210,4 +213,4 @@ tip of your 'master' again and redo the two merges:\n \t\t B0--B1---------B2\n ------------\n \n-See http://git-blame.blogspot.com/2012/03/fun-with-first-parent.html\n+See also http://git-blame.blogspot.com/2013/09/fun-with-first-parent-history.html\n"},{"id":"241236","messageId":"4639676.GfT2sDDHtN@thunderbird","threadId":"36599","inReplyTo":"1399615721-566-1-git-send-email-ischis2@cox.net","subject":"Re: [PATCH] How to keep a project's canonical history correct.","fromName":"Stephen & Linda Smith","fromEmail":"ischis2@cox.net","sentAt":"2014-05-10T04:01:46Z","receivedAt":"2014-05-10T04:01:46Z","isPatch":true,"sender":{"key":"ishchis2@gmail.com","avatar":null},"body":"On Friday, May 09, 2014 02:05:44 PM Junio C Hamano wrote:\n> I needed a few tweaks on top while queuing.  You will find the\n> result on 'pu' after I push it out.\n> \n> In addition to one typofix (\"because\" lacking \"c\"), here are what I\n> did:\n> \n>  - Typeset concrete command e.g. `git pull` in monospace.\n> \n>  - The second and subsequent paragraphs continued with \"+\" need to\n>    be flushed to the left; leaving them indented will format them in\n>    monospace (see \"with `git pull --rebase` or something\").\n> \n>  - Be more explicit in describing 'trunk' being 'the first-parent\n>    chain' in the text.\n> \n>  - Refer to a newer article that discusses this exact topic.\n> \n>  - De-emphasize 'fix-bug-12345' in \"Merge fix-bug-12345\" log message.\n> \n>  - Describe what the final history illustration shows.\n> \n> \n> Unless you have objections to the below (or suggestions for better\n> alternatives), there is no need to resend the patch.\n> \n\nI like the changes.\n"}]}