{"thread":{"id":"15339","subject":"[RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase","startedAt":"2008-09-02T20:18:41Z","lastAt":"2008-10-19T20:07:12Z","messageCount":29,"participants":["Thomas Rast","Junio C Hamano","Jakub Narebski","Marcus Griep","Santi Béjar","Dmitry Potapov"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"89533","messageId":"1220386721-10215-1-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":null,"subject":"[RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-02T20:18:41Z","receivedAt":"2008-09-02T20:18:41Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Documents how to recover if the upstream that you pull from has\nrebased the branches you depend your work on.  Hopefully this can also\nserve as a warning to potential rebasers.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nI've always found the \"warning\" on the git-rebase manpage (it's not\neven marked as a warning!) a bit weak.\n\nSo this is an attempt to solve two problems in one go.  It should be\nprecise enough to help users understand and recover, but scary enough\nto prevent them from doing such rebases in the first place.\n\nI flagged it as RFC because I'd appreciate some feedback:\n\n- Are the warnings too repetitive?  I fear that if we sound too\n  protective, users won't listen.\n\n- Is it perhaps too verbose, or in the wrong place?  I did not want to\n  detract from the feature descriptions that the manpage should first\n  and foremost contain.  Chances that a user will \"accidentally\" read\n  the section at this position and length seem fairly low however.\n\nI've also edited it a fair bit, so chances are that mistakes have\nsnuck in.\n\nIf you like the general direction of this, I'll also make a patch that\npoints at this section from other rewriting manpages.\n\n- Thomas\n\n\n Documentation/git-rebase.txt |   79 +++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 75 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 59c1b02..5e1dc30 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -257,11 +257,12 @@ include::merge-strategies.txt[]\n \n NOTES\n -----\n-When you rebase a branch, you are changing its history in a way that\n-will cause problems for anyone who already has a copy of the branch\n-in their repository and tries to pull updates from you.  You should\n+\n+As a rule of thumb, rebasing anything that you have published already\n+is a bad idea.  It causes problems for people who already have a copy\n+of your branch, and are trying to pull updates from you.  You should\n understand the implications of using 'git-rebase' on a repository that\n-you share.\n+you share.  See also HELP, MY UPSTREAM HAS REBASED! below.\n \n When the git-rebase command is run, it will first execute a \"pre-rebase\"\n hook if one exists.  You can use this hook to do sanity checks and\n@@ -396,6 +397,76 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+HELP, MY UPSTREAM HAS REBASED!\n+------------------------------\n+\n+This section briefly explains the problems that arise from rebasing\n+published branches, and shows how to recover.  The process is rather\n+tedious, so we emphasize again: 'Avoid rebasing published branches.'\n+(The same warning goes for other history rewriting too, for example,\n+`git commit --amend` and 'git-filter-branch'.)\n+\n+To illustrate, suppose you are in a situation where someone develops a\n+'subsystem' branch, and you are working on a 'topic' that is dependent\n+on this 'subsystem'.  You might end up with a history like the\n+following:\n+\n+------------\n+    o---o---o---o---o  master\n+\t \\\n+\t  o---o---o---o---o  subsystem\n+\t\t\t   \\\n+\t\t\t    *---*---*  topic\n+------------\n+\n+In a push/pull workflow, the maintainer of 'subsystem' would use `git\n+merge master` to grab updates from upstream, and you can use the\n+analogous `git merge subsystem`.\n+\n+If 'subsystem' is instead **rebased** against master, the following\n+happens:\n+\n+------------\n+    o---o---o---o---o  master\n+\t|\t     \\\n+\t|\t      o'--o'--o'--o'--o'  subsystem\n+\t\\\n+\t o---o---o---o---o---*---*---*\ttopic\n+------------\n+\n+Note that while we have marked your own commits with a '*', there is\n+nothing that distinguishes them from the commits that previously were\n+on 'subsystem'.  You can easily verify this with, for example, `git\n+log subsystem..topic` -- which returned only your own commits in the\n+scenario of the first graph above, but now has all the commits of the\n+old 'subsystem' too!  Furthermore, a potential merge of 'topic' into\n+'subsystem' is liable to cause unnecessary conflicts due to the\n+duplicated changes.\n+\n+To recover from this, you need to find the original branch point\n+manually, and rebase your topic against the new 'subsystem'.  Since in\n+the graph, there are 3 commits that were your own, you can do\n+------------\n+    git rebase --onto subsystem HEAD~3 topic\n+------------\n+and end up with the fixed history\n+------------\n+    o---o---o---o---o  master\n+\t\t     \\\n+\t\t      o'--o'--o'--o'--o'  subsystem\n+\t\t\t\t\t\\\n+\t\t\t\t\t *'--*'--*'  topic\n+------------\n+\n+`git pull --rebase` (see linkgit:git-pull[1]) can be used to automate\n+this process, but only if you use it instead of fetching, so that it\n+can use the old upstream head to determine the previous branch point.\n+\n+The rewriting becomes a ripple effect to developers downstream from\n+you (if any): since you now have rebased 'topic', they will have to\n+manually rebase their own work to reflect this!\n+\n+\n Authors\n ------\n Written by Junio C Hamano <gitster@pobox.com> and\n-- \n1.6.0.1.302.g47141\n"},{"id":"89550","messageId":"7vvdxei5wv.fsf@gitster.siamese.dyndns.org","threadId":"15339","inReplyTo":"1220386721-10215-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-09-02T21:39:28Z","receivedAt":"2008-09-02T21:39:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> I flagged it as RFC because I'd appreciate some feedback:\n>\n> - Are the warnings too repetitive?  I fear that if we sound too\n>   protective, users won't listen.\n>\n> - Is it perhaps too verbose, or in the wrong place?  I did not want to\n>   detract from the feature descriptions that the manpage should first\n>   and foremost contain.  Chances that a user will \"accidentally\" read\n>   the section at this position and length seem fairly low however.\n\nIt feels on a bit too repetitive side, but I think this is going in the\nright direction.  How about dropping the earlier part of the change to\nNotes section (but keep \"See also\" which is a good guide for understanding\nthe said \"implications\")?\n\n> +HELP, MY UPSTREAM HAS REBASED!\n> +------------------------------\n\nI read this section only once, but it looked reasonable as a recovery\nprocedure to me.\n\nThe additions you made are all about why rebasing public history is bad\nfrom mechanisms (overlapping changes made by old upstream history and new\nupstream history, unless they are identical, will cause merge conflicts\nbetween themselves that downstream will have hard time resolving) POV.\nWhile that description is all good, I think there should also be a\ndiscussion from the patchflow/workflow angle.\n\n\"Upstream has rebased\" almost implies that it has its own upstream\n(i.e. \"My upstream\" is not the toplevel upstream, but is a subsystem tree\nor something).\n\nRebasing upstream is bad, but an upstream that backmerges from its own\nupstream too often is equally bad, and the reason of the badness, viewed\nfrom the workflow angle, shares exactly the same component.\n\nIt means that the mid-level upstream in question is not focused enough.\n\nCf.\n\n    http://article.gmane.org/gmane.linux.kernel/681763\n    http://article.gmane.org/gmane.linux.kernel/684030\n    http://article.gmane.org/gmane.linux.kernel/684073\n    http://article.gmane.org/gmane.linux.kernel/684091\n    http://article.gmane.org/gmane.linux.kernel/638511\n"},{"id":"89593","messageId":"200809030738.09589.trast@student.ethz.ch","threadId":"15339","inReplyTo":"7vvdxei5wv.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-03T05:38:07Z","receivedAt":"2008-09-03T05:38:07Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n> Thomas Rast <trast@student.ethz.ch> writes:\n> > +HELP, MY UPSTREAM HAS REBASED!\n> > +------------------------------\n> \n> I read this section only once, but it looked reasonable as a recovery\n> procedure to me.\n\nThanks a lot for your comments, I will look into the links you gave\nme.\n\nIt occured to me that rebase's ability to skip existing commits can\neffectively replace the entire manual component of finding out when\nthe topic branch started.  Which makes it far less scary. :-(\n\nMaybe I'll write something about editing with 'rebase -i' instead,\nwhich breaks the automatic skips again.\n\n- Thomas\n\n-- \nThomas Rast\ntrast@student.ethz.ch\n\n"},{"id":"90145","messageId":"7vk5dmdz7s.fsf@gitster.siamese.dyndns.org","threadId":"15339","inReplyTo":"1220386721-10215-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-09-08T22:55:51Z","receivedAt":"2008-09-08T22:55:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Any follow-up on this topic since:\n\n    http://thread.gmane.org/gmane.comp.version-control.git/94701/focus=94761\n"},{"id":"90167","messageId":"200809090742.54396.trast@student.ethz.ch","threadId":"15339","inReplyTo":"7vk5dmdz7s.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-09T05:42:51Z","receivedAt":"2008-09-09T05:42:51Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n> Any follow-up on this topic since:\n> \n>     http://thread.gmane.org/gmane.comp.version-control.git/94701/focus=94761\n\nI've been busy doing other work, sorry.  I haven't forgotten though,\nand will definitely get back to it :-)\n\n- Thomas\n\n-- \nThomas Rast\ntrast@student.ethz.ch\n\n"},{"id":"90444","messageId":"1221147525-5589-1-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"200809030738.09589.trast@student.ethz.ch","subject":"[PATCH 0/2.5] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-11T15:38:43Z","receivedAt":"2008-09-11T15:38:43Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"So here's the follow-up I promised.\n\nJunio C Hamano <gitster@pobox.com> wrote:\n>\n> Thomas Rast <trast@student.ethz.ch> writes:\n> > - Is it perhaps too verbose, or in the wrong place?  I did not want to\n> >   detract from the feature descriptions that the manpage should first\n> >   and foremost contain.  Chances that a user will \"accidentally\" read\n> >   the section at this position and length seem fairly low however.\n> \n> It feels on a bit too repetitive side, but I think this is going in the\n> right direction.  How about dropping the earlier part of the change to\n> Notes section (but keep \"See also\" which is a good guide for understanding\n> the said \"implications\")?\n\nI rewrote it to include the actual rebase behaviour and some scenarios\nthat arise from 'rebase -i', 'commit --amend' etc., then tried to\nshorten the section as far as I could.  Hopefully this cut down on the\nrepetitions.  Unfortunately it still grew longer due to the extra\ncontent.  The second patch then includes references to that section in\nthe appropriate manpages.\n\nThe third patch is again RFC, and I made it regarding this section:\n\n> The additions you made are all about why rebasing public history is bad\n> from mechanisms [...] POV.\n> While that description is all good, I think there should also be a\n> discussion from the patchflow/workflow angle.\n> \n> \"Upstream has rebased\" almost implies that it has its own upstream\n> (i.e. \"My upstream\" is not the toplevel upstream, but is a subsystem tree\n> or something).\n> \n> Rebasing upstream is bad, but an upstream that backmerges from its own\n> upstream too often is equally bad, and the reason of the badness, viewed\n> from the workflow angle, shares exactly the same component.\n> \n> It means that the mid-level upstream in question is not focused enough.\n\nI noticed that there is no manpage in which we document such workflows\nanyway.  There is a short definition of 'topic branch' in\nglossary-content.txt, and a parenthetical definition in\nuser-manual.txt in a sort of \"linux.git howto\".  Nothing longer,\nhowever.\n\n  [I learned what I know from Linus's Google Tech Talk[1], Tv's more\n  recent EuroPython talk[2], looking at git.git, and mail such as the\n  ones you linked.  I recommended [2] to people who asked about topic\n  branches on #git a few times.]\n\nSo this is an attempt to make a \"workflow reference\".  I tried to\nstrike a balance between \"just\" a reference (the Rule/Recipe blocks)\nand more of a tutorial approach which explains the reasons.  I would\nagain greatly appreciate comments.\n\n- Thomas\n\n\nThomas Rast (2+1):\n  Documentation: new upstream rebase recovery section in git-rebase\n  Documentation: Refer to git-rebase(1) to warn against rewriting\n  Documentation: add manpage about workflows\n\n\n[1] http://video.google.com/videoplay?docid=-2199332044603874737\n[2] http://blip.tv/file/1114793/\n"},{"id":"90443","messageId":"1221147525-5589-2-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221147525-5589-1-git-send-email-trast@student.ethz.ch","subject":"[PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-11T15:38:44Z","receivedAt":"2008-09-11T15:38:44Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Documents how to recover if the upstream that you pull from has\nrebased the branches you depend your work on.  Hopefully this can also\nserve as a warning to potential rebasers.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/git-rebase.txt |  103 +++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 98 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 59c1b02..ba5255d 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -257,11 +257,10 @@ include::merge-strategies.txt[]\n \n NOTES\n -----\n-When you rebase a branch, you are changing its history in a way that\n-will cause problems for anyone who already has a copy of the branch\n-in their repository and tries to pull updates from you.  You should\n-understand the implications of using 'git-rebase' on a repository that\n-you share.\n+\n+You should understand the implications of using 'git-rebase' on a\n+repository that you share.  See also RECOVERING FROM UPSTREAM REBASE\n+below.\n \n When the git-rebase command is run, it will first execute a \"pre-rebase\"\n hook if one exists.  You can use this hook to do sanity checks and\n@@ -396,6 +395,100 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+RECOVERING FROM UPSTREAM REBASE\n+-------------------------------\n+\n+This section briefly explains the problems that arise from rebasing or\n+rewriting published branches, and shows how to recover.  As you will\n+see, the process is rather tedious, so we emphasize again: 'Avoid\n+rewriting published history.'  This goes for `rebase`, `commit\n+--amend`, `reset HEAD^` and `filter-branch` alike.\n+\n+To illustrate, suppose you are in a situation where someone develops a\n+'subsystem' branch, and you are working on a 'topic' that is dependent\n+on this 'subsystem'.  You might end up with a history like the\n+following:\n+\n+------------\n+    o---o---o---o---o  master\n+\t \\\n+\t  o---o---o---o---o  subsystem\n+\t\t\t   \\\n+\t\t\t    *---*---*  topic\n+------------\n+\n+If 'subsystem' is rebased against master, the following happens:\n+\n+------------\n+    o---o---o---o---o  master\n+\t|\t     \\\n+\t|\t      o'--o'--o'--o'--o'  subsystem\n+\t\\\n+\t o---o---o---o---o---*---*---*\ttopic\n+------------\n+\n+Note that while we have marked your own commits with a '*', there is\n+nothing that distinguishes them from the commits that previously were\n+on 'subsystem'.  Luckily, 'git-rebase' knows to skip commits that are\n+textually the same as commits in the upstream.  So if you say\n+(assuming you're on 'topic')\n+------------\n+    git rebase subsystem\n+------------\n+you will end up with the fixed history\n+------------\n+    o---o---o---o---o  master\n+\t\t     \\\n+\t\t      o'--o'--o'--o'--o'  subsystem\n+\t\t\t\t\t\\\n+\t\t\t\t\t *'--*'--*'  topic\n+------------\n+\n+This becomes a ripple effect to anyone downstream of the first rebase:\n+anyone downstream from 'topic' now needs to rebase too, and so on.\n+\n+Things get more complicated if your upstream used `git rebase\n+--interactive` (or `commit --amend` or `reset --hard HEAD^`).  Label\n+the example history as follows:\n+\n+------------\n+    o---o---o---o---o  master\n+\t \\\n+\t  A---B---C---D---E  subsystem\n+\t\t\t   \\\n+\t\t\t    X---Y---Z  topic\n+------------\n+\n+Now suppose the 'subsystem' maintainer decides to clean up his history\n+with an interactive rebase.  He edits commits A and D (marked with a\n+`*`), decides to remove D entirely and moves B to the front.  This\n+results in\n+\n+------------\n+    o---o---o---o---o  master\n+\t|\t     \\\n+\t|\t      A*--C*--E'--B'  subsystem\n+\t\\\n+\t A---B---C---D---E---X---Y---Z\ttopic\n+------------\n+\n+'git-rebase' can still tell that E'=E and B'=B, so a plain `git rebase\n+subsystem` would not duplicate those commits.  However, it would\n+**resurrect** D (which may succeed silently!) and try to apply the\n+original versions of A and C (probably resulting in conflicts).\n+\n+To fix this, you have to manually transplant your own part of the\n+history to the new branch head.  Looking at `git log`, you should be\n+able to determine that three commits on 'topic' are yours.  Again\n+assuming you are already on 'topic', you can do\n+------------\n+    git rebase --onto subsystem HEAD~3\n+------------\n+to put things right.  Of course, this again ripples onwards:\n+'everyone' downstream from 'subsystem' will have to 'manually' rebase\n+all their work!\n+\n+\n Authors\n ------\n Written by Junio C Hamano <gitster@pobox.com> and\n-- \n1.6.0.1.470.g200b\n"},{"id":"90442","messageId":"1221147525-5589-3-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221147525-5589-2-git-send-email-trast@student.ethz.ch","subject":"[PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-11T15:38:45Z","receivedAt":"2008-09-11T15:38:45Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This points readers at the \"Recovering from upstream rebase\" warning\nin git-rebase(1) when we talk about rewriting published history in the\n'reset', 'commit --amend', and 'filter-branch' documentation.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/git-commit.txt        |    4 ++++\n Documentation/git-filter-branch.txt |    4 +++-\n Documentation/git-reset.txt         |    4 +++-\n 3 files changed, 10 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex eb05b0f..eeba58d 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -144,6 +144,10 @@ It is a rough equivalent for:\n ------\n but can be used to amend a merge commit.\n --\n++\n+You should understand the implications of rewriting history if you\n+amend a commit that has already been published.  (See the \"RECOVERING\n+FROM UPSTREAM REBASE\" section in linkgit:git-rebase[1].)\n \n -i::\n --include::\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex b0e710d..fed6de6 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -36,7 +36,9 @@ the objects and will not converge with the original branch.  You will not\n be able to easily push and distribute the rewritten branch on top of the\n original branch.  Please do not use this command if you do not know the\n full implications, and avoid using it anyway, if a simple single commit\n-would suffice to fix your problem.\n+would suffice to fix your problem.  (See the \"RECOVERING FROM UPSTREAM\n+REBASE\" section in linkgit:git-rebase[1] for further information about\n+rewriting published history.)\n \n Always verify that the rewritten version is correct: The original refs,\n if different from the rewritten ones, will be stored in the namespace\ndiff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt\nindex 6abaeac..52aab5e 100644\n--- a/Documentation/git-reset.txt\n+++ b/Documentation/git-reset.txt\n@@ -82,7 +82,9 @@ $ git reset --hard HEAD~3   <1>\n +\n <1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad\n and you do not want to ever see them again.  Do *not* do this if\n-you have already given these commits to somebody else.\n+you have already given these commits to somebody else.  (See the\n+\"RECOVERING FROM UPSTREAM REBASE\" section in linkgit:git-rebase[1] for\n+the implications of doing so.)\n \n Undo a commit, making it a topic branch::\n +\n-- \n1.6.0.1.470.g200b\n"},{"id":"90445","messageId":"1221147585-5695-1-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221147525-5589-3-git-send-email-trast@student.ethz.ch","subject":"[RFC PATCH] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-11T15:39:45Z","receivedAt":"2008-09-11T15:39:45Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This attempts to make a manpage about workflows that is both handy to\npoint people at it and as a beginner's introduction.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/Makefile         |    2 +-\n Documentation/gitworkflows.txt |  326 ++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 327 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/gitworkflows.txt\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ded0e40..e33ddcb 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \\\n \tgitrepository-layout.txt\n MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \\\n \tgitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \\\n-\tgitdiffcore.txt\n+\tgitdiffcore.txt gitworkflows.txt\n \n MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)\n MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nnew file mode 100644\nindex 0000000..3462000\n--- /dev/null\n+++ b/Documentation/gitworkflows.txt\n@@ -0,0 +1,326 @@\n+gitworkflows(7)\n+===============\n+\n+NAME\n+----\n+gitworkflows - An overview of recommended workflows with git\n+\n+SYNOPSIS\n+--------\n+git *\n+\n+\n+DESCRIPTION\n+-----------\n+\n+This tutorial gives a brief overview of workflows recommended to\n+use, and collaborate with, Git.\n+\n+While the prose tries to motivate each of them, we formulate a set of\n+'rules' for quick reference.  Do not always take them literally; you\n+should value good reasons higher than following a random manpage to\n+the letter.\n+\n+\n+SEPARATE CHANGES\n+----------------\n+\n+As a general rule, you should try to split your changes into small\n+logical steps, and commit each of them.  They should be consistent,\n+working independently of any later commits, pass the test suite, etc.\n+\n+To achieve this, try to commit your new work at least every couple\n+hours.  You can always go back and edit the commits with `git rebase\n+--interactive` to further improve the history before you publish it.\n+\n+\n+MANAGING BRANCHES\n+-----------------\n+\n+In the following, we will assume there are 'developers', 'testers' and\n+'users'.  Even if the \"Testers\" are actually an automated test suite\n+and all \"Users\" are developers themselves, try to think in these terms\n+as you follow a software change through its life cycle.\n+\n+Usually a change evolves in a few steps:\n+\n+* The developers implement a few iterations until it \"seems to work\".\n+\n+* The testers play with it, report bugs, test the fixes, eventually\n+  clearing the change for stable releases.\n+\n+* As the users work with the new feature, they report bugs which will\n+  have to be fixed.\n+\n+In the following sections we discuss some problems that arise from\n+such a \"change flow\", and how to solve them with Git.\n+\n+We consider a fictional project with (supported) stable branch\n+'maint', main testing/development branch 'master' and \"bleeding edge\"\n+branch 'next'.  We collectively call these three branches 'main\n+branches'.\n+\n+\n+Merging upwards\n+~~~~~~~~~~~~~~~\n+\n+Since Git is quite good at merges, one should try to use them to\n+propagate changes.  For example, if a bug is fixed, you would want to\n+apply the corresponding fix to all main branches.\n+\n+A quick moment of thought reveals that you cannot do this by merging\n+\"downwards\" to older releases, since that would merge 'all' changes.\n+Hence the following:\n+\n+.Merge upwards\n+[caption=\"Rule: \"]\n+=====================================\n+Always commit your fixes to the oldest supported branch that require\n+them.  Then (periodically) merge the main branches upwards into each\n+other.\n+=====================================\n+\n+This gives a very controlled flow of fixes.  If you notice that you\n+have applied a fix to e.g. 'master' that is also required in 'maint',\n+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n+downwards.  This will happen a few times and is nothing to worry about\n+unless you do it all the time.\n+\n+\n+Topic branches\n+~~~~~~~~~~~~~~\n+\n+Any nontrivial feature will require several patches to implement, and\n+may get extra bugfixes or improvements during its lifetime.  If all\n+such commits were in one long linear history chain (e.g. if they were\n+all committed directly to, 'master'), it becomes very hard to see how\n+they belong together.\n+\n+The key concept here is \"topic branches\".  The name is pretty self\n+explanatory, with a minor caveat that comes from the \"merge upwards\"\n+rule above:\n+\n+.Topic branches\n+[caption=\"Rule: \"]\n+=====================================\n+Make a side branch for every topic. Fork it off at the oldest main\n+branch that you will eventually want to merge it into.\n+=====================================\n+\n+Many things can then be done very naturally:\n+\n+* To get the feature/bugfix into a main branch, simply merge it.  If\n+  the topic has evolved further in the meantime, merge again.\n+\n+* If you find you need new features from an 'other' branch to continue\n+  working on your topic, merge 'other' to 'topic'.  (However, do not\n+  do this \"just habitually\", see below.)\n+\n+* If you find you forked off the wrong branch and want to move it\n+  \"back in time\", use linkgit:git-rebase[1].\n+\n+Note that the last two points clash: a topic that has been merged\n+elsewhere should not be rebased.  See the section on RECOVERING FROM\n+UPSTREAM REBASE in linkgit:git-rebase[1].\n+\n+We should point out that \"habitually\" (regularly for no real reason)\n+merging a main branch into your topics--and by extension, merging\n+anything upstream into anything downstream on a regular basis--is\n+frowned upon:\n+\n+.Merge to downstream only at well-defined points\n+[caption=\"Rule: \"]\n+=====================================\n+Do not merge to downstream except:\n+\n+* with a good reason (such as upstream API changes that affect you), or\n+\n+* at well-defined points such as when an upstream release has been tagged.\n+=====================================\n+\n+Otherwise, the many resulting small merges will greatly clutter up\n+history.  Anyone who later investigates the history of a file will\n+have to find out whether that merge affected the topic in\n+development.  Linus hates it.  An upstream might even inadvertently be\n+merged into a \"more stable\" branch.  And so on.\n+\n+\n+Integration branches\n+~~~~~~~~~~~~~~~~~~~~\n+\n+If you followed the last paragraph, you will now have many small topic\n+branches, and occasionally wonder how they interact.  Perhaps the\n+result of merging them does not even work?  But on the other hand, we\n+want to avoid merging them anywhere \"stable\" because such merges\n+cannot easily be undone.\n+\n+The solution, of course, is to make a merge that we can undo: merge\n+into a throw-away branch.\n+\n+.Integration branches\n+[caption=\"Rule: \"]\n+=====================================\n+To test the interaction of several topics, merge them into a\n+throw-away branch.\n+=====================================\n+\n+If you make it (very) clear that this branch is going to be deleted\n+right after the testing, you can even publish this branch, for example\n+to give the testers a chance to work with it, or other developers a\n+chance to see if their in-progress work will be compatible.\n+\n+\n+SHARING WORK\n+------------\n+\n+After the last section, you should know how to manage topics.  In\n+general, you will not be the only person working on the project, so\n+you will have to share your work.\n+\n+Roughly speaking, there are two important workflows.  Their\n+distinguishing mark is whether they can be used to propagate merges.\n+Medium to large projects will typically employ some mixture of the\n+two:\n+\n+* \"Upstream\" in the most general sense 'pushes' changes to the\n+  repositor(ies) holding the main history.  Everyone can 'pull' from\n+  there to stay up to date.\n+\n+* Frequent contributors, subsystem maintainers, etc. may use push/pull\n+  to send their changes upstream.\n+\n+* The rest -- typically anyone more than one or two levels away from the\n+  main maintainer -- send patches by mail.\n+\n+None of these boundaries are sharp, so find out what works best for\n+you.\n+\n+\n+Push/pull\n+~~~~~~~~~\n+\n+There are three main tools that can be used for this:\n+\n+* linkgit:git-push[1] copies your branches to a remote repository,\n+  usually to one that can be read by all involved parties;\n+\n+* linkgit:git-fetch[1] that copies remote branches to your repository;\n+  and\n+\n+* linkgit:git-pull[1] that is fetch and merge in one go.\n+\n+Note the last point.  Do 'not' use 'git-pull' unless you actually want\n+to merge the remote branch.\n+\n+Getting changes out is easy:\n+\n+.Push/pull: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git push <remote> <branch>` and tell everyone where they can fetch\n+from.\n+=====================================\n+\n+You will still have to tell people by other means, such as mail.  (Git\n+provides the linkgit:request-pull[1] to send preformatted pull\n+requests to upstream maintainers to simplify this task.)\n+\n+If you just want to get the newest copies of the main branches,\n+staying up to date is easy too:\n+\n+.Push/pull: Staying up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+Use `git fetch <remote>` or `git remote update` to stay up to date.\n+=====================================\n+\n+Then simply fork your topic branches from the stable remotes as\n+explained earlier.\n+\n+If you are a maintainer and would like to merge other people's topic\n+branches to the main branches, they will typically send a request to\n+do so by mail.  Such a request might say\n+\n+-------------------------------------\n+Please pull from\n+    git://some.server.somewhere/random/repo.git mytopic\n+-------------------------------------\n+\n+In that case, 'git-pull' can do the fetch and merge in one go, as\n+follows.\n+\n+.Push/pull: Merging remote topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git pull <url> <branch>`\n+=====================================\n+\n+Occasionally, the maintainer may get merge conflicts when he tries to\n+pull changes from downstream.  In this case, he can ask downstream to\n+do the merge and resolve the conflicts themselves (perhaps they will\n+know better how to react).  It is one of the rare cases where\n+downstream 'should' merge from upstream.\n+\n+\n+format-patch/am\n+~~~~~~~~~~~~~~~\n+\n+If you are a contributor that sends changes upstream in the form of\n+emails, you should use topic branches as usual (see above).  Then use\n+linkgit:git-format-patch[1] to generate the corresponding emails\n+(highly recommended over manually formatting them because it makes the\n+maintainer's life easier).\n+\n+.format-patch/am: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git format-patch -M upstream..topic` and send out the resulting files.\n+=====================================\n+\n+See the linkgit:git-format-patch[1] manpage for further usage notes.\n+Also you should be aware that the maintainer may impose further\n+restrictions, such as \"Signed-off-by\" requirements.\n+\n+If the maintainer tells you that your patch no longer applies to the\n+current upstream, you will have to rebase your topic (you cannot use a\n+merge because you cannot format-patch merges):\n+\n+.format-patch/am: Keeping topics up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+`git rebase upstream`\n+=====================================\n+\n+You can then fix the conflicts during the rebase.  Presumably you have\n+not published your topic other than by mail, so rebasing it is not a\n+problem.\n+\n+If you receive such a patch (as maintainer, or perhaps reader of the\n+mailing list it was sent to), save the mail to a file and use\n+'git-am':\n+\n+.format-patch/am: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git am < patch`\n+=====================================\n+\n+One feature worth pointing out is the three-way merge, which can help\n+if you get conflicts because of renames: `git am -3` will use index\n+information contained in patches to reconstruct a merge base.  See\n+linkgit:git-am[1] for other options.\n+\n+\n+SEE ALSO\n+--------\n+linkgit:gittutorial[7],\n+linkgit:git-push[1],\n+linkgit:git-pull[1],\n+linkgit:git-merge[1],\n+linkgit:git-rebase[1],\n+linkgit:git-format-patch[1],\n+linkgit:git-am[1]\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite.\n-- \n1.6.0.1.470.g200b\n"},{"id":"90451","messageId":"gabhgj$2oi$1@ger.gmane.org","threadId":"15339","inReplyTo":"1221147585-5695-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: add manpage about workflows","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-09-11T16:37:42Z","receivedAt":"2008-09-11T16:37:42Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Thomas Rast wrote:\n\n> This attempts to make a manpage about workflows that is both handy to\n> point people at it and as a beginner's introduction.\n[...]\n\nVery nice.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"90508","messageId":"48C9C2A4.6070601@griep.us","threadId":"15339","inReplyTo":"1221147525-5589-2-git-send-email-trast@student.ethz.ch","subject":"Re: [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Marcus Griep","fromEmail":"marcus@griep.us","sentAt":"2008-09-12T01:15:16Z","receivedAt":"2008-09-12T01:15:16Z","isPatch":true,"sender":{"key":"marcus@griep.us","avatar":"https://gravatar.com/avatar/0a841f2aad3f9a38c9bcf87a567c2a1751cb08924bae1bc46ee171395bcf9794?d=mp&s=160"},"body":"Thomas Rast wrote:\n> +Now suppose the 'subsystem' maintainer decides to clean up his history\n> +with an interactive rebase.  He edits commits A and D (marked with a\n> +`*`), decides to remove D entirely and moves B to the front.  This\n> +results in\n\nMinor correction:\n-+with an interactive rebase.  He edits commits A and D (marked with a\n++with an interactive rebase.  He edits commits A and C (marked with a\n\n> +To fix this, you have to manually transplant your own part of the\n> +history to the new branch head.  Looking at `git log`, you should be\n> +able to determine that three commits on 'topic' are yours.  Again\n> +assuming you are already on 'topic', you can do\n> +------------\n> +    git rebase --onto subsystem HEAD~3\n> +------------\n> +to put things right.  Of course, this again ripples onwards:\n> +'everyone' downstream from 'subsystem' will have to 'manually' rebase\n> +all their work!\n\nI like this documentation because it provides another clear case of how\nthe '--onto' option is used.\n\n-- \nMarcus Griep\nGPG Key ID: 0x5E968152\n——\nhttp://www.boohaunt.net\nאת.ψο´\n\n"},{"id":"90520","messageId":"200809120926.21607.trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221147585-5695-1-git-send-email-trast@student.ethz.ch","subject":"[RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows]","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-12T07:26:15Z","receivedAt":"2008-09-12T07:26:15Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Thomas Rast wrote:\n> +.Merge upwards\n> +[caption=\"Rule: \"]\n> +=====================================\n> +Always commit your fixes to the oldest supported branch that require\n> +them.  Then (periodically) merge the main branches upwards into each\n> +other.\n> +=====================================\n\nTurns out that asciidoc, at least the 8.2.5 on my system, does not\nhonour the custom caption when converting to manpages.  They become\nnumbered 'Example' blocks instead.  Is there another way to get a\nsimilar result?\n\n- Thomas\n\n-- \nThomas Rast\ntrast@student.ethz.ch\n\n\n"},{"id":"90623","messageId":"7v8wtwk4yp.fsf@gitster.siamese.dyndns.org","threadId":"15339","inReplyTo":"1221147525-5589-2-git-send-email-trast@student.ethz.ch","subject":"Re: [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-09-13T05:08:46Z","receivedAt":"2008-09-13T05:08:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> +RECOVERING FROM UPSTREAM REBASE\n> +-------------------------------\n> +\n> +This section briefly explains the problems that arise from rebasing or\n> +rewriting published branches, and shows how to recover.\n\nThe largest issue of \"The problem\" is that the person who rebases causes\nthis problem to others, _forcing_ his downstream to recover.  This intro\nneeds to make it clear the distinction between the person who rebases, who\nsuffers is forced to recover as the consequence.\n\n> +    o---o---o---o---o  master\n> +         \\\n> +          o---o---o---o---o  subsystem\n> +                           \\\n> +                            *---*---*  topic\n>...\n> +If 'subsystem' is rebased against master, the following happens:\n>...\n> +    o---o---o---o---o  master\n> +        |            \\\n> +        |             o'--o'--o'--o'--o'  subsystem\n> +        \\\n> +         o---o---o---o---o---*---*---*  topic\n\nMake the original upstream a bit longer in the \"after\" picture, explaining\nthat \"your upstream subsystem rebased on top of its own upstream after it\ngets updated\", so that the part that are unchanged in two pictures are not\ndrawn differently like you did above.\n\nIn other words, draw it like this.  It is much easier to see what's\nchanged and what's unchanged, if the part that hasn't changed stayed\nunchanged in the picture:\n\n       o---o---o---o---o  master\n            \\\n             o---o---o---o---o  subsystem\n                              \\\n                               *---*---*  topic\n\n\n       o---o---o---o---o---o---o---o  master\n            \\                       \\ \n             o---o---o---o---o       o'--o'--o'--o'--o' subsystem\n                              \\\n                               *---*---*  topic\n\n> +Note that while we have marked your own commits with a '*', there is\n> +nothing that distinguishes them from the commits that previously were\n> +on 'subsystem'.  Luckily, 'git-rebase' knows to skip commits that are\n> +textually the same as commits in the upstream.  So if you say\n> +(assuming you're on 'topic')\n\nThere is no luck involved in \"git rebase\" knowing how to do this -- this\nis by design.\n\nBut more importantly, at this point, there is a break in the flow of\nthought in this section.  Step back and read what you wrote, pretending as\nif you are reading the section for the first time, and notice:\n\n * The readers were shown how the topology before and after the\n   subsystem's rebase looked like;\n\n * The readers haven't been told what you are trying teach them now.  Yes,\n   I know that you are going to tell them how to transplant their own\n   commits on top of updated subsystem, but they don't know that yet;\n\n * Some of the readers may not even understand why it is a bad idea to\n   keep building on top of the old subsystem without rebasing on top of\n   the rebased subsystem at this point.\n\nOnly when the readers know that the objective is to transplant these three\ntop commits, they would start appreciating the difficulty (i.e. you cannot\ntell the commits apart by looking at the topology alone) of rebase the\nreader has to do, and the smart (i.e. if you are lucky, the rebase your\nupstream did may have been a simple one) git-rebase uses to help them.\n\nIt would suffice to insert something like this before \"Note that...\".\n\n        To continue working from here, you need to transplant your own\n        commits (marked as '*') on top of the \"subsystem\", which is now\n        rebased.\n\nBut see footnote below.\n\n> +This becomes a ripple effect to anyone downstream of the first rebase:\n> +anyone downstream from 'topic' now needs to rebase too, and so on.\n\nThis calls for a stronger wording than \"needs to\", perhaps \"forced to\".\n\n> +Things get more complicated if your upstream used `git rebase\n> +--interactive` (or `commit --amend` or `reset --hard HEAD^`).\n\nI do not think this section is absolutely necessary.  The upstream may\nhave done a simple rebase, which may have conflicted with the changes in\nits own upstream.\n\n> +To fix this, you have to manually transplant your own part of the\n> +history to the new branch head.  Looking at `git log`, you should be\n> +able to determine that three commits on 'topic' are yours.  Again\n> +assuming you are already on 'topic', you can do\n> +------------\n> +    git rebase --onto subsystem HEAD~3\n> +------------\n> +to put things right.\n\nHEAD~3 would _work_, but it often is easier to visualize this (perhaps in\nyour head, or in \"gitk HEAD origin origin@{1}\"):\n\n       o---o---o---o---o---o---o---o  master\n            \\                       \\ \n             o---o---o---o---o       o'--o'--o'--o'--o' subsystem\n                              \\\n                               *---*---*  topic\n\nand say:\n\n    $ git rebase --onto subsystem subsystem@{1}\n\nThe reflog reference \"1\" may be larger depending on the number of times\nyou fetched from them without rebasing, though.\n\n\n[Footnote]\n\nYou did not cover why midstream rebase _forces_ downstream to rebase.  If\nthe leaf-level person did not know better, or did not care, starting from\nthis topology:\n\n       o---o---o---o---o---o---o---o  master\n            \\                       \\ \n             o---o---o---o---o       o'--o'--o'--o'--o' subsystem\n                              \\\n                               *---*---*  topic\n\nthe leaf person can keep building on top of the old topic, and later when\nthe topic is mature, have subsystem merge the result.  If the rebase the\nsubsystem did was simple enough, the merge will be easy to resolve (both\nsides modifying the same way).\n\n       o---o---o---o---o---o---o---o  master\n            \\                       \\ \n             o---o---o---o---o       o'--o'--o'--o'--o'--M subsystem\n                              \\                         /\n                               *---*---*---*---*---*---*\n\nThe problem is that the resulting history will keep two copies of the\nmorally equivalent commits from the subsystem.  You know that, and I know\nthat, but the purpose of the document is to explain it to people who do\nnot know it yet.\n"},{"id":"90634","messageId":"1221322263-25291-1-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"7v8wtwk4yp.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 0/3] Documentation: rebase and workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-13T16:10:59Z","receivedAt":"2008-09-13T16:10:59Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n>\n\nFirst of all, thanks for your excellent criticism of my patch.\n(Thanks also to Marcus for spotting the typo, though I eventually\ndecided to remove the corresponding part again.)\n\nI'm rerolling the entire series, with a few improvements to 3/3, and\nfollowing that with an interdiff.  1/3 is almost a complete rewrite.\n(I realise that 3/3 is not really related to the first two, so we may\neventually have to split it off the series if it takes more time.)\n\nAll snipped comments have been addressed ... hopefully ;-)\n\n> In other words, draw it like this.  It is much easier to see what's\n> changed and what's unchanged, if the part that hasn't changed stayed\n> unchanged in the picture:\n[...]\n>        o---o---o---o---o---o---o---o  master\n>             \\                       \\ \n>              o---o---o---o---o       o'--o'--o'--o'--o' subsystem\n>                               \\\n>                                *---*---*  topic\n\nI had the old one in the other style to emphasise that all commits on\n'topic' are \"indistinguishable\" w.r.t. source.  But this indeed makes\nfor nicer graphs.\n\n> Thomas Rast <trast@student.ethz.ch> writes:\n> > +on 'subsystem'.  Luckily, 'git-rebase' knows to skip commits that are\n> > +textually the same as commits in the upstream.  So if you say\n> \n> There is no luck involved in \"git rebase\" knowing how to do this -- this\n> is by design.\n\nLuckily for the user! :-)\n\n> But more importantly, at this point, there is a break in the flow of\n> thought in this section.  Step back and read what you wrote, pretending as\n> if you are reading the section for the first time, and notice:\n[...]\n\nIndeed, you are right.  I stole your \"merge without rebase\" drawing,\nand added a paragraph about the reasons for a rebase.  However:\n\n> The problem is that the resulting history will keep two copies of the\n> morally equivalent commits from the subsystem.  You know that, and I know\n> that, but the purpose of the document is to explain it to people who do\n> not know it yet.\n\nMaybe that's just me, but I always thought the duplication argument\nwas a bit weak.  I think reasons such as \"resurrects changes that have\nbeen (presumably for a reason) undone\" are far scarier and more likely\nto stop users from rebasing.  Eventually, I omitted it to keep the\njustification paragraph shorter, but if others feel the same, maybe it\nshould go in.\n\n- Thomas\n\n\nThomas Rast (3):\n  Documentation: new upstream rebase recovery section in git-rebase\n  Documentation: Refer to git-rebase(1) to warn against rewriting\n  Documentation: add manpage about workflows\n\n Documentation/Makefile              |    2 +-\n Documentation/git-commit.txt        |    4 +\n Documentation/git-filter-branch.txt |    4 +-\n Documentation/git-rebase.txt        |  129 +++++++++++++-\n Documentation/git-reset.txt         |    4 +-\n Documentation/gitworkflows.txt      |  330 +++++++++++++++++++++++++++++++++++\n 6 files changed, 465 insertions(+), 8 deletions(-)\n create mode 100644 Documentation/gitworkflows.txt\n"},{"id":"90636","messageId":"1221322263-25291-2-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221322263-25291-1-git-send-email-trast@student.ethz.ch","subject":"[PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-13T16:11:00Z","receivedAt":"2008-09-13T16:11:00Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Documents how to recover if the upstream that you pull from has\nrebased the branches you depend your work on.  Hopefully this can also\nserve as a warning to potential rebasers.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nSee the series leader for discussion.\n\n Documentation/git-rebase.txt |  129 ++++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 124 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 59c1b02..a2f686c 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -257,11 +257,10 @@ include::merge-strategies.txt[]\n \n NOTES\n -----\n-When you rebase a branch, you are changing its history in a way that\n-will cause problems for anyone who already has a copy of the branch\n-in their repository and tries to pull updates from you.  You should\n-understand the implications of using 'git-rebase' on a repository that\n-you share.\n+\n+You should understand the implications of using 'git-rebase' on a\n+repository that you share.  See also RECOVERING FROM UPSTREAM REBASE\n+below.\n \n When the git-rebase command is run, it will first execute a \"pre-rebase\"\n hook if one exists.  You can use this hook to do sanity checks and\n@@ -396,6 +395,126 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+RECOVERING FROM UPSTREAM REBASE\n+-------------------------------\n+\n+Rebasing (or any other form of rewriting) a branch that others have\n+based work on is a bad idea: anyone downstream of it is forced to\n+manually fix their history.  This section explains how to do the fix\n+from the downstream's point of view.  The real fix, however, would be\n+to avoid rebasing the upstream in the first place.\n+\n+To illustrate, suppose you are in a situation where someone develops a\n+'subsystem' branch, and you are working on a 'topic' that is dependent\n+on this 'subsystem'.  You might end up with a history like the\n+following:\n+\n+------------\n+    o---o---o---o---o---o---o---o---o  master\n+\t \\\n+\t  o---o---o---o---o  subsystem\n+\t\t\t   \\\n+\t\t\t    *---*---*  topic\n+------------\n+\n+If 'subsystem' is rebased against 'master', the following happens:\n+\n+------------\n+    o---o---o---o---o---o---o---o  master\n+\t \\\t\t\t \\\n+\t  o---o---o---o---o\t  o'--o'--o'--o'--o'  subsystem\n+\t\t\t   \\\n+\t\t\t    *---*---*  topic\n+------------\n+\n+If you now continue development as usual, and eventually merge 'topic'\n+to 'subsystem', the commits will remain duplicated forever:\n+\n+------------\n+    o---o---o---o---o---o---o---o  master\n+\t \\\t\t\t \\\n+\t  o---o---o---o---o\t  o'--o'--o'--o'--o'--M\t subsystem\n+\t\t\t   \\\t\t\t     /\n+\t\t\t    *---*---*-..........-*--*  topic\n+------------\n+\n+Such duplicates are generally frowned upon because they clutter up\n+history, making it harder to follow.  To clean things up, you need to\n+transplant the commits on 'topic' to the new 'subsystem' tip, i.e.,\n+rebase 'topic'.  This becomes a ripple effect: anyone downstream from\n+'topic' is forced to rebase too, and so on!\n+\n+There are two kinds of fixes, discussed in the following subsections:\n+\n+Easy case: The changes are literally the same.::\n+\n+\tThis happens if the 'subsystem' rebase was a simple rebase and\n+\thad no conflicts.\n+\n+Hard case: The changes are not the same.::\n+\n+\tThis happens if the 'subsystem' rebase had conflicts, or used\n+\t`\\--interactive` to omit, edit, or squash commits; or if the\n+\tupstream used one of `commit \\--amend`, `reset`, or\n+\t`filter-branch`.\n+\n+\n+The easy case\n+~~~~~~~~~~~~~\n+\n+Only works if the changes (patch IDs based on the diff contents) on\n+'subsystem' are literally the same before and after the rebase.\n+\n+In that case, the fix is easy because 'git-rebase' knows to skip\n+changes that are already present in the new upstream.  So if you say\n+(assuming you're on 'topic')\n+------------\n+    git rebase subsystem\n+------------\n+you will end up with the fixed history\n+------------\n+    o---o---o---o---o---o---o---o  master\n+\t\t\t\t \\\n+\t\t\t\t  o'--o'--o'--o'--o'  subsystem\n+\t\t\t\t\t\t   \\\n+\t\t\t\t\t\t    *---*---*  topic\n+------------\n+\n+\n+The hard case\n+~~~~~~~~~~~~~\n+\n+Things get more complicated if the 'subsystem' changes do not exactly\n+correspond to the pre-rebase ones.\n+\n+NOTE: While an \"easy case recovery\" sometimes appears to be successful\n+      even in the hard case, it may have unintended consequences.  For\n+      example, a commit that was removed via `git rebase\n+      \\--interactive` will be **resurrected**!\n+\n+The idea is to manually tell 'git-rebase' \"where the old 'subsystem'\n+ended and your 'topic' began\", that is, what the old merge-base\n+between them was.  You will have to find a way to name the last commit\n+of the old 'subsystem', for example:\n+\n+* With the 'subsystem' reflog: after 'git-fetch', the old tip of\n+  'subsystem' is at `subsystem@\\{1}`.  Subsequent fetches will\n+  increase the number.  (See linkgit:git-reflog[1].)\n+\n+* Relative to the tip of 'topic': knowing that your 'topic' has three\n+  commits, the old tip of 'subsystem' must be `topic~3`.\n+\n+You can then transplant the old `subsystem..topic` to the new tip by\n+saying (for the reflog case, and assuming you are on 'topic' already):\n+------------\n+    git rebase --onto subsystem subsystem@{1}\n+------------\n+\n+The ripple effect of a \"hard case\" recovery is especially bad:\n+'everyone' downstream from 'topic' will now have to perform a \"hard\n+case\" recovery too!\n+\n+\n Authors\n ------\n Written by Junio C Hamano <gitster@pobox.com> and\n-- \n1.6.0.2.408.g3709\n"},{"id":"90633","messageId":"1221322263-25291-3-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221322263-25291-2-git-send-email-trast@student.ethz.ch","subject":"[PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-13T16:11:01Z","receivedAt":"2008-09-13T16:11:01Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This points readers at the \"Recovering from upstream rebase\" warning\nin git-rebase(1) when we talk about rewriting published history in the\n'reset', 'commit --amend', and 'filter-branch' documentation.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/git-commit.txt        |    4 ++++\n Documentation/git-filter-branch.txt |    4 +++-\n Documentation/git-reset.txt         |    4 +++-\n 3 files changed, 10 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex eb05b0f..eeba58d 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -144,6 +144,10 @@ It is a rough equivalent for:\n ------\n but can be used to amend a merge commit.\n --\n++\n+You should understand the implications of rewriting history if you\n+amend a commit that has already been published.  (See the \"RECOVERING\n+FROM UPSTREAM REBASE\" section in linkgit:git-rebase[1].)\n \n -i::\n --include::\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex b0e710d..fed6de6 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -36,7 +36,9 @@ the objects and will not converge with the original branch.  You will not\n be able to easily push and distribute the rewritten branch on top of the\n original branch.  Please do not use this command if you do not know the\n full implications, and avoid using it anyway, if a simple single commit\n-would suffice to fix your problem.\n+would suffice to fix your problem.  (See the \"RECOVERING FROM UPSTREAM\n+REBASE\" section in linkgit:git-rebase[1] for further information about\n+rewriting published history.)\n \n Always verify that the rewritten version is correct: The original refs,\n if different from the rewritten ones, will be stored in the namespace\ndiff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt\nindex 6abaeac..52aab5e 100644\n--- a/Documentation/git-reset.txt\n+++ b/Documentation/git-reset.txt\n@@ -82,7 +82,9 @@ $ git reset --hard HEAD~3   <1>\n +\n <1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad\n and you do not want to ever see them again.  Do *not* do this if\n-you have already given these commits to somebody else.\n+you have already given these commits to somebody else.  (See the\n+\"RECOVERING FROM UPSTREAM REBASE\" section in linkgit:git-rebase[1] for\n+the implications of doing so.)\n \n Undo a commit, making it a topic branch::\n +\n-- \n1.6.0.2.408.g3709\n"},{"id":"90637","messageId":"1221322263-25291-4-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221322263-25291-3-git-send-email-trast@student.ethz.ch","subject":"[PATCH 3/3] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-13T16:11:02Z","receivedAt":"2008-09-13T16:11:02Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This attempts to make a manpage about workflows that is both handy to\npoint people at it and as a beginner's introduction.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nInterdiff follows.  The important change is that the format-patch\nrecipe says to use send-email, hopefully keeping people from damaging\ntheir patches via cut&paste.\n\nUnfortunately I still don't know how to make the blocks look right in\nmanpage format.\n\n\n Documentation/Makefile         |    2 +-\n Documentation/gitworkflows.txt |  330 ++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 331 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/gitworkflows.txt\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ded0e40..e33ddcb 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \\\n \tgitrepository-layout.txt\n MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \\\n \tgitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \\\n-\tgitdiffcore.txt\n+\tgitdiffcore.txt gitworkflows.txt\n \n MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)\n MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nnew file mode 100644\nindex 0000000..b4b43da\n--- /dev/null\n+++ b/Documentation/gitworkflows.txt\n@@ -0,0 +1,330 @@\n+gitworkflows(7)\n+===============\n+\n+NAME\n+----\n+gitworkflows - An overview of recommended workflows with git\n+\n+SYNOPSIS\n+--------\n+git *\n+\n+\n+DESCRIPTION\n+-----------\n+\n+This tutorial gives a brief overview of workflows recommended to\n+use, and collaborate with, Git.\n+\n+While the prose tries to motivate each of them, we formulate a set of\n+'rules' for quick reference.  Do not always take them literally; you\n+should value good reasons higher than following a random manpage to\n+the letter.\n+\n+\n+SEPARATE CHANGES\n+----------------\n+\n+As a general rule, you should try to split your changes into small\n+logical steps, and commit each of them.  They should be consistent,\n+working independently of any later commits, pass the test suite, etc.\n+\n+To achieve this, try to commit your new work at least every couple\n+hours.  You can always go back and edit the commits with `git rebase\n+--interactive` to further improve the history before you publish it.\n+\n+\n+MANAGING BRANCHES\n+-----------------\n+\n+In the following, we will assume there are 'developers', 'testers' and\n+'users'.  Even if the \"Testers\" are actually an automated test suite\n+and all \"Users\" are developers themselves, try to think in these terms\n+as you follow a software change through its life cycle.\n+\n+Usually a change evolves in a few steps:\n+\n+* The developers implement a few iterations until it \"seems to work\".\n+\n+* The testers play with it, report bugs, test the fixes, eventually\n+  clearing the change for stable releases.\n+\n+* As the users work with the new feature, they report bugs which will\n+  have to be fixed.\n+\n+In the following sections we discuss some problems that arise from\n+such a \"change flow\", and how to solve them with Git.\n+\n+We consider a fictional project with (supported) stable branch\n+'maint', main testing/development branch 'master' and \"bleeding edge\"\n+branch 'next'.  We collectively call these three branches 'main\n+branches'.\n+\n+\n+Merging upwards\n+~~~~~~~~~~~~~~~\n+\n+Since Git is quite good at merges, one should try to use them to\n+propagate changes.  For example, if a bug is fixed, you would want to\n+apply the corresponding fix to all main branches.\n+\n+A quick moment of thought reveals that you cannot do this by merging\n+\"downwards\" to older releases, since that would merge 'all' changes.\n+Hence the following:\n+\n+.Merge upwards\n+[caption=\"Rule: \"]\n+=====================================\n+Always commit your fixes to the oldest supported branch that require\n+them.  Then (periodically) merge the main branches upwards into each\n+other.\n+=====================================\n+\n+This gives a very controlled flow of fixes.  If you notice that you\n+have applied a fix to e.g. 'master' that is also required in 'maint',\n+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n+downwards.  This will happen a few times and is nothing to worry about\n+unless you do it all the time.\n+\n+\n+Topic branches\n+~~~~~~~~~~~~~~\n+\n+Any nontrivial feature will require several patches to implement, and\n+may get extra bugfixes or improvements during its lifetime.  If all\n+such commits were in one long linear history chain (e.g., if they were\n+all committed directly to 'master'), it becomes very hard to see how\n+they belong together.\n+\n+The key concept here is \"topic branches\".  The name is pretty self\n+explanatory, with a minor caveat that comes from the \"merge upwards\"\n+rule above:\n+\n+.Topic branches\n+[caption=\"Rule: \"]\n+=====================================\n+Make a side branch for every topic. Fork it off at the oldest main\n+branch that you will eventually want to merge it into.\n+=====================================\n+\n+Many things can then be done very naturally:\n+\n+* To get the feature/bugfix into a main branch, simply merge it.  If\n+  the topic has evolved further in the meantime, merge again.\n+\n+* If you find you need new features from an 'other' branch to continue\n+  working on your topic, merge 'other' to 'topic'.  (However, do not\n+  do this \"just habitually\", see below.)\n+\n+* If you find you forked off the wrong branch and want to move it\n+  \"back in time\", use linkgit:git-rebase[1].\n+\n+Note that the last two points clash: a topic that has been merged\n+elsewhere should not be rebased.  See the section on RECOVERING FROM\n+UPSTREAM REBASE in linkgit:git-rebase[1].\n+\n+We should point out that \"habitually\" (regularly for no real reason)\n+merging a main branch into your topics -- and by extension, merging\n+anything upstream into anything downstream on a regular basis -- is\n+frowned upon:\n+\n+.Merge to downstream only at well-defined points\n+[caption=\"Rule: \"]\n+=====================================\n+Do not merge to downstream except:\n+\n+* with a good reason (such as upstream API changes that affect you), or\n+\n+* at well-defined points such as when an upstream release has been tagged.\n+=====================================\n+\n+Otherwise, the many resulting small merges will greatly clutter up\n+history.  Anyone who later investigates the history of a file will\n+have to find out whether that merge affected the topic in\n+development.  Linus hates it.  An upstream might even inadvertently be\n+merged into a \"more stable\" branch.  And so on.\n+\n+\n+Integration branches\n+~~~~~~~~~~~~~~~~~~~~\n+\n+If you followed the last paragraph, you will now have many small topic\n+branches, and occasionally wonder how they interact.  Perhaps the\n+result of merging them does not even work?  But on the other hand, we\n+want to avoid merging them anywhere \"stable\" because such merges\n+cannot easily be undone.\n+\n+The solution, of course, is to make a merge that we can undo: merge\n+into a throw-away branch.\n+\n+.Integration branches\n+[caption=\"Rule: \"]\n+=====================================\n+To test the interaction of several topics, merge them into a\n+throw-away branch.\n+=====================================\n+\n+If you make it (very) clear that this branch is going to be deleted\n+right after the testing, you can even publish this branch, for example\n+to give the testers a chance to work with it, or other developers a\n+chance to see if their in-progress work will be compatible.\n+\n+\n+SHARING WORK\n+------------\n+\n+After the last section, you should know how to manage topics.  In\n+general, you will not be the only person working on the project, so\n+you will have to share your work.\n+\n+Roughly speaking, there are two important workflows.  Their\n+distinguishing mark is whether they can be used to propagate merges.\n+Medium to large projects will typically employ some mixture of the\n+two:\n+\n+* \"Upstream\" in the most general sense 'pushes' changes to the\n+  repositor(ies) holding the main history.  Everyone can 'pull' from\n+  there to stay up to date.\n+\n+* Frequent contributors, subsystem maintainers, etc. may use push/pull\n+  to send their changes upstream.\n+\n+* The rest -- typically anyone more than one or two levels away from the\n+  main maintainer -- send patches by mail.\n+\n+None of these boundaries are sharp, so find out what works best for\n+you.\n+\n+\n+Push/pull\n+~~~~~~~~~\n+\n+There are three main tools that can be used for this:\n+\n+* linkgit:git-push[1] copies your branches to a remote repository,\n+  usually to one that can be read by all involved parties;\n+\n+* linkgit:git-fetch[1] that copies remote branches to your repository;\n+  and\n+\n+* linkgit:git-pull[1] that does fetch and merge in one go.\n+\n+Note the last point.  Do 'not' use 'git-pull' unless you actually want\n+to merge the remote branch.\n+\n+Getting changes out is easy:\n+\n+.Push/pull: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git push <remote> <branch>` and tell everyone where they can fetch\n+from.\n+=====================================\n+\n+You will still have to tell people by other means, such as mail.  (Git\n+provides the linkgit:request-pull[1] to send preformatted pull\n+requests to upstream maintainers to simplify this task.)\n+\n+If you just want to get the newest copies of the main branches,\n+staying up to date is easy too:\n+\n+.Push/pull: Staying up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+Use `git fetch <remote>` or `git remote update` to stay up to date.\n+=====================================\n+\n+Then simply fork your topic branches from the stable remotes as\n+explained earlier.\n+\n+If you are a maintainer and would like to merge other people's topic\n+branches to the main branches, they will typically send a request to\n+do so by mail.  Such a request might say\n+\n+-------------------------------------\n+Please pull from\n+    git://some.server.somewhere/random/repo.git mytopic\n+-------------------------------------\n+\n+In that case, 'git-pull' can do the fetch and merge in one go, as\n+follows.\n+\n+.Push/pull: Merging remote topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git pull <url> <branch>`\n+=====================================\n+\n+Occasionally, the maintainer may get merge conflicts when he tries to\n+pull changes from downstream.  In this case, he can ask downstream to\n+do the merge and resolve the conflicts themselves (perhaps they will\n+know better how to resolve them).  It is one of the rare cases where\n+downstream 'should' merge from upstream.\n+\n+\n+format-patch/am\n+~~~~~~~~~~~~~~~\n+\n+If you are a contributor that sends changes upstream in the form of\n+emails, you should use topic branches as usual (see above).  Then use\n+linkgit:git-format-patch[1] to generate the corresponding emails\n+(highly recommended over manually formatting them because it makes the\n+maintainer's life easier).\n+\n+.format-patch/am: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+* `git format-patch -M upstream..topic` to turn them into preformatted\n+  patch files\n+* `git send-email --to=<recipient> <patches>`\n+=====================================\n+\n+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\n+manpages for further usage notes.  Also you should be aware that the\n+maintainer may impose further restrictions, such as \"Signed-off-by\"\n+requirements.\n+\n+If the maintainer tells you that your patch no longer applies to the\n+current upstream, you will have to rebase your topic (you cannot use a\n+merge because you cannot format-patch merges):\n+\n+.format-patch/am: Keeping topics up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+`git rebase upstream`\n+=====================================\n+\n+You can then fix the conflicts during the rebase.  Presumably you have\n+not published your topic other than by mail, so rebasing it is not a\n+problem.\n+\n+If you receive such a patch (as maintainer, or perhaps reader of the\n+mailing list it was sent to), save the mail to a file and use\n+'git-am':\n+\n+.format-patch/am: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git am < patch`\n+=====================================\n+\n+One feature worth pointing out is the three-way merge, which can help\n+if you get conflicts because of renames: `git am -3` will use index\n+information contained in patches to reconstruct a merge base.  See\n+linkgit:git-am[1] for other options.\n+\n+\n+SEE ALSO\n+--------\n+linkgit:gittutorial[7],\n+linkgit:git-push[1],\n+linkgit:git-pull[1],\n+linkgit:git-merge[1],\n+linkgit:git-rebase[1],\n+linkgit:git-format-patch[1],\n+linkgit:git-send-email[1],\n+linkgit:git-am[1]\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite.\n-- \n1.6.0.2.408.g3709\n"},{"id":"90635","messageId":"1221322263-25291-5-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1221322263-25291-4-git-send-email-trast@student.ethz.ch","subject":"Interdiff: [3/3] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-13T16:11:03Z","receivedAt":"2008-09-13T16:11:03Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"---\n Documentation/gitworkflows.txt |   24 ++++++++++++++----------\n 1 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nindex 3462000..b4b43da 100644\n--- a/Documentation/gitworkflows.txt\n+++ b/Documentation/gitworkflows.txt\n@@ -92,8 +92,8 @@ Topic branches\n \n Any nontrivial feature will require several patches to implement, and\n may get extra bugfixes or improvements during its lifetime.  If all\n-such commits were in one long linear history chain (e.g. if they were\n-all committed directly to, 'master'), it becomes very hard to see how\n+such commits were in one long linear history chain (e.g., if they were\n+all committed directly to 'master'), it becomes very hard to see how\n they belong together.\n \n The key concept here is \"topic branches\".  The name is pretty self\n@@ -124,8 +124,8 @@ elsewhere should not be rebased.  See the section on RECOVERING FROM\n UPSTREAM REBASE in linkgit:git-rebase[1].\n \n We should point out that \"habitually\" (regularly for no real reason)\n-merging a main branch into your topics--and by extension, merging\n-anything upstream into anything downstream on a regular basis--is\n+merging a main branch into your topics -- and by extension, merging\n+anything upstream into anything downstream on a regular basis -- is\n frowned upon:\n \n .Merge to downstream only at well-defined points\n@@ -207,7 +207,7 @@ There are three main tools that can be used for this:\n * linkgit:git-fetch[1] that copies remote branches to your repository;\n   and\n \n-* linkgit:git-pull[1] that is fetch and merge in one go.\n+* linkgit:git-pull[1] that does fetch and merge in one go.\n \n Note the last point.  Do 'not' use 'git-pull' unless you actually want\n to merge the remote branch.\n@@ -258,7 +258,7 @@ follows.\n Occasionally, the maintainer may get merge conflicts when he tries to\n pull changes from downstream.  In this case, he can ask downstream to\n do the merge and resolve the conflicts themselves (perhaps they will\n-know better how to react).  It is one of the rare cases where\n+know better how to resolve them).  It is one of the rare cases where\n downstream 'should' merge from upstream.\n \n \n@@ -274,12 +274,15 @@ maintainer's life easier).\n .format-patch/am: Publishing branches/topics\n [caption=\"Recipe: \"]\n =====================================\n-`git format-patch -M upstream..topic` and send out the resulting files.\n+* `git format-patch -M upstream..topic` to turn them into preformatted\n+  patch files\n+* `git send-email --to=<recipient> <patches>`\n =====================================\n \n-See the linkgit:git-format-patch[1] manpage for further usage notes.\n-Also you should be aware that the maintainer may impose further\n-restrictions, such as \"Signed-off-by\" requirements.\n+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\n+manpages for further usage notes.  Also you should be aware that the\n+maintainer may impose further restrictions, such as \"Signed-off-by\"\n+requirements.\n \n If the maintainer tells you that your patch no longer applies to the\n current upstream, you will have to rebase your topic (you cannot use a\n@@ -319,6 +322,7 @@ linkgit:git-pull[1],\n linkgit:git-merge[1],\n linkgit:git-rebase[1],\n linkgit:git-format-patch[1],\n+linkgit:git-send-email[1],\n linkgit:git-am[1]\n \n GIT\n-- \n1.6.0.2.408.g3709\n"},{"id":"91158","messageId":"adf1fd3d0809191722n44b49176u83833c33c5779b8d@mail.gmail.com","threadId":"15339","inReplyTo":"1221147585-5695-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: add manpage about workflows","fromName":"Santi Béjar","fromEmail":"santi@agolina.net","sentAt":"2008-09-20T00:22:58Z","receivedAt":"2008-09-20T00:22:58Z","isPatch":true,"sender":{"key":"santi@agolina.net","avatar":null},"body":"On Thu, Sep 11, 2008 at 5:39 PM, Thomas Rast <trast@student.ethz.ch> wrote:\n> This attempts to make a manpage about workflows that is both handy to\n> point people at it and as a beginner's introduction.\n>\n> Signed-off-by: Thomas Rast <trast@student.ethz.ch>\n> ---\n>  Documentation/Makefile         |    2 +-\n>  Documentation/gitworkflows.txt |  326 +\n+++++++++++++++++++++++++++++++++++++++\n\nIt should be linked/advertised from other pages (git, tutorial, everyday?)\n> diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\n> new file mode 100644\n> index 0000000..3462000\n> --- /dev/null\n> +++ b/Documentation/gitworkflows.txt\n\n[...]\n\n> +To achieve this, try to commit your new work at least every couple\n> +hours. You can always go back and edit the commits with `git rebase\n> +--interactive` to further improve the history before you publish it.\n\nI do not agree with this. I don´t much differences between a big patch\nand the same patch divided randomly.\n\nTo achieve this, try to commit when you are minimally satisfied with\nthe new code or before large changes. You can always go back and edit\nthe commits with `git rebase --interactive` to further improve the\nhistory before you publish it, or you could split a big patch as is\nexplained in gitlink:git-stash.\n\n> +\n> +\n> +MANAGING BRANCHES\n> +-----------------\n> +\n> +In the following, we will assume there are 'developers', 'testers' and\n> +'users'.  Even if the \"Testers\" are actually an automated test suite\n> +and all \"Users\" are developers themselves, try to think in these terms\n\n\"Testers\" -> 'testers', ...\n\n> +as you follow a software change through its life cycle.\n> +\n> +Usually a change evolves in a few steps:\n> +\n> +* The developers implement a few iterations until it \"seems to work\".\n> +\n> +* The testers play with it, report bugs, test the fixes, eventually\n> +  clearing the change for stable releases.\n> +\n> +* As the users work with the new feature, they report bugs which will\n> +  have to be fixed.\n> +\n> +In the following sections we discuss some problems that arise from\n> +such a \"change flow\", and how to solve them with Git.\n> +\n> +We consider a fictional project with (supported) stable branch\n> +'maint', main testing/development branch 'master' and \"bleeding edge\"\n> +branch 'next'.  We collectively call these three branches 'main\n> +branches'.\n\nYou mention the next branch but it is not explained.\n\n> +\n> +\n> +Merging upwards\n> +~~~~~~~~~~~~~~~\n> +\n> +Since Git is quite good at merges, one should try to use them to\n> +propagate changes.  For example, if a bug is fixed, you would want to\n> +apply the corresponding fix to all main branches.\n> +\n> +A quick moment of thought reveals that you cannot do this by merging\n> +\"downwards\" to older releases, since that would merge 'all' changes.\n\nall development changes\n\n> +Hence the following:\n> +\n> +.Merge upwards\n> +[caption=\"Rule: \"]\n> +=====================================\n> +Always commit your fixes to the oldest supported branch that require\n> +them.  Then (periodically) merge the main branches upwards into each\n> +other.\n> +=====================================\n> +\n> +This gives a very controlled flow of fixes.  If you notice that you\n> +have applied a fix to e.g. 'master' that is also required in 'maint',\n> +you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n> +downwards.  This will happen a few times and is nothing to worry about\n> +unless you do it all the time.\n> +\n> +\n> +Topic branches\n> +~~~~~~~~~~~~~~\n> +\n> +Any nontrivial feature will require several patches to implement, and\n> +may get extra bugfixes or improvements during its lifetime.  If all\n> +such commits were in one long linear history chain (e.g. if they were\n> +all committed directly to, 'master'), it becomes very hard to see how\n> +they belong together.\n> +\n> +The key concept here is \"topic branches\".  The name is pretty self\n> +explanatory, with a minor caveat that comes from the \"merge upwards\"\n> +rule above:\n> +\n> +.Topic branches\n> +[caption=\"Rule: \"]\n> +=====================================\n> +Make a side branch for every topic. Fork it off at the oldest main\n> +branch that you will eventually want to merge it into.\n> +=====================================\n> +\n> +Many things can then be done very naturally:\n> +\n> +* To get the feature/bugfix into a main branch, simply merge it.  If\n> +  the topic has evolved further in the meantime, merge again.\n> +\n> +* If you find you need new features from an 'other' branch to continue\n\n... from the branch 'other' to continue\n\n> +  working on your topic, merge 'other' to 'topic'.  (However, do not\n> +  do this \"just habitually\", see below.)\n> +\n> +* If you find you forked off the wrong branch and want to move it\n> +  \"back in time\", use linkgit:git-rebase[1].\n> +\n> +Note that the last two points clash: a topic that has been merged\n> +elsewhere should not be rebased.  See the section on RECOVERING FROM\n> +UPSTREAM REBASE in linkgit:git-rebase[1].\n> +\n> +We should point out that \"habitually\" (regularly for no real reason)\n> +merging a main branch into your topics--and by extension, merging\n> +anything upstream into anything downstream on a regular basis--is\n> +frowned upon:\n> +\n> +.Merge to downstream only at well-defined points\n> +[caption=\"Rule: \"]\n> +=====================================\n> +Do not merge to downstream except:\n> +\n> +* with a good reason (such as upstream API changes that affect you), or\n> +\n> +* at well-defined points such as when an upstream release has been tagged.\n\nDo not merge to downstream except with a good reasons:\n\n* API changes that affect you branch\n* your branch no longer merges cleanly\n* when your branch is way not up-to-date.\n\nAnd mainly at well-defined points, such as when an upstream release\nhas been tagged, preferably stable release.\n\n> +=====================================\n> +\n> +Otherwise, the many resulting small merges will greatly clutter up\n> +history.  Anyone who later investigates the history of a file will\n> +have to find out whether that merge affected the topic in\n> +development.  Linus hates it.  An upstream might even inadvertently be\n> +merged into a \"more stable\" branch.  And so on.\n\nYes, the main point is that Linus hates it :-)\n> +\n> +\n> +Integration branches\n> +~~~~~~~~~~~~~~~~~~~~\n> +\n> +If you followed the last paragraph, you will now have many small topic\n> +branches, and occasionally wonder how they interact.  Perhaps the\n> +result of merging them does not even work?  But on the other hand, we\n> +want to avoid merging them anywhere \"stable\" because such merges\n> +cannot easily be undone.\n> +\n> +The solution, of course, is to make a merge that we can undo: merge\n> +into a throw-away branch.\n> +\n> +.Integration branches\n> +[caption=\"Rule: \"]\n> +=====================================\n> +To test the interaction of several topics, merge them into a\n> +throw-away branch.\n> +=====================================\n> +\n> +If you make it (very) clear that this branch is going to be deleted\n> +right after the testing, you can even publish this branch, for example\n> +to give the testers a chance to work with it, or other developers a\n> +chance to see if their in-progress work will be compatible.\n> +\n> +\n> +SHARING WORK\n> +------------\n> +\n> +After the last section, you should know how to manage topics.  In\n> +general, you will not be the only person working on the project, so\n> +you will have to share your work.\n> +\n> +Roughly speaking, there are two important workflows.  Their\n> +distinguishing mark is whether they can be used to propagate merges.\n\nand one keeps the branch history while the other rewrite it.\n\n> +Medium to large projects will typically employ some mixture of the\n> +two:\n\nI would remove this.\n\nThe different actors share their work as:\n> +\n> +* \"Upstream\" in the most general sense 'pushes' changes to the\n> +  repositor(ies) holding the main history.  Everyone can 'pull' from\n> +  there to stay up to date.\n\ns/repositor(ies)/repository/\n\nAnd:\n\nShe pull from her (trusted) downstreams, and applies the patches from\nthe others.\n\n> +\n> +* Frequent contributors, subsystem maintainers, etc. may use push/pull\n> +  to send their changes upstream.\n\n?\n\nMaybe:\n\n* (Trusted) Downstreams act like the Upstreams but publish their\nchanges in their own repository.\n> +\n> +* The rest -- typically anyone more than one or two levels away from the\n> +  main maintainer -- send patches by mail.\n> +\n> +None of these boundaries are sharp, so find out what works best for\n> +you.\n> +\n> +\n> +Push/pull\n> +~~~~~~~~~\n> +\n> +There are three main tools that can be used for this:\n> +\n> +* linkgit:git-push[1] copies your branches to a remote repository,\n> +  usually to one that can be read by all involved parties;\n> +\n> +* linkgit:git-fetch[1] that copies remote branches to your repository;\n> +  and\n> +\n> +* linkgit:git-pull[1] that is fetch and merge in one go.\n> +\n> +Note the last point.  Do 'not' use 'git-pull' unless you actually want\n> +to merge the remote branch.\n\nNo need to repeat what is explained in the tutorial.\n\n> +\n> +Getting changes out is easy:\n> +\n> +.Push/pull: Publishing branches/topics\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git push <remote> <branch>` and tell everyone where they can fetch\n> +from.\n> +=====================================\n> +\n> +You will still have to tell people by other means, such as mail.  (Git\n\ns/tell/inform/\n\n> +provides the linkgit:request-pull[1] to send preformatted pull\n> +requests to upstream maintainers to simplify this task.)\n> +\n\n\n> +If you just want to get the newest copies of the main branches,\n> +staying up to date is easy too:\n> +\n> +.Push/pull: Staying up to date\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +Use `git fetch <remote>` or `git remote update` to stay up to date.\n> +=====================================\n> +\n> +Then simply fork your topic branches from the stable remotes as\n> +explained earlier.\n> +\n\nIn tutorial.txt. And it applies to everybody (upstream, contributors,...)\n\n> +If you are a maintainer and would like to merge other people's topic\n> +branches to the main branches, they will typically send a request to\n> +do so by mail.  Such a request might say\n> +\n> +-------------------------------------\n> +Please pull from\n> +    git://some.server.somewhere/random/repo.git mytopic\n> +-------------------------------------\n> +\n> +In that case, 'git-pull' can do the fetch and merge in one go, as\n> +follows.\n> +\n> +.Push/pull: Merging remote topics\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git pull <url> <branch>`\n> +=====================================\n> +\n\nIn tutorial. I think they are well explained in the tutorial. No need\nto repeat it here. You could just mentions the tools and the recipies.\n\n> +Occasionally, the maintainer may get merge conflicts when he tries to\n> +pull changes from downstream.  In this case, he can ask downstream to\n> +do the merge and resolve the conflicts themselves (perhaps they will\n> +know better how to react).  It is one of the rare cases where\n> +downstream 'should' merge from upstream.\n> +\n> +\n> +format-patch/am\n> +~~~~~~~~~~~~~~~\n> +\n> +If you are a contributor that sends changes upstream in the form of\n> +emails, you should use topic branches as usual (see above).  Then use\n> +linkgit:git-format-patch[1] to generate the corresponding emails\n> +(highly recommended over manually formatting them because it makes the\n> +maintainer's life easier).\n> +\n> +.format-patch/am: Publishing branches/topics\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git format-patch -M upstream..topic` and send out the resulting files.\n> +=====================================\n> +\n> +See the linkgit:git-format-patch[1] manpage for further usage notes.\n> +Also you should be aware that the maintainer may impose further\n> +restrictions, such as \"Signed-off-by\" requirements.\n\nthe further restrictions are not only for git-format-patch users.\n\n> +\n> +If the maintainer tells you that your patch no longer applies to the\n> +current upstream, you will have to rebase your topic (you cannot use a\n> +merge because you cannot format-patch merges):\n> +\n> +.format-patch/am: Keeping topics up to date\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git rebase upstream`\n> +=====================================\n\ngit rebase <upstream>\n\n> +\n> +You can then fix the conflicts during the rebase.  Presumably you have\n> +not published your topic other than by mail, so rebasing it is not a\n> +problem.\n> +\n> +If you receive such a patch (as maintainer, or perhaps reader of the\n\nas a reader\n\n> +mailing list it was sent to), save the mail to a file and use\n> +'git-am':\n> +\n> +.format-patch/am: Publishing branches/topics\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git am < patch`\n> +=====================================\n> +\n> +One feature worth pointing out is the three-way merge, which can help\n> +if you get conflicts because of renames: `git am -3` will use index\n> +information contained in patches to reconstruct a merge base.  See\n> +linkgit:git-am[1] for other options.\n> +\n> +\n> +SEE ALSO\n> +--------\n> +linkgit:gittutorial[7],\n> +linkgit:git-push[1],\n> +linkgit:git-pull[1],\n> +linkgit:git-merge[1],\n> +linkgit:git-rebase[1],\n> +linkgit:git-format-patch[1],\n> +linkgit:git-am[1]\n> +\n> +GIT\n> +---\n> +Part of the linkgit:git[1] suite.\n> --\n\nSanti-\n"},{"id":"91260","messageId":"20080921202620.GG21650@dpotapov.dyndns.org","threadId":"15339","inReplyTo":"1221147585-5695-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: add manpage about workflows","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-09-21T20:26:20Z","receivedAt":"2008-09-21T20:26:20Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Thu, Sep 11, 2008 at 05:39:45PM +0200, Thomas Rast wrote:\n> This attempts to make a manpage about workflows that is both handy to\n> point people at it and as a beginner's introduction.\n\nThank you for your attempt. It is clearly a missing part of the Git\ndocumentation. I have a few comments to it below.\n\n> +SEPARATE CHANGES\n> +----------------\n> +\n> +As a general rule, you should try to split your changes into small\n> +logical steps, and commit each of them.  They should be consistent,\n> +working independently of any later commits, pass the test suite, etc.\n\nI would rather add some explanation why it is a good idea. Something\nlike this:\n\n\"This makes the review process much easier, as well as, makes git bisect\nmuch more useful in finding the cause of regressions.\"\n\n> +\n> +To achieve this, try to commit your new work at least every couple\n> +hours.  You can always go back and edit the commits with `git rebase\n> +--interactive` to further improve the history before you publish it.\n\nI like the idea of this paragraph but not its wording. Maybe this will\nbe better (just a variant):\n\n\"To achieve this, try to split your work in small steps from the very\nbeginning. It is always easier to squash a few commits together than\nsplitting one big commit into a few.  Don't be afraid making steps too\nsmall or that they are not perfect yet. You can always go back later and\nedit the commits with `git rebase --interactive` before you publish it.\"\n\n> +\n> +MANAGING BRANCHES\n> +-----------------\n> +\n> +In the following, we will assume there are 'developers', 'testers' and\n> +'users'.  Even if the \"Testers\" are actually an automated test suite\n> +and all \"Users\" are developers themselves, try to think in these terms\n> +as you follow a software change through its life cycle.\n> +\n> +Usually a change evolves in a few steps:\n> +\n> +* The developers implement a few iterations until it \"seems to work\".\n> +\n> +* The testers play with it, report bugs, test the fixes, eventually\n> +  clearing the change for stable releases.\n\nPerhaps, the above two points are the most controversial in my opinion.\n\nFirst, I would expect developers to implement a few iterations until\nit (their work) passes the automated test suite and peer review. Only\nthen their work is merged into 'next' (or into a similar branch, which\nconstitute that this series is published now).\n\nSecond, I am not sure what you meant by testers clears changes for\nstable releases, especially after you stated \"Testers\" may be an\nautomated test suite.  Whether some change is included is always a\nconscious decision of the project maintainer. The fact that some change\nhas passed all tests successfully only clears it for including into\n'next'.\n\n> +\n> +* As the users work with the new feature, they report bugs which will\n> +  have to be fixed.\n> +\n> +In the following sections we discuss some problems that arise from\n> +such a \"change flow\", and how to solve them with Git.\n> +\n> +We consider a fictional project with (supported) stable branch\n> +'maint', main testing/development branch 'master' and \"bleeding edge\"\n> +branch 'next'.  We collectively call these three branches 'main\n> +branches'.\n\nThe idea of 'next' is not obvious from your above explanation. When I\nstarted to learn how Git workflow works, I read something like above\nand was very puzzled what is the purpose of having two development\nbranches: 'master' and 'next'. Only later I realized that it is\nnecessary to give flexibility in making decisions of what should be\nincluded in the next stable release and what may need more \"cooking\"\nto prove their reliability and usefulness.\n\n> +\n> +\n> +Merging upwards\n> +~~~~~~~~~~~~~~~\n> +\n> +Since Git is quite good at merges, one should try to use them to\n> +propagate changes.  For example, if a bug is fixed, you would want to\n> +apply the corresponding fix to all main branches.\n\nThe first and second sentences are a bit disconnected here. I would\nrather write the second one like this: \"An example of such a change\ncan be a bug fix, which should be applied to all main branches.\"\n\nAnother thing is that I am not sure that the provided reason for doing\nso (\"Git is quite good at merges\") is good enough. It can be said that\nGit is quite good at cherry-picking too. Yet, we use merge, because it\nallows to deal with large number of patches easier. Merge can be easily\nvisualized and understood as every merge point means that all changes\nbefore it are included. However, to being able use merge, the developer\nhas to start from the oldest branch that will include this change. This\nis a clear restriction over the anarchic nature of cherry-picking (where\nyou can introduce a change to an arbitrary branch and then cherry-pick\nto others), but it pays off in the long run by better maintainability of\nthe project. Thus the recommended practice is a strong preference to use\nmerge over cherry-picking. It does not mean that cherry-picking should\nbe completely excluded. Occasionally, it may be useful.\n\n> +\n> +A quick moment of thought reveals that you cannot do this by merging\n> +\"downwards\" to older releases, since that would merge 'all' changes.\n\nIMHO, expressions such as \"a quick moment of thought reveals...\" is\nmore suitable for blogs than for serious documentation.\n\n> +Hence the following:\n> +\n> +.Merge upwards\n> +[caption=\"Rule: \"]\n> +=====================================\n> +Always commit your fixes to the oldest supported branch that require\n> +them.  Then (periodically) merge the main branches upwards into each\n> +other.\n> +=====================================\n\nPerhaps, it is worth to note here that a non-trivial fixes can be\nimplemented as topic branches, which starts from the oldest branch\nthat needs them.\n\n> +\n> +This gives a very controlled flow of fixes.  If you notice that you\n> +have applied a fix to e.g. 'master' that is also required in 'maint',\n> +you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n> +downwards.  This will happen a few times and is nothing to worry about\n> +unless you do it all the time.\n> +\n> +\n> +Topic branches\n> +~~~~~~~~~~~~~~\n> +\n> +Any nontrivial feature will require several patches to implement, and\n> +may get extra bugfixes or improvements during its lifetime.  If all\n> +such commits were in one long linear history chain (e.g. if they were\n> +all committed directly to, 'master'), it becomes very hard to see how\n> +they belong together.\n\nThere is a far more important reason to use topic branches than ecstatic\npleasure from being able to see related changes grouped together in the\nhistory. The main reason to use topic branches is to facilitate parallel\ndevelopment. Though the idea that anyone commit to the main development\nbranch ('master') is very appealing due to its simplicity, it leads to\nproblems down the road. Namely, not all good sounding ideas turns out\ngood in reality.\n\nIn the workflow where everyone commits to 'master' there are only two\nways to deal with that. The first approach is not let developers to\ncommit their changes until they have completely finished their work\nand passed all tests and code-review, and their work deemed important\nenough to be included in the next feature release. The second approach\nis to commit their work in progress in the hope that it will succeed,\nand if not then to rollback changes.\n\nNeither of these two approaches is satisfactory, especially for large\nprojects. The first approach means that developers are under a great\nstress due to inability to save their work in progress, they accumulate\na huge patch, which is very difficult to review, often include some\nother changes unrelated to the stated goal, and makes the history of\nthe project nearly useless for bisecting (linkgit:git-bisect[1]) when\nit comes to finding a regression. The second approach means that the\nproject history gets contaminating with a great number of changes that\neventually didn't work out. Moreover, reverting changes that are belong\nto some failed work may extremely difficult as other changes intervene\nwith them. So, this reverting is hardly ever done completely in practice\nif it is done at all, which leads to a lot of garbage in the source\ncode. Obviously, the history of this project is completely useless for\nbisecting as many commits do not really work if they are compiled at\nall. Also, this approach leads to an extremely long stabilization period\nas it is determined by the time when slowest going work will be in good\nshape for release.\n\nUsing topic branches immune to that problem as feature are included\ninto 'master' when they are ready. Moreover, feature branches unless\nthey are \"publish\" can go through cycles of testing, review, and\ninteractive rebasing to edit and improve individual commits. Thus\nthe finally published history is clean and easy to bisect.\n\n\n> +\n> +Roughly speaking, there are two important workflows.\n\nI think it would make sense to name them here.\n\n> Their\n> +distinguishing mark is whether they can be used to propagate merges.\n\nPerhaps, it would be better to say:\n\"They are distinguished by the ability to propagate merges.\"\n\nHowever, this is not the only distinguish between them. Besides, I am\nnot sure how this one is connected with the rest of the paragraph:\n\n> +Medium to large projects will typically employ some mixture of the\n> +two:\n> +\n> +* \"Upstream\" in the most general sense 'pushes' changes to the\n> +  repositor(ies) holding the main history.\n\nIMHO, it would be better:\ns/the main history/the official history of the project/\n\n> Everyone can 'pull' from there to stay up to date.\n\nWould that entrench the wrong idea that one needs to do 'pull'\nhabitually? And the habitual 'pull' results in habitual 'merge'.\n\n> +\n> +* Frequent contributors, subsystem maintainers, etc. may use push/pull\n> +  to send their changes upstream.\n\nThis is nitpicking, but you cannot use 'pull' to send changes. However,\nI suppose you meant to make your repository available for other people\nto pull from it.\n\n> +\n> +* The rest -- typically anyone more than one or two levels away from the\n> +  main maintainer -- send patches by mail.\n\nAfter reading \"mixture of the two:\" above, I expected these two being named,\nbut instead I can see three points. So, it is confusing.\n\n> +If the maintainer tells you that your patch no longer applies to the\n> +current upstream, you will have to rebase your topic (you cannot use a\n> +merge because you cannot format-patch merges):\n> +\n> +.format-patch/am: Keeping topics up to date\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git rebase upstream`\n> +=====================================\n\nMaybe, git pull --rebase is better advice here as it will also fetch\nthe latest changes from the upstream.\n\n> +\n> +You can then fix the conflicts during the rebase.  Presumably you have\n> +not published your topic other than by mail, so rebasing it is not a\n> +problem.\n> +\n> +If you receive such a patch (as maintainer, or perhaps reader of the\n> +mailing list it was sent to), save the mail to a file and use\n> +'git-am':\n> +\n> +.format-patch/am: Publishing branches/topics\n> +[caption=\"Recipe: \"]\n> +=====================================\n> +`git am < patch`\n> +=====================================\n> +\n> +One feature worth pointing out is the three-way merge, which can help\n> +if you get conflicts because of renames:\n\nCould it not be any other reason besides renames? Maybe it is better to\ndrop \"because of renames\" here.\n\n> `git am -3` will use index\n> +information contained in patches\n\nBecause the word \"index\" is often used in Git in the different meaning\n(a.k.a cache), I would re-write this sentence to avoid confusion as:\n\n\"`git am -3` will use information contained in index lines of patches\"\n\n> to reconstruct a merge base.  See\n\nIf I did not know how git am -3 works, reading this would make me think\nthat git am somehow manage to figure out a common ancestor (commit),\nwhile it uses index lines of the patch to learn the identity of the blob\nthat was used as the starting point to create the patch, and if this\nblob is available locally, git am -3 performs 3-way merge.\n\nSo, \"reconstruct a merge base\" is hardly appropriate here.\n\n\nDmitry\n"},{"id":"91958","messageId":"200809301805.30753.trast@student.ethz.ch","threadId":"15339","inReplyTo":"20080921202620.GG21650@dpotapov.dyndns.org","subject":"Re: [RFC PATCH] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-30T16:05:22Z","receivedAt":"2008-09-30T16:05:22Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"As a quick status update, mostly to show that I haven't forgotten\nabout this topic:\n\nThanks Santi and Dmitry for your comments.  You have raised some very\ngood points, and I attempted to fix these issues.\n\nUnfortunately, in some places I got stuck trying to work out good\nexplanations for the workings of git.git, and some of the newer\nrearrangements left the lead of \"Merging branches\" in a dire state.\nI'll see if I can find a good solution myself, but suggestions would\nbe welcome in any case.  The WIP text is below, and I'll follow up\nwith an interdiff to the last version.\n\n- Thomas\n\n--- 8< ---\ngitworkflows(7)\n===============\n\nNAME\n----\ngitworkflows - An overview of recommended workflows with git\n\nSYNOPSIS\n--------\ngit *\n\n\nDESCRIPTION\n-----------\n\nThis document attempts to write down and motivate some of the workflow\nelements used for `git.git` itself.  Many ideas apply in general,\nthough the full workflow is rarely required for smaller projects with\nfewer people involved.\n\nWe formulate a set of 'rules' for quick reference, while the prose\ntries to motivate each of them.  Do not always take them literally;\nyou should value good reasons for your actions higher than manpages\nsuch as this one.\n\n\nSEPARATE CHANGES\n----------------\n\nAs a general rule, you should try to split your changes into small\nlogical steps, and commit each of them.  They should be consistent,\nworking independently of any later commits, pass the test suite, etc.\nThis makes the review process much easier, and the history much more\nuseful for later inspection and analysis, for example with\nlinkgit:git-blame[1] and linkgit:git-bisect[1].\n\nTo achieve this, try to split your work into small steps from the very\nbeginning. It is always easier to squash a few commits together than\nto split one big commit into several.  Don't be afraid of making too\nsmall or imperfect steps along the way. You can always go back later\nand edit the commits with `git rebase \\--interactive` before you\npublish them.\n\n\nMANAGING BRANCHES\n-----------------\n\nUsually a feature (or other change) evolves in stages: it \"graduates\"\nfrom patch to the testing branches and on to stable releases.  During\nthis process, it may require fixes or improvements.  XXX terrible\nparagraph XXX\n\nMerges (as opposed to cherry-picks, see below) greatly simplify\nhandling large numbers of commits, so a scalable workflow needs to use\nmerges.  Fortunately Git is very good at merging.\n\nXXX non sequitur XXX\nIn the following sections we discuss some problems that arise from\nsuch a \"change flow\", and how to solve them with Git.\n\n\nGraduation\n~~~~~~~~~~\n\nAs a given feature goes from experimental to stable, it also\n\"graduates\" between the corresponding branches of the software.\n`git.git` uses the following 'main branches':\n\n* 'master' tracks the commits that should go into the next release;\n\n* 'maint' tracks the commits that should go into the next \"maintenance\n  release\", i.e., update of the last released stable version; and\n\n* 'next' is intended as a testing branch for people who like to use\n  more experimental stuff.\n\nThere is a fourth official branch that is used slightly differently:\n\n* 'pu' (proposed updates) is an integration branch for things that are\n  not quite ready for inclusion yet (see \"Integration Branches\"\n  below).\n\nConceptually, the feature enters at an unstable branch (usually 'next'\nor 'pu'), and \"graduates\" to 'master' for the next release once it is\nconsidered stable enough.\n\n\nMerging upwards\n~~~~~~~~~~~~~~~\n\nAs explained above, features conceptually \"graduate downwards\" to\nolder releases.  This cannot be done by actually merging downwards,\nhowever, since that would merge 'all' changes on the unstable branch\ninto the stable one.  Hence the following:\n\n.Merge upwards\n[caption=\"Rule: \"]\n=====================================\nAlways commit your fixes to the oldest supported branch that require\nthem.  Then (periodically) merge the main branches upwards into each\nother.\n=====================================\n\nThis gives a very controlled flow of fixes.  If you notice that you\nhave applied a fix to e.g. 'master' that is also required in 'maint',\nyou will need to cherry-pick it (using linkgit:git-cherry-pick[1])\ndownwards.  This will happen a few times and is nothing to worry about\nunless you do it very frequently.\n\n\nTopic branches\n~~~~~~~~~~~~~~\n\nAny nontrivial feature will require several patches to implement, and\nmay get extra bugfixes or improvements during its lifetime.\n\nCommitting everything directly on the main branches leads to many\nproblems: Bad commits cannot be undone, so they must be reverted one\nby one, which creates confusing histories and further error potential\nwhen you forget to revert part of a group of changes.  Working in\nparallel mixes up the changes, creating further confusion.\n\nThe key concept here is \"topic branches\".  The name is pretty self\nexplanatory, with a caveat that comes from the \"merge upwards\" rule\nabove:\n\n.Topic branches\n[caption=\"Rule: \"]\n=====================================\nMake a side branch for every topic (feature, bugfix, ...). Fork it off\nat the oldest main branch that you will eventually want to merge it\ninto.\n=====================================\n\nMany things can then be done very naturally:\n\n* To get the feature/bugfix into a main branch, simply merge it.  If\n  the topic has evolved further in the meantime, merge again.\n\n* If you find you need new features from the branch 'other' to continue\n  working on your topic, merge 'other' to 'topic'.  (However, do not\n  do this \"just habitually\", see below.)\n\n* If you find you forked off the wrong branch and want to move it\n  \"back in time\", use linkgit:git-rebase[1].\n\nNote that the last two points clash: a topic that has been merged\nelsewhere should not be rebased.  See the section on RECOVERING FROM\nUPSTREAM REBASE in linkgit:git-rebase[1].\n\nWe should point out that \"habitually\" (regularly for no real reason)\nmerging a main branch into your topics -- and by extension, merging\nanything upstream into anything downstream on a regular basis -- is\nfrowned upon:\n\n.Merge to downstream only at well-defined points\n[caption=\"Rule: \"]\n=====================================\nDo not merge to downstream except:\n\n* with a good reason: upstream API changes affect your branch; your\n  branch no longer merges to upstream cleanly; etc.\n\n* at well-defined points such as when an upstream release has been tagged.\n=====================================\n\nOtherwise, the many resulting small merges will greatly clutter up\nhistory.  Anyone who later investigates the history of a file will\nhave to find out whether that merge affected the topic in development.\nAn upstream might even inadvertently be merged into a \"more stable\"\nbranch.  And so on.\n\n\nIntegration branches\n~~~~~~~~~~~~~~~~~~~~\n\nIf you followed the last paragraph, you will now have many small topic\nbranches, and occasionally wonder how they interact.  Perhaps the\nresult of merging them does not even work?  But on the other hand, we\nwant to avoid merging them anywhere \"stable\" because such merges\ncannot easily be undone.\n\nThe solution, of course, is to make a merge that we can undo: merge\ninto a throw-away branch.\n\n.Integration branches\n[caption=\"Rule: \"]\n=====================================\nTo test the interaction of several topics, merge them into a\nthrow-away branch.\n=====================================\n\nIf you make it (very) clear that this branch is going to be deleted\nright after the testing, you can even publish this branch, for example\nto give the testers a chance to work with it, or other developers a\nchance to see if their in-progress work will be compatible.  `git.git`\nhas such an official integration branch called 'pu'.  You must never\nbase any work on such a throw-away branch!\n\n\nSHARING WORK\n------------\n\nAfter the last section, you should know how to manage topics.  In\ngeneral, you will not be the only person working on the project, so\nyou will have to share your work.\n\nRoughly speaking, there are two important workflows: push/pull and\nformat-patch/am.  The important difference is that push/pull can\npropagate merges, while format-patch cannot.  Medium to large projects\nwill typically employ some mixture of the two:\n\n* \"Upstream\" in the most general sense 'pushes' changes to the\n  repositor(ies) holding the official history of the project.\n  Everyone can 'fetch' from there to stay up to date.\n\n* Frequent contributors, subsystem maintainers, etc. may push to a\n  public repository to make their changes available to upstream.\n\n* The rest -- typically anyone more than one or two levels away from the\n  main maintainer -- send patches by mail.\n\nNone of these boundaries are sharp, so find out what works best for\nyou.\n\n\nPush/pull\n~~~~~~~~~\n\nThere are three main tools that can be used for this:\n\n* linkgit:git-push[1] copies your branches to a remote repository,\n  usually to one that can be read by all involved parties;\n\n* linkgit:git-fetch[1] that copies remote branches to your repository;\n  and\n\n* linkgit:git-pull[1] that does fetch and merge in one go.\n\nNote the last point.  Do 'not' use 'git-pull' unless you actually want\nto merge the remote branch.\n\nGetting changes out is easy:\n\n.Push/pull: Publishing branches/topics\n[caption=\"Recipe: \"]\n=====================================\n`git push <remote> <branch>` and tell everyone where they can fetch\nfrom.\n=====================================\n\nYou will still have to tell people by other means, such as mail.  (Git\nprovides the linkgit:request-pull[1] to send preformatted pull\nrequests to upstream maintainers to simplify this task.)\n\nIf you just want to get the newest copies of the main branches,\nstaying up to date is easy too:\n\n.Push/pull: Staying up to date\n[caption=\"Recipe: \"]\n=====================================\nUse `git fetch <remote>` or `git remote update` to stay up to date.\n=====================================\n\nThen simply fork your topic branches from the stable remotes as\nexplained earlier.\n\nIf you are a maintainer and would like to merge other people's topic\nbranches to the main branches, they will typically send a request to\ndo so by mail.  Such a request might say\n\n-------------------------------------\nPlease pull from\n    git://some.server.somewhere/random/repo.git mytopic\n-------------------------------------\n\nIn that case, 'git-pull' can do the fetch and merge in one go, as\nfollows.\n\n.Push/pull: Merging remote topics\n[caption=\"Recipe: \"]\n=====================================\n`git pull <url> <branch>`\n=====================================\n\nOccasionally, the maintainer may get merge conflicts when he tries to\npull changes from downstream.  In this case, he can ask downstream to\ndo the merge and resolve the conflicts themselves (perhaps they will\nknow better how to resolve them).  It is one of the rare cases where\ndownstream 'should' merge from upstream.\n\n\nformat-patch/am\n~~~~~~~~~~~~~~~\n\nIf you are a contributor that sends changes upstream in the form of\nemails, you should use topic branches as usual (see above).  Then use\nlinkgit:git-format-patch[1] to generate the corresponding emails\n(highly recommended over manually formatting them because it makes the\nmaintainer's life easier).\n\n.format-patch/am: Publishing branches/topics\n[caption=\"Recipe: \"]\n=====================================\n* `git format-patch -M upstream..topic` to turn them into preformatted\n  patch files\n* `git send-email --to=<recipient> <patches>`\n=====================================\n\nSee the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\nmanpages for further usage notes.  Also you should be aware that the\nmaintainer may impose further restrictions, such as \"Signed-off-by\"\nrequirements.\n\nIf the maintainer tells you that your patch no longer applies to the\ncurrent upstream, you will have to rebase your topic (you cannot use a\nmerge because you cannot format-patch merges):\n\n.format-patch/am: Keeping topics up to date\n[caption=\"Recipe: \"]\n=====================================\n`git pull --rebase <url> <branch>`\n=====================================\n\nYou can then fix the conflicts during the rebase.  Presumably you have\nnot published your topic other than by mail, so rebasing it is not a\nproblem.\n\nIf you receive such a patch (as maintainer, or perhaps as a reader of\nthe mailing list it was sent to), save the mail to a file and use\n'git-am':\n\n.format-patch/am: Publishing branches/topics\n[caption=\"Recipe: \"]\n=====================================\n`git am < patch`\n=====================================\n\nOne feature worth pointing out is the three-way merge, which can help\nif you get conflicts: `git am -3` will use index information contained\nin patches to figure out the merge base.  See linkgit:git-am[1] for\nother options.\n\n\nSEE ALSO\n--------\nlinkgit:gittutorial[7],\nlinkgit:git-push[1],\nlinkgit:git-pull[1],\nlinkgit:git-merge[1],\nlinkgit:git-rebase[1],\nlinkgit:git-format-patch[1],\nlinkgit:git-send-email[1],\nlinkgit:git-am[1]\n\nGIT\n---\nPart of the linkgit:git[1] suite.\n\n\n"},{"id":"91959","messageId":"200809301807.15932.trast@student.ethz.ch","threadId":"15339","inReplyTo":"200809301805.30753.trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-09-30T16:07:13Z","receivedAt":"2008-09-30T16:07:13Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"I wrote:\n> The WIP text is below, and I'll follow up with an interdiff to the\n> last version.\n\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nindex b4b43da..87c2270 100644\n--- a/Documentation/gitworkflows.txt\n+++ b/Documentation/gitworkflows.txt\n@@ -13,13 +13,15 @@ git *\n DESCRIPTION\n -----------\n \n-This tutorial gives a brief overview of workflows recommended to\n-use, and collaborate with, Git.\n+This document attempts to write down and motivate some of the workflow\n+elements used for `git.git` itself.  Many ideas apply in general,\n+though the full workflow is rarely required for smaller projects with\n+fewer people involved.\n \n-While the prose tries to motivate each of them, we formulate a set of\n-'rules' for quick reference.  Do not always take them literally; you\n-should value good reasons higher than following a random manpage to\n-the letter.\n+We formulate a set of 'rules' for quick reference, while the prose\n+tries to motivate each of them.  Do not always take them literally;\n+you should value good reasons for your actions higher than manpages\n+such as this one.\n \n \n SEPARATE CHANGES\n@@ -28,49 +30,68 @@ SEPARATE CHANGES\n As a general rule, you should try to split your changes into small\n logical steps, and commit each of them.  They should be consistent,\n working independently of any later commits, pass the test suite, etc.\n+This makes the review process much easier, and the history much more\n+useful for later inspection and analysis, for example with\n+linkgit:git-blame[1] and linkgit:git-bisect[1].\n \n-To achieve this, try to commit your new work at least every couple\n-hours.  You can always go back and edit the commits with `git rebase\n---interactive` to further improve the history before you publish it.\n+To achieve this, try to split your work into small steps from the very\n+beginning. It is always easier to squash a few commits together than\n+to split one big commit into several.  Don't be afraid of making too\n+small or imperfect steps along the way. You can always go back later\n+and edit the commits with `git rebase \\--interactive` before you\n+publish them.\n \n \n MANAGING BRANCHES\n -----------------\n \n-In the following, we will assume there are 'developers', 'testers' and\n-'users'.  Even if the \"Testers\" are actually an automated test suite\n-and all \"Users\" are developers themselves, try to think in these terms\n-as you follow a software change through its life cycle.\n+Usually a feature (or other change) evolves in stages: it \"graduates\"\n+from patch to the testing branches and on to stable releases.  During\n+this process, it may require fixes or improvements.  XXX terrible\n+paragraph XXX\n \n-Usually a change evolves in a few steps:\n+Merges (as opposed to cherry-picks, see below) greatly simplify\n+handling large numbers of commits, so a scalable workflow needs to use\n+merges.  Fortunately Git is very good at merging.\n \n-* The developers implement a few iterations until it \"seems to work\".\n+XXX non sequitur XXX\n+In the following sections we discuss some problems that arise from\n+such a \"change flow\", and how to solve them with Git.\n \n-* The testers play with it, report bugs, test the fixes, eventually\n-  clearing the change for stable releases.\n \n-* As the users work with the new feature, they report bugs which will\n-  have to be fixed.\n+Graduation\n+~~~~~~~~~~\n \n-In the following sections we discuss some problems that arise from\n-such a \"change flow\", and how to solve them with Git.\n+As a given feature goes from experimental to stable, it also\n+\"graduates\" between the corresponding branches of the software.\n+`git.git` uses the following 'main branches':\n+\n+* 'master' tracks the commits that should go into the next release;\n+\n+* 'maint' tracks the commits that should go into the next \"maintenance\n+  release\", i.e., update of the last released stable version; and\n \n-We consider a fictional project with (supported) stable branch\n-'maint', main testing/development branch 'master' and \"bleeding edge\"\n-branch 'next'.  We collectively call these three branches 'main\n-branches'.\n+* 'next' is intended as a testing branch for people who like to use\n+  more experimental stuff.\n+\n+There is a fourth official branch that is used slightly differently:\n+\n+* 'pu' (proposed updates) is an integration branch for things that are\n+  not quite ready for inclusion yet (see \"Integration Branches\"\n+  below).\n+\n+Conceptually, the feature enters at an unstable branch (usually 'next'\n+or 'pu'), and \"graduates\" to 'master' for the next release once it is\n+considered stable enough.\n \n \n Merging upwards\n ~~~~~~~~~~~~~~~\n \n-Since Git is quite good at merges, one should try to use them to\n-propagate changes.  For example, if a bug is fixed, you would want to\n-apply the corresponding fix to all main branches.\n-\n-A quick moment of thought reveals that you cannot do this by merging\n-\"downwards\" to older releases, since that would merge 'all' changes.\n-Hence the following:\n+As explained above, features conceptually \"graduate downwards\" to\n+older releases.  This cannot be done by actually merging downwards,\n+however, since that would merge 'all' changes on the unstable branch\n+into the stable one.  Hence the following:\n \n .Merge upwards\n [caption=\"Rule: \"]\n@@ -84,27 +105,31 @@ This gives a very controlled flow of fixes.  If you notice that you\n have applied a fix to e.g. 'master' that is also required in 'maint',\n you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n downwards.  This will happen a few times and is nothing to worry about\n-unless you do it all the time.\n+unless you do it very frequently.\n \n \n Topic branches\n ~~~~~~~~~~~~~~\n \n Any nontrivial feature will require several patches to implement, and\n-may get extra bugfixes or improvements during its lifetime.  If all\n-such commits were in one long linear history chain (e.g., if they were\n-all committed directly to 'master'), it becomes very hard to see how\n-they belong together.\n+may get extra bugfixes or improvements during its lifetime.\n+\n+Committing everything directly on the main branches leads to many\n+problems: Bad commits cannot be undone, so they must be reverted one\n+by one, which creates confusing histories and further error potential\n+when you forget to revert part of a group of changes.  Working in\n+parallel mixes up the changes, creating further confusion.\n \n The key concept here is \"topic branches\".  The name is pretty self\n-explanatory, with a minor caveat that comes from the \"merge upwards\"\n-rule above:\n+explanatory, with a caveat that comes from the \"merge upwards\" rule\n+above:\n \n .Topic branches\n [caption=\"Rule: \"]\n =====================================\n-Make a side branch for every topic. Fork it off at the oldest main\n-branch that you will eventually want to merge it into.\n+Make a side branch for every topic (feature, bugfix, ...). Fork it off\n+at the oldest main branch that you will eventually want to merge it\n+into.\n =====================================\n \n Many things can then be done very naturally:\n@@ -112,7 +137,7 @@ Many things can then be done very naturally:\n * To get the feature/bugfix into a main branch, simply merge it.  If\n   the topic has evolved further in the meantime, merge again.\n \n-* If you find you need new features from an 'other' branch to continue\n+* If you find you need new features from the branch 'other' to continue\n   working on your topic, merge 'other' to 'topic'.  (However, do not\n   do this \"just habitually\", see below.)\n \n@@ -133,16 +158,17 @@ frowned upon:\n =====================================\n Do not merge to downstream except:\n \n-* with a good reason (such as upstream API changes that affect you), or\n+* with a good reason: upstream API changes affect your branch; your\n+  branch no longer merges to upstream cleanly; etc.\n \n * at well-defined points such as when an upstream release has been tagged.\n =====================================\n \n Otherwise, the many resulting small merges will greatly clutter up\n history.  Anyone who later investigates the history of a file will\n-have to find out whether that merge affected the topic in\n-development.  Linus hates it.  An upstream might even inadvertently be\n-merged into a \"more stable\" branch.  And so on.\n+have to find out whether that merge affected the topic in development.\n+An upstream might even inadvertently be merged into a \"more stable\"\n+branch.  And so on.\n \n \n Integration branches\n@@ -167,7 +193,9 @@ throw-away branch.\n If you make it (very) clear that this branch is going to be deleted\n right after the testing, you can even publish this branch, for example\n to give the testers a chance to work with it, or other developers a\n-chance to see if their in-progress work will be compatible.\n+chance to see if their in-progress work will be compatible.  `git.git`\n+has such an official integration branch called 'pu'.  You must never\n+base any work on such a throw-away branch!\n \n \n SHARING WORK\n@@ -177,17 +205,17 @@ After the last section, you should know how to manage topics.  In\n general, you will not be the only person working on the project, so\n you will have to share your work.\n \n-Roughly speaking, there are two important workflows.  Their\n-distinguishing mark is whether they can be used to propagate merges.\n-Medium to large projects will typically employ some mixture of the\n-two:\n+Roughly speaking, there are two important workflows: push/pull and\n+format-patch/am.  The important difference is that push/pull can\n+propagate merges, while format-patch cannot.  Medium to large projects\n+will typically employ some mixture of the two:\n \n * \"Upstream\" in the most general sense 'pushes' changes to the\n-  repositor(ies) holding the main history.  Everyone can 'pull' from\n-  there to stay up to date.\n+  repositor(ies) holding the official history of the project.\n+  Everyone can 'fetch' from there to stay up to date.\n \n-* Frequent contributors, subsystem maintainers, etc. may use push/pull\n-  to send their changes upstream.\n+* Frequent contributors, subsystem maintainers, etc. may push to a\n+  public repository to make their changes available to upstream.\n \n * The rest -- typically anyone more than one or two levels away from the\n   main maintainer -- send patches by mail.\n@@ -291,15 +319,15 @@ merge because you cannot format-patch merges):\n .format-patch/am: Keeping topics up to date\n [caption=\"Recipe: \"]\n =====================================\n-`git rebase upstream`\n+`git pull --rebase <url> <branch>`\n =====================================\n \n You can then fix the conflicts during the rebase.  Presumably you have\n not published your topic other than by mail, so rebasing it is not a\n problem.\n \n-If you receive such a patch (as maintainer, or perhaps reader of the\n-mailing list it was sent to), save the mail to a file and use\n+If you receive such a patch (as maintainer, or perhaps as a reader of\n+the mailing list it was sent to), save the mail to a file and use\n 'git-am':\n \n .format-patch/am: Publishing branches/topics\n@@ -309,9 +337,9 @@ mailing list it was sent to), save the mail to a file and use\n =====================================\n \n One feature worth pointing out is the three-way merge, which can help\n-if you get conflicts because of renames: `git am -3` will use index\n-information contained in patches to reconstruct a merge base.  See\n-linkgit:git-am[1] for other options.\n+if you get conflicts: `git am -3` will use index information contained\n+in patches to figure out the merge base.  See linkgit:git-am[1] for\n+other options.\n \n \n SEE ALSO\n"},{"id":"92041","messageId":"adf1fd3d0810010254k5961b182ked9acda55e2aa57c@mail.gmail.com","threadId":"15339","inReplyTo":"200809301805.30753.trast@student.ethz.ch","subject":"Re: [RFC PATCH] Documentation: add manpage about workflows","fromName":"Santi Béjar","fromEmail":"santi@agolina.net","sentAt":"2008-10-01T09:54:35Z","receivedAt":"2008-10-01T09:54:35Z","isPatch":true,"sender":{"key":"santi@agolina.net","avatar":null},"body":"On Tue, Sep 30, 2008 at 6:05 PM, Thomas Rast <trast@student.ethz.ch> wrote:\n> As a quick status update, mostly to show that I haven't forgotten\n> about this topic:\n>\n> Thanks Santi and Dmitry for your comments.  You have raised some very\n> good points, and I attempted to fix these issues.\n\nThanks for you document.\n\n>\n> Unfortunately, in some places I got stuck trying to work out good\n> explanations for the workings of git.git, and some of the newer\n> rearrangements left the lead of \"Merging branches\" in a dire state.\n> I'll see if I can find a good solution myself, but suggestions would\n> be welcome in any case.  The WIP text is below, and I'll follow up\n> with an interdiff to the last version.\n>\n> - Thomas\n>\n[...]\n\n>\n> SEPARATE CHANGES\n> ----------------\n>\n> As a general rule, you should try to split your changes into small\n> logical steps, and commit each of them.  They should be consistent,\n> working independently of any later commits, pass the test suite, etc.\n> This makes the review process much easier, and the history much more\n> useful for later inspection and analysis, for example with\n> linkgit:git-blame[1] and linkgit:git-bisect[1].\n>\n> To achieve this, try to split your work into small steps from the very\n> beginning. It is always easier to squash a few commits together than\n> to split one big commit into several.  Don't be afraid of making too\n> small or imperfect steps along the way. You can always go back later\n> and edit the commits with `git rebase \\--interactive` before you\n> publish them.\n>\n\nI know it is against the recommendation but I think it makes sense to\nexplain how you can split big patches testing them as is explained in\ngitlink:git-stash.\n\n[...]\n\n> Graduation\n> ~~~~~~~~~~\n>\n> As a given feature goes from experimental to stable, it also\n> \"graduates\" between the corresponding branches of the software.\n> `git.git` uses the following 'main branches':\n>\n> * 'master' tracks the commits that should go into the next release;\n>\n> * 'maint' tracks the commits that should go into the next \"maintenance\n>  release\", i.e., update of the last released stable version; and\n\nThe \"logical\" order would be 'maint', 'master', 'next', 'pu', each one\nshould fast-forward to the next one.\n\n>\n> * 'next' is intended as a testing branch for people who like to use\n>  more experimental stuff.\n\nThe key point is not \"more experimental stuff\", but 'master' material\nbut not stable enough.\n\n[...]\n\n> Integration branches\n> ~~~~~~~~~~~~~~~~~~~~\n>\n> If you followed the last paragraph, you will now have many small topic\n> branches, and occasionally wonder how they interact.  Perhaps the\n> result of merging them does not even work?  But on the other hand, we\n> want to avoid merging them anywhere \"stable\" because such merges\n> cannot easily be undone.\n>\n> The solution, of course, is to make a merge that we can undo: merge\n> into a throw-away branch.\n>\n> .Integration branches\n> [caption=\"Rule: \"]\n> =====================================\n> To test the interaction of several topics, merge them into a\n> throw-away branch.\n> =====================================\n>\n> If you make it (very) clear that this branch is going to be deleted\n> right after the testing, you can even publish this branch, for example\n> to give the testers a chance to work with it, or other developers a\n> chance to see if their in-progress work will be compatible.  `git.git`\n> has such an official integration branch called 'pu'. You must never\n> base any work on such a throw-away branch!\n\nMaybe this last sentence should go in the \"Rule:\".\n\n>\n>\n> SHARING WORK\n> ------------\n>\n> After the last section, you should know how to manage topics.  In\n> general, you will not be the only person working on the project, so\n> you will have to share your work.\n\nSharing work is explained in the tutorials, maybe this section should\nbe about \"distributed workflows\".\n\n>\n> Roughly speaking, there are two important workflows: push/pull and\n> format-patch/am.\n\nA more descriptive name could be the \"merge workflow\" and the \"patch workflow\".\n\n>  The important difference is that push/pull can\n> propagate merges, while format-patch cannot.\n\nLike I said in the other mail, the key is that one preserves the\nhistory (including merges) and the other not. This is what makes\npossible the push/pull workflow, that all the branches should\nfast-forward (and this should be said somewhere)\n\n>  Medium to large projects\n> will typically employ some mixture of the two:\n\ns/:/./\n\nAlthough I think it should be deleted. And what about litle projects?\n\nDifferent roles do uses different workflows:\n\n>\n> * \"Upstream\" in the most general sense 'pushes' changes to the\n>  repositor(ies) holding the official history of the project.\n>  Everyone can 'fetch' from there to stay up to date.\n\ns/pushes/publishes/\ns/fetch/merge/\n\n>\n> * Frequent contributors, subsystem maintainers, etc. may push to a\n>  public repository to make their changes available to upstream.\n\ns/push/publish/\n\nOr:\n\n* Frequent contributors, subsystem maintainers, etc. may publish to a\npublic repository to make their changes available to upstream, or to\ntheir downstreams (acting as upstream to them)\n\n>\n> * The rest -- typically anyone more than one or two levels away from the\n>  main maintainer -- send patches by mail.\n\nIn the \"distributed workflows\" this would be:\n\n* \"Upstream\" merges the branches from subsystem maintainers, applies\nthe 'patches' from others (including themselves) and publishes to the\nmain repository. See link:howto/maintain-git.txt to see how it is done\nin git.git)\n\n* \"Subsystem maintainers\" act as \"upstream\" but publishes to a\ndifferent repository/branch.\n\n* Frequent contributors, etc, publish their changes in another repository.\n\n* The rest ...\n\n>\n> None of these boundaries are sharp, so find out what works best for\n> you.\n>\n>\n> Push/pull\n> ~~~~~~~~~\n>\n> There are three main tools that can be used for this:\n\nSorry, but I don't see the point explaining how to publish the\nbranches, or keep them up to date.\n\n>\n> If you are a maintainer and would like to merge other people's topic\n> branches to the main branches, they will typically send a request to\n> do so by mail.  Such a request might say\n>\n> -------------------------------------\n> Please pull from\n>    git://some.server.somewhere/random/repo.git mytopic\n> -------------------------------------\n>\n> In that case, 'git-pull' can do the fetch and merge in one go, as\n> follows.\n\nOr:\n\nThen, you can merge them with just:\n\n> .Push/pull: Merging remote topics\n> [caption=\"Recipe: \"]\n> =====================================\n> `git pull <url> <branch>`\n> =====================================\n>\n\nUse \"<url> <branch>\" or \"git://some.server.somewhere/random/repo.git\nmytopic\" in the recipies, but not both.\n\n[...]\n\n>\n> format-patch/am\n> ~~~~~~~~~~~~~~~\n\ns/.*/patch workflow/\n\n>\n> If you are a contributor that sends changes upstream in the form of\n> emails, you should use topic branches as usual (see above).  Then use\n> linkgit:git-format-patch[1] to generate the corresponding emails\n> (highly recommended over manually formatting them because it makes the\n> maintainer's life easier).\n>\n> .format-patch/am: Publishing branches/topics\n> [caption=\"Recipe: \"]\n> =====================================\n> * `git format-patch -M upstream..topic` to turn them into preformatted\n>  patch files\n> * `git send-email --to=<recipient> <patches>`\n> =====================================\n>\n> See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\n> manpages for further usage notes.  Also you should be aware that the\n> maintainer may impose further restrictions, such as \"Signed-off-by\"\n> requirements.\n\nThe restrictions and the Signed-off-by also applies to the other workflows.\n\n>\n> If the maintainer tells you that your patch no longer applies to the\n> current upstream, you will have to rebase your topic (you cannot use a\n> merge because you cannot format-patch merges):\n>\n> .format-patch/am: Keeping topics up to date\n> [caption=\"Recipe: \"]\n> =====================================\n> `git pull --rebase <url> <branch>`\n> =====================================\n>\n> You can then fix the conflicts during the rebase.  Presumably you have\n> not published your topic other than by mail, so rebasing it is not a\n> problem.\n>\n> If you receive such a patch (as maintainer, or perhaps as a reader of\n> the mailing list it was sent to), save the mail to a file and use\n> 'git-am':\n>\n> .format-patch/am: Publishing branches/topics\n> [caption=\"Recipe: \"]\n> =====================================\n> `git am < patch`\n> =====================================\n>\n> One feature worth pointing out is the three-way merge, which can help\n> if you get conflicts: `git am -3` will use index information contained\n> in patches to figure out the merge base.  See linkgit:git-am[1] for\n> other options.\n>\n>\n> SEE ALSO\n> --------\n> linkgit:gittutorial[7],\n> linkgit:git-push[1],\n> linkgit:git-pull[1],\n> linkgit:git-merge[1],\n> linkgit:git-rebase[1],\n> linkgit:git-format-patch[1],\n> linkgit:git-send-email[1],\n> linkgit:git-am[1]\n>\n> GIT\n> ---\n> Part of the linkgit:git[1] suite.\n>\n>\n>\n"},{"id":"92666","messageId":"1223552537-6918-1-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"adf1fd3d0810010254k5961b182ked9acda55e2aa57c@mail.gmail.com","subject":"[RFC PATCH v2] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-10-09T11:42:16Z","receivedAt":"2008-10-09T11:42:16Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This attempts to make a manpage about workflows that is both handy to\npoint people at it and as a beginner's introduction.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n\n---\n\n[Apologies if some of the Cc's were sent twice; I got a bounce because\nof non-ASCII headers and was unable to tell if any were delivered.]\n\nLet's try another iteration.\n\nI decided the \"MANAGING BRANCHES\" introduction paragraph was a good\nplace to (finally) mention the points about merge vs. cherry-pick\nraised by Dmitry earlier.\n\nI think I've addressed the other concerns, except for the \"SHARING\nWORK\" section, now renamed to \"DISTRIBUTED WORKFLOWS\":\n\nSanti BÃ©jar wrote:\n> Sorry, but I don't see the point explaining how to publish the\n> branches, or keep them up to date.\n\nI feel it needs to be explained _somewhere_, since pull is designed to\nmake the merge workflow as easy as possible, and then push/fetch are\nneeded to complete the picture (especially so since I'm trying to make\na point of highlighting when not to use pull).  Maybe you can/want to\nconvince me otherwise.\n\nAnd note that push is not explained in gittutorial.txt, only linked.\nIt is explained in gitcore-tutorial.txt, but that says\n\n  However, an understanding of these low-level tools can be helpful if\n  you want to understand git's internals.\n\nin the introduction.  I don't really expect any user to read any\nfurther after hearing that everything in there is \"low-level\".  Maybe\nsome tutorial cleanup would be in order.\n\nOther than that, I'll wait for some more comments, then polish up the\ncommit message and submit \"for real\".\n\nInterdiff will follow, as before.\n\n- Thomas\n\n\n Documentation/Makefile         |    2 +-\n Documentation/gitworkflows.txt |  362 ++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 363 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ded0e40..e33ddcb 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \\\n \tgitrepository-layout.txt\n MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \\\n \tgitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \\\n-\tgitdiffcore.txt\n+\tgitdiffcore.txt gitworkflows.txt\n \n MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)\n MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nnew file mode 100644\nindex 0000000..037ace5\n--- /dev/null\n+++ b/Documentation/gitworkflows.txt\n@@ -0,0 +1,362 @@\n+gitworkflows(7)\n+===============\n+\n+NAME\n+----\n+gitworkflows - An overview of recommended workflows with git\n+\n+SYNOPSIS\n+--------\n+git *\n+\n+\n+DESCRIPTION\n+-----------\n+\n+This document attempts to write down and motivate some of the workflow\n+elements used for `git.git` itself.  Many ideas apply in general,\n+though the full workflow is rarely required for smaller projects with\n+fewer people involved.\n+\n+We formulate a set of 'rules' for quick reference, while the prose\n+tries to motivate each of them.  Do not always take them literally;\n+you should value good reasons for your actions higher than manpages\n+such as this one.\n+\n+\n+SEPARATE CHANGES\n+----------------\n+\n+As a general rule, you should try to split your changes into small\n+logical steps, and commit each of them.  They should be consistent,\n+working independently of any later commits, pass the test suite, etc.\n+This makes the review process much easier, and the history much more\n+useful for later inspection and analysis, for example with\n+linkgit:git-blame[1] and linkgit:git-bisect[1].\n+\n+To achieve this, try to split your work into small steps from the very\n+beginning. It is always easier to squash a few commits together than\n+to split one big commit into several.  Don't be afraid of making too\n+small or imperfect steps along the way. You can always go back later\n+and edit the commits with `git rebase \\--interactive` before you\n+publish them.  You can use `git stash save \\--keep-index` to run the\n+test suite independent of other uncommitted changes; see the EXAMPLES\n+section of linkgit:git-stash[1].\n+\n+\n+MANAGING BRANCHES\n+-----------------\n+\n+There are two main tools that can be used to include changes from one\n+branch on another: linkgit:git-merge[1] and\n+linkgit:git-cherry-pick[1].\n+\n+Merges have many advantages, so we try to solve as many problems as\n+possible with merges alone.  Cherry-picking is still occasionally\n+useful; see \"Merging upwards\" below for an example.\n+\n+Most importantly, merging works at the branch level, while\n+cherry-picking works at the commit level.  This means that a merge can\n+carry over the changes from 1, 10, or 1000 commits with equal ease,\n+which in turn means the workflow scales much better to a large number\n+of contributors (and contributions).  Merges are also easier to\n+understand because a merge commit is a \"promise\" that all changes from\n+all its parents are now included.\n+\n+There is a tradeoff of course: merges require a more careful branch\n+management.  The following subsections discuss the important points.\n+\n+\n+Graduation\n+~~~~~~~~~~\n+\n+As a given feature goes from experimental to stable, it also\n+\"graduates\" between the corresponding branches of the software.\n+`git.git` uses the following 'main branches':\n+\n+* 'maint' tracks the commits that should go into the next \"maintenance\n+  release\", i.e., update of the last released stable version;\n+\n+* 'master' tracks the commits that should go into the next release;\n+\n+* 'next' is intended as a testing branch for topics not stable enough\n+  for master yet.\n+\n+There is a fourth official branch that is used slightly differently:\n+\n+* 'pu' (proposed updates) is an integration branch for things that are\n+  not quite ready for inclusion yet (see \"Integration Branches\"\n+  below).\n+\n+Each of the four branches is usually a direct descendant of the one\n+above it.\n+\n+Conceptually, the feature enters at an unstable branch (usually 'next'\n+or 'pu'), and \"graduates\" to 'master' for the next release once it is\n+considered stable enough.\n+\n+\n+Merging upwards\n+~~~~~~~~~~~~~~~\n+\n+The \"downwards graduation\" discussed above cannot be done by actually\n+merging downwards, however, since that would merge 'all' changes on\n+the unstable branch into the stable one.  Hence the following:\n+\n+.Merge upwards\n+[caption=\"Rule: \"]\n+=====================================\n+Always commit your fixes to the oldest supported branch that require\n+them.  Then (periodically) merge the main branches upwards into each\n+other.\n+=====================================\n+\n+This gives a very controlled flow of fixes.  If you notice that you\n+have applied a fix to e.g. 'master' that is also required in 'maint',\n+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n+downwards.  This will happen a few times and is nothing to worry about\n+unless you do it very frequently.\n+\n+\n+Topic branches\n+~~~~~~~~~~~~~~\n+\n+Any nontrivial feature will require several patches to implement, and\n+may get extra bugfixes or improvements during its lifetime.\n+\n+Committing everything directly on the main branches leads to many\n+problems: Bad commits cannot be undone, so they must be reverted one\n+by one, which creates confusing histories and further error potential\n+when you forget to revert part of a group of changes.  Working in\n+parallel mixes up the changes, creating further confusion.\n+\n+The key concept here is \"topic branches\".  The name is pretty self\n+explanatory, with a caveat that comes from the \"merge upwards\" rule\n+above:\n+\n+.Topic branches\n+[caption=\"Rule: \"]\n+=====================================\n+Make a side branch for every topic (feature, bugfix, ...). Fork it off\n+at the oldest main branch that you will eventually want to merge it\n+into.\n+=====================================\n+\n+Many things can then be done very naturally:\n+\n+* To get the feature/bugfix into a main branch, simply merge it.  If\n+  the topic has evolved further in the meantime, merge again.\n+\n+* If you find you need new features from the branch 'other' to continue\n+  working on your topic, merge 'other' to 'topic'.  (However, do not\n+  do this \"just habitually\", see below.)\n+\n+* If you find you forked off the wrong branch and want to move it\n+  \"back in time\", use linkgit:git-rebase[1].\n+\n+Note that the last two points clash: a topic that has been merged\n+elsewhere should not be rebased.  See the section on RECOVERING FROM\n+UPSTREAM REBASE in linkgit:git-rebase[1].\n+\n+We should point out that \"habitually\" (regularly for no real reason)\n+merging a main branch into your topics -- and by extension, merging\n+anything upstream into anything downstream on a regular basis -- is\n+frowned upon:\n+\n+.Merge to downstream only at well-defined points\n+[caption=\"Rule: \"]\n+=====================================\n+Do not merge to downstream except:\n+\n+* with a good reason: upstream API changes affect your branch; your\n+  branch no longer merges to upstream cleanly; etc.\n+\n+* at well-defined points such as when an upstream release has been tagged.\n+=====================================\n+\n+Otherwise, the many resulting small merges will greatly clutter up\n+history.  Anyone who later investigates the history of a file will\n+have to find out whether that merge affected the topic in development.\n+An upstream might even inadvertently be merged into a \"more stable\"\n+branch.  And so on.\n+\n+\n+Integration branches\n+~~~~~~~~~~~~~~~~~~~~\n+\n+If you followed the last paragraph, you will now have many small topic\n+branches, and occasionally wonder how they interact.  Perhaps the\n+result of merging them does not even work?  But on the other hand, we\n+want to avoid merging them anywhere \"stable\" because such merges\n+cannot easily be undone.\n+\n+The solution, of course, is to make a merge that we can undo: merge\n+into a throw-away branch.\n+\n+.Integration branches\n+[caption=\"Rule: \"]\n+=====================================\n+To test the interaction of several topics, merge them into a\n+throw-away branch.  You must never base any work on such a branch!\n+=====================================\n+\n+If you make it (very) clear that this branch is going to be deleted\n+right after the testing, you can even publish this branch, for example\n+to give the testers a chance to work with it, or other developers a\n+chance to see if their in-progress work will be compatible.  `git.git`\n+has such an official integration branch called 'pu'.\n+\n+\n+DISTRIBUTED WORKFLOWS\n+---------------------\n+\n+After the last section, you should know how to manage topics.  In\n+general, you will not be the only person working on the project, so\n+you will have to share your work.\n+\n+Roughly speaking, there are two important workflows: merge and patch.\n+The important difference is that the merge workflow can propagate full\n+history, including merges, while patches cannot.  Both workflows can\n+be used in parallel: in `git.git`, only subsystem maintainers use\n+the merge workflow, while everyone else sends patches.\n+\n+Note that the maintainer(s) may impose restrictions, such as\n+\"Signed-off-by\" requirements, that all commits/patches submitted for\n+inclusion must adhere to.  Consult your project's documentation for\n+more information.\n+\n+\n+Merge workflow\n+~~~~~~~~~~~~~~\n+\n+The merge workflow works by copying branches between upstream and\n+downstream.  Upstream can merge contributions into the official\n+history; downstream base their work on the official history.\n+\n+There are three main tools that can be used for this:\n+\n+* linkgit:git-push[1] copies your branches to a remote repository,\n+  usually to one that can be read by all involved parties;\n+\n+* linkgit:git-fetch[1] that copies remote branches to your repository;\n+  and\n+\n+* linkgit:git-pull[1] that does fetch and merge in one go.\n+\n+Note the last point.  Do 'not' use 'git-pull' unless you actually want\n+to merge the remote branch.\n+\n+Getting changes out is easy:\n+\n+.Push/pull: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git push <remote> <branch>` and tell everyone where they can fetch\n+from.\n+=====================================\n+\n+You will still have to tell people by other means, such as mail.  (Git\n+provides the linkgit:request-pull[1] to send preformatted pull\n+requests to upstream maintainers to simplify this task.)\n+\n+If you just want to get the newest copies of the main branches,\n+staying up to date is easy too:\n+\n+.Push/pull: Staying up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+Use `git fetch <remote>` or `git remote update` to stay up to date.\n+=====================================\n+\n+Then simply fork your topic branches from the stable remotes as\n+explained earlier.\n+\n+If you are a maintainer and would like to merge other people's topic\n+branches to the main branches, they will typically send a request to\n+do so by mail.  Such a request looks like\n+\n+-------------------------------------\n+Please pull from\n+    <url> <branch>\n+-------------------------------------\n+\n+In that case, 'git-pull' can do the fetch and merge in one go, as\n+follows.\n+\n+.Push/pull: Merging remote topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git pull <url> <branch>`\n+=====================================\n+\n+Occasionally, the maintainer may get merge conflicts when he tries to\n+pull changes from downstream.  In this case, he can ask downstream to\n+do the merge and resolve the conflicts themselves (perhaps they will\n+know better how to resolve them).  It is one of the rare cases where\n+downstream 'should' merge from upstream.\n+\n+\n+Patch workflow\n+~~~~~~~~~~~~~~\n+\n+If you are a contributor that sends changes upstream in the form of\n+emails, you should use topic branches as usual (see above).  Then use\n+linkgit:git-format-patch[1] to generate the corresponding emails\n+(highly recommended over manually formatting them because it makes the\n+maintainer's life easier).\n+\n+.format-patch/am: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+* `git format-patch -M upstream..topic` to turn them into preformatted\n+  patch files\n+* `git send-email --to=<recipient> <patches>`\n+=====================================\n+\n+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\n+manpages for further usage notes.\n+\n+If the maintainer tells you that your patch no longer applies to the\n+current upstream, you will have to rebase your topic (you cannot use a\n+merge because you cannot format-patch merges):\n+\n+.format-patch/am: Keeping topics up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+`git pull --rebase <url> <branch>`\n+=====================================\n+\n+You can then fix the conflicts during the rebase.  Presumably you have\n+not published your topic other than by mail, so rebasing it is not a\n+problem.\n+\n+If you receive such a patch series (as maintainer, or perhaps as a\n+reader of the mailing list it was sent to), save the mails to files,\n+create a new topic branch and use 'git-am' to import the commits:\n+\n+.format-patch/am: Importing patches\n+[caption=\"Recipe: \"]\n+=====================================\n+`git am < patch`\n+=====================================\n+\n+One feature worth pointing out is the three-way merge, which can help\n+if you get conflicts: `git am -3` will use index information contained\n+in patches to figure out the merge base.  See linkgit:git-am[1] for\n+other options.\n+\n+\n+SEE ALSO\n+--------\n+linkgit:gittutorial[7],\n+linkgit:git-push[1],\n+linkgit:git-pull[1],\n+linkgit:git-merge[1],\n+linkgit:git-rebase[1],\n+linkgit:git-format-patch[1],\n+linkgit:git-send-email[1],\n+linkgit:git-am[1]\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite.\n-- \ntg: (2de69d4..) t/doc-workflows (depends on: origin/master t/doc-rebase-warn t/doc-rebase-refer)\n"},{"id":"92665","messageId":"1223552537-6918-2-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1223552537-6918-1-git-send-email-trast@student.ethz.ch","subject":"[Interdiff] [RFC PATCH v2] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-10-09T11:42:17Z","receivedAt":"2008-10-09T11:42:17Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"---\n\nI wrote:\n> Interdiff will follow, as before.\n\n\n\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nindex 87c2270..037ace5 100644\n--- a/Documentation/gitworkflows.txt\n+++ b/Documentation/gitworkflows.txt\n@@ -39,24 +39,32 @@ beginning. It is always easier to squash a few commits together than\n to split one big commit into several.  Don't be afraid of making too\n small or imperfect steps along the way. You can always go back later\n and edit the commits with `git rebase \\--interactive` before you\n-publish them.\n+publish them.  You can use `git stash save \\--keep-index` to run the\n+test suite independent of other uncommitted changes; see the EXAMPLES\n+section of linkgit:git-stash[1].\n \n \n MANAGING BRANCHES\n -----------------\n \n-Usually a feature (or other change) evolves in stages: it \"graduates\"\n-from patch to the testing branches and on to stable releases.  During\n-this process, it may require fixes or improvements.  XXX terrible\n-paragraph XXX\n+There are two main tools that can be used to include changes from one\n+branch on another: linkgit:git-merge[1] and\n+linkgit:git-cherry-pick[1].\n \n-Merges (as opposed to cherry-picks, see below) greatly simplify\n-handling large numbers of commits, so a scalable workflow needs to use\n-merges.  Fortunately Git is very good at merging.\n+Merges have many advantages, so we try to solve as many problems as\n+possible with merges alone.  Cherry-picking is still occasionally\n+useful; see \"Merging upwards\" below for an example.\n \n-XXX non sequitur XXX\n-In the following sections we discuss some problems that arise from\n-such a \"change flow\", and how to solve them with Git.\n+Most importantly, merging works at the branch level, while\n+cherry-picking works at the commit level.  This means that a merge can\n+carry over the changes from 1, 10, or 1000 commits with equal ease,\n+which in turn means the workflow scales much better to a large number\n+of contributors (and contributions).  Merges are also easier to\n+understand because a merge commit is a \"promise\" that all changes from\n+all its parents are now included.\n+\n+There is a tradeoff of course: merges require a more careful branch\n+management.  The following subsections discuss the important points.\n \n \n Graduation\n@@ -66,13 +74,13 @@ As a given feature goes from experimental to stable, it also\n \"graduates\" between the corresponding branches of the software.\n `git.git` uses the following 'main branches':\n \n-* 'master' tracks the commits that should go into the next release;\n-\n * 'maint' tracks the commits that should go into the next \"maintenance\n-  release\", i.e., update of the last released stable version; and\n+  release\", i.e., update of the last released stable version;\n \n-* 'next' is intended as a testing branch for people who like to use\n-  more experimental stuff.\n+* 'master' tracks the commits that should go into the next release;\n+\n+* 'next' is intended as a testing branch for topics not stable enough\n+  for master yet.\n \n There is a fourth official branch that is used slightly differently:\n \n@@ -80,6 +88,9 @@ There is a fourth official branch that is used slightly differently:\n   not quite ready for inclusion yet (see \"Integration Branches\"\n   below).\n \n+Each of the four branches is usually a direct descendant of the one\n+above it.\n+\n Conceptually, the feature enters at an unstable branch (usually 'next'\n or 'pu'), and \"graduates\" to 'master' for the next release once it is\n considered stable enough.\n@@ -88,10 +99,9 @@ considered stable enough.\n Merging upwards\n ~~~~~~~~~~~~~~~\n \n-As explained above, features conceptually \"graduate downwards\" to\n-older releases.  This cannot be done by actually merging downwards,\n-however, since that would merge 'all' changes on the unstable branch\n-into the stable one.  Hence the following:\n+The \"downwards graduation\" discussed above cannot be done by actually\n+merging downwards, however, since that would merge 'all' changes on\n+the unstable branch into the stable one.  Hence the following:\n \n .Merge upwards\n [caption=\"Rule: \"]\n@@ -187,45 +197,41 @@ into a throw-away branch.\n [caption=\"Rule: \"]\n =====================================\n To test the interaction of several topics, merge them into a\n-throw-away branch.\n+throw-away branch.  You must never base any work on such a branch!\n =====================================\n \n If you make it (very) clear that this branch is going to be deleted\n right after the testing, you can even publish this branch, for example\n to give the testers a chance to work with it, or other developers a\n chance to see if their in-progress work will be compatible.  `git.git`\n-has such an official integration branch called 'pu'.  You must never\n-base any work on such a throw-away branch!\n+has such an official integration branch called 'pu'.\n \n \n-SHARING WORK\n-------------\n+DISTRIBUTED WORKFLOWS\n+---------------------\n \n After the last section, you should know how to manage topics.  In\n general, you will not be the only person working on the project, so\n you will have to share your work.\n \n-Roughly speaking, there are two important workflows: push/pull and\n-format-patch/am.  The important difference is that push/pull can\n-propagate merges, while format-patch cannot.  Medium to large projects\n-will typically employ some mixture of the two:\n+Roughly speaking, there are two important workflows: merge and patch.\n+The important difference is that the merge workflow can propagate full\n+history, including merges, while patches cannot.  Both workflows can\n+be used in parallel: in `git.git`, only subsystem maintainers use\n+the merge workflow, while everyone else sends patches.\n \n-* \"Upstream\" in the most general sense 'pushes' changes to the\n-  repositor(ies) holding the official history of the project.\n-  Everyone can 'fetch' from there to stay up to date.\n+Note that the maintainer(s) may impose restrictions, such as\n+\"Signed-off-by\" requirements, that all commits/patches submitted for\n+inclusion must adhere to.  Consult your project's documentation for\n+more information.\n \n-* Frequent contributors, subsystem maintainers, etc. may push to a\n-  public repository to make their changes available to upstream.\n-\n-* The rest -- typically anyone more than one or two levels away from the\n-  main maintainer -- send patches by mail.\n-\n-None of these boundaries are sharp, so find out what works best for\n-you.\n \n+Merge workflow\n+~~~~~~~~~~~~~~\n \n-Push/pull\n-~~~~~~~~~\n+The merge workflow works by copying branches between upstream and\n+downstream.  Upstream can merge contributions into the official\n+history; downstream base their work on the official history.\n \n There are three main tools that can be used for this:\n \n@@ -267,11 +273,11 @@ explained earlier.\n \n If you are a maintainer and would like to merge other people's topic\n branches to the main branches, they will typically send a request to\n-do so by mail.  Such a request might say\n+do so by mail.  Such a request looks like\n \n -------------------------------------\n Please pull from\n-    git://some.server.somewhere/random/repo.git mytopic\n+    <url> <branch>\n -------------------------------------\n \n In that case, 'git-pull' can do the fetch and merge in one go, as\n@@ -290,8 +296,8 @@ know better how to resolve them).  It is one of the rare cases where\n downstream 'should' merge from upstream.\n \n \n-format-patch/am\n-~~~~~~~~~~~~~~~\n+Patch workflow\n+~~~~~~~~~~~~~~\n \n If you are a contributor that sends changes upstream in the form of\n emails, you should use topic branches as usual (see above).  Then use\n@@ -308,9 +314,7 @@ maintainer's life easier).\n =====================================\n \n See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\n-manpages for further usage notes.  Also you should be aware that the\n-maintainer may impose further restrictions, such as \"Signed-off-by\"\n-requirements.\n+manpages for further usage notes.\n \n If the maintainer tells you that your patch no longer applies to the\n current upstream, you will have to rebase your topic (you cannot use a\n@@ -326,11 +330,11 @@ You can then fix the conflicts during the rebase.  Presumably you have\n not published your topic other than by mail, so rebasing it is not a\n problem.\n \n-If you receive such a patch (as maintainer, or perhaps as a reader of\n-the mailing list it was sent to), save the mail to a file and use\n-'git-am':\n+If you receive such a patch series (as maintainer, or perhaps as a\n+reader of the mailing list it was sent to), save the mails to files,\n+create a new topic branch and use 'git-am' to import the commits:\n \n-.format-patch/am: Publishing branches/topics\n+.format-patch/am: Importing patches\n [caption=\"Recipe: \"]\n =====================================\n `git am < patch`\n"},{"id":"92667","messageId":"7v8wsyortf.fsf@gitster.siamese.dyndns.org","threadId":"15339","inReplyTo":"1223552537-6918-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH v2] Documentation: add manpage about workflows","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-10-09T12:50:52Z","receivedAt":"2008-10-09T12:50:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\n> new file mode 100644\n> index 0000000..037ace5\n> --- /dev/null\n> +++ b/Documentation/gitworkflows.txt\n> @@ -0,0 +1,362 @@\n> +gitworkflows(7)\n> +===============\n> ...\n> +DESCRIPTION\n> +-----------\n> +\n> +This document attempts to write down and motivate some of the workflow\n> +elements used for `git.git` itself.  Many ideas apply in general,\n> +though the full workflow is rarely required for smaller projects with\n> +fewer people involved.\n\nHmm.  Even though I have to wonder if the workflow used in git.git should\nbe treated as a representative BCP.  For one thing, git.git is on the\nsmaller end of the spectrum (from the point of view of the size of the\ncodebase, but not from the size of the contributor base), it is something\nwe know well enough and probably is a good place to take examples from.\n\n> +Graduation\n> +~~~~~~~~~~\n> +\n> +As a given feature goes from experimental to stable, it also\n> +\"graduates\" between the corresponding branches of the software.\n> +`git.git` uses the following 'main branches':\n> +\n> +* 'maint' tracks the commits that should go into the next \"maintenance\n> +  release\", i.e., update of the last released stable version;\n> +\n> +* 'master' tracks the commits that should go into the next release;\n> +\n> +* 'next' is intended as a testing branch for topics not stable enough\n> +  for master yet.\n\ns/not stable enough/being tested for stability/;s/ yet//;\n\nThe point being that commits on next are deemed stable enough from code\ninspection but are kept out of master for a while because your maintainer\nwants to be extra careful.\n\n> +Topic branches\n> +~~~~~~~~~~~~~~\n> +\n> +Any nontrivial feature will require several patches to implement, and\n> +may get extra bugfixes or improvements during its lifetime.\n> +\n> +Committing everything directly on the main branches leads to many\n> +problems: Bad commits cannot be undone, so they must be reverted one\n> +by one, which creates confusing histories and further error potential\n> +when you forget to revert part of a group of changes.  Working in\n> +parallel mixes up the changes, creating further confusion.\n> +\n> +The key concept here is \"topic branches\".  The name is pretty self\n> +explanatory, with a caveat that comes from the \"merge upwards\" rule\n> +above:\n\nI'd reword the first sentence --- Use of \"Topic branches\" solves these\nproblems.\n\n> +We should point out that \"habitually\" (regularly for no real reason)\n> +merging a main branch into your topics -- and by extension, merging\n> +anything upstream into anything downstream on a regular basis -- is\n> +frowned upon:\n> +\n> +.Merge to downstream only at well-defined points\n> +[caption=\"Rule: \"]\n> +=====================================\n> +Do not merge to downstream except:\n> +\n> +* with a good reason: upstream API changes affect your branch; your\n> +  branch no longer merges to upstream cleanly; etc.\n> +\n> +* at well-defined points such as when an upstream release has been tagged.\n> +=====================================\n> +\n> +Otherwise, the many resulting small merges will greatly clutter up\n> +history.  Anyone who later investigates the history of a file will\n> +have to find out whether that merge affected the topic in development.\n\nThis description misses the most important reason why merging into topic\nbranches is not a good idea.  Once you merge a general purpose integration\nbranch such as master into a topic branch, the branch ceases to be about\nthe single topic.  It becomes \"the topic and other unrelated changes mixed\ntogether\".\n\n> +Integration branches\n> +~~~~~~~~~~~~~~~~~~~~\n\nNomenclature.  I think we use the word \"integration branches\" to mean the\nstable branches such as maint/master/next, not the ones you use for\nthrow-away test merges.\n\nAlways merging upward is a good rule, and this is when used with topic\nbranches, there is one twist you did not mention but is worth knowing\nabout.  A topic that is meant to eventually merge into older integration\nbranch (e.g. maint) does not necessarily have to be merged to its final\ndestination branch first.  I often do this:\n\n\tgit checkout tr/maint-fix-bla maint\n        git am -s fix-mail-from-thomas.txt\n        git checkout next\n        git merge tr/maint-fix-bla\n        ... cook further, perhaps adding more commits to\n        ... tr/maint-fix-bla topic and merging the result to next;\n\t... and then when the topic appears to be stable do:\n\tgit checkout master\n        git merge tr/maint-fix-bla\n\t... and later\n        git checkout maint\n        git merge tr/maint-fix-bla\n\tgit branch -d tr/maint-fix-bla\n\nThis keeps older integration branches stale, until the topic really gets\nproven to be regression-free in the field.  This workflow is safer and\nmore suitable for a final integration branch to which a known breakage is\nbetter than an unintended regression.  An alternative would be what the\nreader would assume from your description of merging upwards, which would\nlook like this:\n\n\tgit checkout tr/maint-fix-bla maint\n        git am -s fix-mail-from-thomas.txt\n        git checkout maint\n        git merge tr/maint-fix-bla\n\tgit checkout master\n        git merge maint\n        git checkout next\n\tgit merge master\n\nThis can regress maint unintentionally and then the regression is\npropagated upwards to contaminate all integration branches.\n"},{"id":"93420","messageId":"1224429622-1548-1-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"7v8wsyortf.fsf@gitster.siamese.dyndns.org","subject":"[RFC PATCH v3] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-10-19T15:20:21Z","receivedAt":"2008-10-19T15:20:21Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This attempts to make a manpage about workflows that is both handy to\npoint people at it and as a beginner's introduction.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n\n---\n\n> > +Integration branches\n> > +~~~~~~~~~~~~~~~~~~~~\n> \n> Nomenclature.  I think we use the word \"integration branches\" to mean the\n> stable branches such as maint/master/next, not the ones you use for\n> throw-away test merges.\n\nI renamed those, and now call 'pu' a \"throw-away integration branch\",\nwhich is sort of unwieldy but I can't think of a good short name.\n\nFull interdiff follows, as before.\n\n\n Documentation/Makefile         |    2 +-\n Documentation/gitworkflows.txt |  364 ++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 365 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ded0e40..e33ddcb 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \\\n \tgitrepository-layout.txt\n MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \\\n \tgitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \\\n-\tgitdiffcore.txt\n+\tgitdiffcore.txt gitworkflows.txt\n \n MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)\n MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nnew file mode 100644\nindex 0000000..7fe9f72\n--- /dev/null\n+++ b/Documentation/gitworkflows.txt\n@@ -0,0 +1,364 @@\n+gitworkflows(7)\n+===============\n+\n+NAME\n+----\n+gitworkflows - An overview of recommended workflows with git\n+\n+SYNOPSIS\n+--------\n+git *\n+\n+\n+DESCRIPTION\n+-----------\n+\n+This document attempts to write down and motivate some of the workflow\n+elements used for `git.git` itself.  Many ideas apply in general,\n+though the full workflow is rarely required for smaller projects with\n+fewer people involved.\n+\n+We formulate a set of 'rules' for quick reference, while the prose\n+tries to motivate each of them.  Do not always take them literally;\n+you should value good reasons for your actions higher than manpages\n+such as this one.\n+\n+\n+SEPARATE CHANGES\n+----------------\n+\n+As a general rule, you should try to split your changes into small\n+logical steps, and commit each of them.  They should be consistent,\n+working independently of any later commits, pass the test suite, etc.\n+This makes the review process much easier, and the history much more\n+useful for later inspection and analysis, for example with\n+linkgit:git-blame[1] and linkgit:git-bisect[1].\n+\n+To achieve this, try to split your work into small steps from the very\n+beginning. It is always easier to squash a few commits together than\n+to split one big commit into several.  Don't be afraid of making too\n+small or imperfect steps along the way. You can always go back later\n+and edit the commits with `git rebase \\--interactive` before you\n+publish them.  You can use `git stash save \\--keep-index` to run the\n+test suite independent of other uncommitted changes; see the EXAMPLES\n+section of linkgit:git-stash[1].\n+\n+\n+MANAGING BRANCHES\n+-----------------\n+\n+There are two main tools that can be used to include changes from one\n+branch on another: linkgit:git-merge[1] and\n+linkgit:git-cherry-pick[1].\n+\n+Merges have many advantages, so we try to solve as many problems as\n+possible with merges alone.  Cherry-picking is still occasionally\n+useful; see \"Merging upwards\" below for an example.\n+\n+Most importantly, merging works at the branch level, while\n+cherry-picking works at the commit level.  This means that a merge can\n+carry over the changes from 1, 10, or 1000 commits with equal ease,\n+which in turn means the workflow scales much better to a large number\n+of contributors (and contributions).  Merges are also easier to\n+understand because a merge commit is a \"promise\" that all changes from\n+all its parents are now included.\n+\n+There is a tradeoff of course: merges require a more careful branch\n+management.  The following subsections discuss the important points.\n+\n+\n+Graduation\n+~~~~~~~~~~\n+\n+As a given feature goes from experimental to stable, it also\n+\"graduates\" between the corresponding branches of the software.\n+`git.git` uses the following 'integration branches':\n+\n+* 'maint' tracks the commits that should go into the next \"maintenance\n+  release\", i.e., update of the last released stable version;\n+\n+* 'master' tracks the commits that should go into the next release;\n+\n+* 'next' is intended as a testing branch for topics being tested for\n+  stability for master.\n+\n+There is a fourth official branch that is used slightly differently:\n+\n+* 'pu' (proposed updates) is an integration branch for things that are\n+  not quite ready for inclusion yet (see \"Integration Branches\"\n+  below).\n+\n+Each of the four branches is usually a direct descendant of the one\n+above it.\n+\n+Conceptually, the feature enters at an unstable branch (usually 'next'\n+or 'pu'), and \"graduates\" to 'master' for the next release once it is\n+considered stable enough.\n+\n+\n+Merging upwards\n+~~~~~~~~~~~~~~~\n+\n+The \"downwards graduation\" discussed above cannot be done by actually\n+merging downwards, however, since that would merge 'all' changes on\n+the unstable branch into the stable one.  Hence the following:\n+\n+.Merge upwards\n+[caption=\"Rule: \"]\n+=====================================\n+Always commit your fixes to the oldest supported branch that require\n+them.  Then (periodically) merge the integration branches upwards into each\n+other.\n+=====================================\n+\n+This gives a very controlled flow of fixes.  If you notice that you\n+have applied a fix to e.g. 'master' that is also required in 'maint',\n+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])\n+downwards.  This will happen a few times and is nothing to worry about\n+unless you do it very frequently.\n+\n+\n+Topic branches\n+~~~~~~~~~~~~~~\n+\n+Any nontrivial feature will require several patches to implement, and\n+may get extra bugfixes or improvements during its lifetime.\n+\n+Committing everything directly on the integration branches leads to many\n+problems: Bad commits cannot be undone, so they must be reverted one\n+by one, which creates confusing histories and further error potential\n+when you forget to revert part of a group of changes.  Working in\n+parallel mixes up the changes, creating further confusion.\n+\n+Use of \"topic branches\" solves these problems.  The name is pretty\n+self explanatory, with a caveat that comes from the \"merge upwards\"\n+rule above:\n+\n+.Topic branches\n+[caption=\"Rule: \"]\n+=====================================\n+Make a side branch for every topic (feature, bugfix, ...). Fork it off\n+at the oldest integration branch that you will eventually want to merge it\n+into.\n+=====================================\n+\n+Many things can then be done very naturally:\n+\n+* To get the feature/bugfix into an integration branch, simply merge\n+  it.  If the topic has evolved further in the meantime, merge again.\n+  (Note that you do not necessarily have to merge it to the oldest\n+  integration branch first.  For example, you can first merge a bugfix\n+  to 'next', give it some testing time, and merge to 'maint' when you\n+  know it is stable.)\n+\n+* If you find you need new features from the branch 'other' to continue\n+  working on your topic, merge 'other' to 'topic'.  (However, do not\n+  do this \"just habitually\", see below.)\n+\n+* If you find you forked off the wrong branch and want to move it\n+  \"back in time\", use linkgit:git-rebase[1].\n+\n+Note that the last point clashes with the other two: a topic that has\n+been merged elsewhere should not be rebased.  See the section on\n+RECOVERING FROM UPSTREAM REBASE in linkgit:git-rebase[1].\n+\n+We should point out that \"habitually\" (regularly for no real reason)\n+merging an integration branch into your topics -- and by extension,\n+merging anything upstream into anything downstream on a regular basis\n+-- is frowned upon:\n+\n+.Merge to downstream only at well-defined points\n+[caption=\"Rule: \"]\n+=====================================\n+Do not merge to downstream except with a good reason: upstream API\n+changes affect your branch; your branch no longer merges to upstream\n+cleanly; etc.\n+=====================================\n+\n+Otherwise, the topic that was merged to suddenly contains more than a\n+single (well-separated) change.  The many resulting small merges will\n+greatly clutter up history.  Anyone who later investigates the history\n+of a file will have to find out whether that merge affected the topic\n+in development.  An upstream might even inadvertently be merged into a\n+\"more stable\" branch.  And so on.\n+\n+\n+Throw-away integration\n+~~~~~~~~~~~~~~~~~~~~~~\n+\n+If you followed the last paragraph, you will now have many small topic\n+branches, and occasionally wonder how they interact.  Perhaps the\n+result of merging them does not even work?  But on the other hand, we\n+want to avoid merging them anywhere \"stable\" because such merges\n+cannot easily be undone.\n+\n+The solution, of course, is to make a merge that we can undo: merge\n+into a throw-away branch.\n+\n+.Throw-away integration branches\n+[caption=\"Rule: \"]\n+=====================================\n+To test the interaction of several topics, merge them into a\n+throw-away branch.  You must never base any work on such a branch!\n+=====================================\n+\n+If you make it (very) clear that this branch is going to be deleted\n+right after the testing, you can even publish this branch, for example\n+to give the testers a chance to work with it, or other developers a\n+chance to see if their in-progress work will be compatible.  `git.git`\n+has such an official throw-away integration branch called 'pu'.\n+\n+\n+DISTRIBUTED WORKFLOWS\n+---------------------\n+\n+After the last section, you should know how to manage topics.  In\n+general, you will not be the only person working on the project, so\n+you will have to share your work.\n+\n+Roughly speaking, there are two important workflows: merge and patch.\n+The important difference is that the merge workflow can propagate full\n+history, including merges, while patches cannot.  Both workflows can\n+be used in parallel: in `git.git`, only subsystem maintainers use\n+the merge workflow, while everyone else sends patches.\n+\n+Note that the maintainer(s) may impose restrictions, such as\n+\"Signed-off-by\" requirements, that all commits/patches submitted for\n+inclusion must adhere to.  Consult your project's documentation for\n+more information.\n+\n+\n+Merge workflow\n+~~~~~~~~~~~~~~\n+\n+The merge workflow works by copying branches between upstream and\n+downstream.  Upstream can merge contributions into the official\n+history; downstream base their work on the official history.\n+\n+There are three main tools that can be used for this:\n+\n+* linkgit:git-push[1] copies your branches to a remote repository,\n+  usually to one that can be read by all involved parties;\n+\n+* linkgit:git-fetch[1] that copies remote branches to your repository;\n+  and\n+\n+* linkgit:git-pull[1] that does fetch and merge in one go.\n+\n+Note the last point.  Do 'not' use 'git-pull' unless you actually want\n+to merge the remote branch.\n+\n+Getting changes out is easy:\n+\n+.Push/pull: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git push <remote> <branch>` and tell everyone where they can fetch\n+from.\n+=====================================\n+\n+You will still have to tell people by other means, such as mail.  (Git\n+provides the linkgit:request-pull[1] to send preformatted pull\n+requests to upstream maintainers to simplify this task.)\n+\n+If you just want to get the newest copies of the integration branches,\n+staying up to date is easy too:\n+\n+.Push/pull: Staying up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+Use `git fetch <remote>` or `git remote update` to stay up to date.\n+=====================================\n+\n+Then simply fork your topic branches from the stable remotes as\n+explained earlier.\n+\n+If you are a maintainer and would like to merge other people's topic\n+branches to the integration branches, they will typically send a\n+request to do so by mail.  Such a request looks like\n+\n+-------------------------------------\n+Please pull from\n+    <url> <branch>\n+-------------------------------------\n+\n+In that case, 'git-pull' can do the fetch and merge in one go, as\n+follows.\n+\n+.Push/pull: Merging remote topics\n+[caption=\"Recipe: \"]\n+=====================================\n+`git pull <url> <branch>`\n+=====================================\n+\n+Occasionally, the maintainer may get merge conflicts when he tries to\n+pull changes from downstream.  In this case, he can ask downstream to\n+do the merge and resolve the conflicts themselves (perhaps they will\n+know better how to resolve them).  It is one of the rare cases where\n+downstream 'should' merge from upstream.\n+\n+\n+Patch workflow\n+~~~~~~~~~~~~~~\n+\n+If you are a contributor that sends changes upstream in the form of\n+emails, you should use topic branches as usual (see above).  Then use\n+linkgit:git-format-patch[1] to generate the corresponding emails\n+(highly recommended over manually formatting them because it makes the\n+maintainer's life easier).\n+\n+.format-patch/am: Publishing branches/topics\n+[caption=\"Recipe: \"]\n+=====================================\n+* `git format-patch -M upstream..topic` to turn them into preformatted\n+  patch files\n+* `git send-email --to=<recipient> <patches>`\n+=====================================\n+\n+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]\n+manpages for further usage notes.\n+\n+If the maintainer tells you that your patch no longer applies to the\n+current upstream, you will have to rebase your topic (you cannot use a\n+merge because you cannot format-patch merges):\n+\n+.format-patch/am: Keeping topics up to date\n+[caption=\"Recipe: \"]\n+=====================================\n+`git pull --rebase <url> <branch>`\n+=====================================\n+\n+You can then fix the conflicts during the rebase.  Presumably you have\n+not published your topic other than by mail, so rebasing it is not a\n+problem.\n+\n+If you receive such a patch series (as maintainer, or perhaps as a\n+reader of the mailing list it was sent to), save the mails to files,\n+create a new topic branch and use 'git-am' to import the commits:\n+\n+.format-patch/am: Importing patches\n+[caption=\"Recipe: \"]\n+=====================================\n+`git am < patch`\n+=====================================\n+\n+One feature worth pointing out is the three-way merge, which can help\n+if you get conflicts: `git am -3` will use index information contained\n+in patches to figure out the merge base.  See linkgit:git-am[1] for\n+other options.\n+\n+\n+SEE ALSO\n+--------\n+linkgit:gittutorial[7],\n+linkgit:git-push[1],\n+linkgit:git-pull[1],\n+linkgit:git-merge[1],\n+linkgit:git-rebase[1],\n+linkgit:git-format-patch[1],\n+linkgit:git-send-email[1],\n+linkgit:git-am[1]\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite.\n-- \ntg: (50ea8e5..) t/doc-workflows (depends on: origin/master t/doc-rebase-warn t/doc-rebase-refer)\n"},{"id":"93419","messageId":"1224429622-1548-2-git-send-email-trast@student.ethz.ch","threadId":"15339","inReplyTo":"1224429622-1548-1-git-send-email-trast@student.ethz.ch","subject":"[Interdiff] [RFC PATCH v3] Documentation: add manpage about workflows","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2008-10-19T15:20:22Z","receivedAt":"2008-10-19T15:20:22Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"---\n Documentation/gitworkflows.txt |   72 ++++++++++++++++++++-------------------\n 1 files changed, 37 insertions(+), 35 deletions(-)\n\ndiff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt\nindex 037ace5..7fe9f72 100644\n--- a/Documentation/gitworkflows.txt\n+++ b/Documentation/gitworkflows.txt\n@@ -72,15 +72,15 @@ Graduation\n \n As a given feature goes from experimental to stable, it also\n \"graduates\" between the corresponding branches of the software.\n-`git.git` uses the following 'main branches':\n+`git.git` uses the following 'integration branches':\n \n * 'maint' tracks the commits that should go into the next \"maintenance\n   release\", i.e., update of the last released stable version;\n \n * 'master' tracks the commits that should go into the next release;\n \n-* 'next' is intended as a testing branch for topics not stable enough\n-  for master yet.\n+* 'next' is intended as a testing branch for topics being tested for\n+  stability for master.\n \n There is a fourth official branch that is used slightly differently:\n \n@@ -107,7 +107,7 @@ the unstable branch into the stable one.  Hence the following:\n [caption=\"Rule: \"]\n =====================================\n Always commit your fixes to the oldest supported branch that require\n-them.  Then (periodically) merge the main branches upwards into each\n+them.  Then (periodically) merge the integration branches upwards into each\n other.\n =====================================\n \n@@ -124,28 +124,32 @@ Topic branches\n Any nontrivial feature will require several patches to implement, and\n may get extra bugfixes or improvements during its lifetime.\n \n-Committing everything directly on the main branches leads to many\n+Committing everything directly on the integration branches leads to many\n problems: Bad commits cannot be undone, so they must be reverted one\n by one, which creates confusing histories and further error potential\n when you forget to revert part of a group of changes.  Working in\n parallel mixes up the changes, creating further confusion.\n \n-The key concept here is \"topic branches\".  The name is pretty self\n-explanatory, with a caveat that comes from the \"merge upwards\" rule\n-above:\n+Use of \"topic branches\" solves these problems.  The name is pretty\n+self explanatory, with a caveat that comes from the \"merge upwards\"\n+rule above:\n \n .Topic branches\n [caption=\"Rule: \"]\n =====================================\n Make a side branch for every topic (feature, bugfix, ...). Fork it off\n-at the oldest main branch that you will eventually want to merge it\n+at the oldest integration branch that you will eventually want to merge it\n into.\n =====================================\n \n Many things can then be done very naturally:\n \n-* To get the feature/bugfix into a main branch, simply merge it.  If\n-  the topic has evolved further in the meantime, merge again.\n+* To get the feature/bugfix into an integration branch, simply merge\n+  it.  If the topic has evolved further in the meantime, merge again.\n+  (Note that you do not necessarily have to merge it to the oldest\n+  integration branch first.  For example, you can first merge a bugfix\n+  to 'next', give it some testing time, and merge to 'maint' when you\n+  know it is stable.)\n \n * If you find you need new features from the branch 'other' to continue\n   working on your topic, merge 'other' to 'topic'.  (However, do not\n@@ -154,35 +158,33 @@ Many things can then be done very naturally:\n * If you find you forked off the wrong branch and want to move it\n   \"back in time\", use linkgit:git-rebase[1].\n \n-Note that the last two points clash: a topic that has been merged\n-elsewhere should not be rebased.  See the section on RECOVERING FROM\n-UPSTREAM REBASE in linkgit:git-rebase[1].\n+Note that the last point clashes with the other two: a topic that has\n+been merged elsewhere should not be rebased.  See the section on\n+RECOVERING FROM UPSTREAM REBASE in linkgit:git-rebase[1].\n \n We should point out that \"habitually\" (regularly for no real reason)\n-merging a main branch into your topics -- and by extension, merging\n-anything upstream into anything downstream on a regular basis -- is\n-frowned upon:\n+merging an integration branch into your topics -- and by extension,\n+merging anything upstream into anything downstream on a regular basis\n+-- is frowned upon:\n \n .Merge to downstream only at well-defined points\n [caption=\"Rule: \"]\n =====================================\n-Do not merge to downstream except:\n-\n-* with a good reason: upstream API changes affect your branch; your\n-  branch no longer merges to upstream cleanly; etc.\n-\n-* at well-defined points such as when an upstream release has been tagged.\n+Do not merge to downstream except with a good reason: upstream API\n+changes affect your branch; your branch no longer merges to upstream\n+cleanly; etc.\n =====================================\n \n-Otherwise, the many resulting small merges will greatly clutter up\n-history.  Anyone who later investigates the history of a file will\n-have to find out whether that merge affected the topic in development.\n-An upstream might even inadvertently be merged into a \"more stable\"\n-branch.  And so on.\n+Otherwise, the topic that was merged to suddenly contains more than a\n+single (well-separated) change.  The many resulting small merges will\n+greatly clutter up history.  Anyone who later investigates the history\n+of a file will have to find out whether that merge affected the topic\n+in development.  An upstream might even inadvertently be merged into a\n+\"more stable\" branch.  And so on.\n \n \n-Integration branches\n-~~~~~~~~~~~~~~~~~~~~\n+Throw-away integration\n+~~~~~~~~~~~~~~~~~~~~~~\n \n If you followed the last paragraph, you will now have many small topic\n branches, and occasionally wonder how they interact.  Perhaps the\n@@ -193,7 +195,7 @@ cannot easily be undone.\n The solution, of course, is to make a merge that we can undo: merge\n into a throw-away branch.\n \n-.Integration branches\n+.Throw-away integration branches\n [caption=\"Rule: \"]\n =====================================\n To test the interaction of several topics, merge them into a\n@@ -204,7 +206,7 @@ If you make it (very) clear that this branch is going to be deleted\n right after the testing, you can even publish this branch, for example\n to give the testers a chance to work with it, or other developers a\n chance to see if their in-progress work will be compatible.  `git.git`\n-has such an official integration branch called 'pu'.\n+has such an official throw-away integration branch called 'pu'.\n \n \n DISTRIBUTED WORKFLOWS\n@@ -259,7 +261,7 @@ You will still have to tell people by other means, such as mail.  (Git\n provides the linkgit:request-pull[1] to send preformatted pull\n requests to upstream maintainers to simplify this task.)\n \n-If you just want to get the newest copies of the main branches,\n+If you just want to get the newest copies of the integration branches,\n staying up to date is easy too:\n \n .Push/pull: Staying up to date\n@@ -272,8 +274,8 @@ Then simply fork your topic branches from the stable remotes as\n explained earlier.\n \n If you are a maintainer and would like to merge other people's topic\n-branches to the main branches, they will typically send a request to\n-do so by mail.  Such a request looks like\n+branches to the integration branches, they will typically send a\n+request to do so by mail.  Such a request looks like\n \n -------------------------------------\n Please pull from\n-- \n1.6.0.2.916.g8e7f4\n"},{"id":"93459","messageId":"7vej2c73in.fsf@gitster.siamese.dyndns.org","threadId":"15339","inReplyTo":"1224429622-1548-1-git-send-email-trast@student.ethz.ch","subject":"Re: [RFC PATCH v3] Documentation: add manpage about workflows","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-10-19T20:07:12Z","receivedAt":"2008-10-19T20:07:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> This attempts to make a manpage about workflows that is both handy to\n> point people at it and as a beginner's introduction.\n\nIs this still \"RFC PATCH\" or meant for application?\n\nI did not find many things that I find objectionable.  On the other hand,\nI am not a good person to judge if this documentation is easily\nunderstandable by beginners (anymore).  Do others who interact regularly\nwith new people have comments?\n"}]}