threads / rfc / 15339

RFC patchDocumentation: new upstream rebase recovery section in git-rebase

Subject: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase

## tl;dr

29 messages between Sep 2, 2008 and Oct 19, 2008. Diffs are folded; open one to read it.

replies: 28people: 6as markdown or json

Thomas Rast· Sep 2, 2008, 20:18 UTC · lore

Documents how to recover if the upstream that you pull from has rebased the branches you depend your work on. Hopefully this can also serve as a warning to potential rebasers.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

I've always found the "warning" on the git-rebase manpage (it's not even marked as a warning!) a bit weak.

So this is an attempt to solve two problems in one go. It should be precise enough to help users understand and recover, but scary enough to prevent them from doing such rebases in the first place.

I flagged it as RFC because I'd appreciate some feedback:
- Are the warnings too repetitive?  I fear that if we sound too
  protective, users won't listen.
- Is it perhaps too verbose, or in the wrong place?  I did not want to
  detract from the feature descriptions that the manpage should first
  and foremost contain.  Chances that a user will "accidentally" read
  the section at this position and length seem fairly low however.

I've also edited it a fair bit, so chances are that mistakes have snuck in.

If you like the general direction of this, I'll also make a patch that points at this section from other rewriting manpages.

- Thomas
 Documentation/git-rebase.txt |   79 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 75 insertions(+), 4 deletions(-)
Show changes to Documentation/git-rebase.txt +75 −4
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 59c1b02..5e1dc30 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -257,11 +257,12 @@ include::merge-strategies.txt[]
 
 NOTES
 -----
-When you rebase a branch, you are changing its history in a way that
-will cause problems for anyone who already has a copy of the branch
-in their repository and tries to pull updates from you.  You should
+
+As a rule of thumb, rebasing anything that you have published already
+is a bad idea.  It causes problems for people who already have a copy
+of your branch, and are trying to pull updates from you.  You should
 understand the implications of using 'git-rebase' on a repository that
-you share.
+you share.  See also HELP, MY UPSTREAM HAS REBASED! below.
 
 When the git-rebase command is run, it will first execute a "pre-rebase"
 hook if one exists.  You can use this hook to do sanity checks and
@@ -396,6 +397,76 @@ consistent (they compile, pass the testsuite, etc.) you should use
 after each commit, test, and amend the commit if fixes are necessary.
 
 
+HELP, MY UPSTREAM HAS REBASED!
+------------------------------
+
+This section briefly explains the problems that arise from rebasing
+published branches, and shows how to recover.  The process is rather
+tedious, so we emphasize again: 'Avoid rebasing published branches.'
+(The same warning goes for other history rewriting too, for example,
+`git commit --amend` and 'git-filter-branch'.)
+
+To illustrate, suppose you are in a situation where someone develops a
+'subsystem' branch, and you are working on a 'topic' that is dependent
+on this 'subsystem'.  You might end up with a history like the
+following:
+
+------------
+    o---o---o---o---o  master
+	 \
+	  o---o---o---o---o  subsystem
+			   \
+			    *---*---*  topic
+------------
+
+In a push/pull workflow, the maintainer of 'subsystem' would use `git
+merge master` to grab updates from upstream, and you can use the
+analogous `git merge subsystem`.
+
+If 'subsystem' is instead **rebased** against master, the following
+happens:
+
+------------
+    o---o---o---o---o  master
+	|	     \
+	|	      o'--o'--o'--o'--o'  subsystem
+	\
+	 o---o---o---o---o---*---*---*	topic
+------------
+
+Note that while we have marked your own commits with a '*', there is
+nothing that distinguishes them from the commits that previously were
+on 'subsystem'.  You can easily verify this with, for example, `git
+log subsystem..topic` -- which returned only your own commits in the
+scenario of the first graph above, but now has all the commits of the
+old 'subsystem' too!  Furthermore, a potential merge of 'topic' into
+'subsystem' is liable to cause unnecessary conflicts due to the
+duplicated changes.
+
+To recover from this, you need to find the original branch point
+manually, and rebase your topic against the new 'subsystem'.  Since in
+the graph, there are 3 commits that were your own, you can do
+------------
+    git rebase --onto subsystem HEAD~3 topic
+------------
+and end up with the fixed history
+------------
+    o---o---o---o---o  master
+		     \
+		      o'--o'--o'--o'--o'  subsystem
+					\
+					 *'--*'--*'  topic
+------------
+
+`git pull --rebase` (see linkgit:git-pull[1]) can be used to automate
+this process, but only if you use it instead of fetching, so that it
+can use the old upstream head to determine the previous branch point.
+
+The rewriting becomes a ripple effect to developers downstream from
+you (if any): since you now have rebased 'topic', they will have to
+manually rebase their own work to reflect this!
+
+
 Authors
 ------
 Written by Junio C Hamano <gitster@pobox.com> and
-- 
1.6.0.1.302.g47141
Junio C Hamano· Sep 2, 2008, 21:39 UTC · re: Thomas Rast · lore

Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase

Thomas Rast <trast@student.ethz.ch> writes:
Show 9 quoted lines
> I flagged it as RFC because I'd appreciate some feedback:
>
> - Are the warnings too repetitive?  I fear that if we sound too
>   protective, users won't listen.
>
> - Is it perhaps too verbose, or in the wrong place?  I did not want to
>   detract from the feature descriptions that the manpage should first
>   and foremost contain.  Chances that a user will "accidentally" read
>   the section at this position and length seem fairly low however.

It feels on a bit too repetitive side, but I think this is going in the right direction. How about dropping the earlier part of the change to Notes section (but keep "See also" which is a good guide for understanding the said "implications")?

> +HELP, MY UPSTREAM HAS REBASED!
> +------------------------------

I read this section only once, but it looked reasonable as a recovery procedure to me.

The additions you made are all about why rebasing public history is bad from mechanisms (overlapping changes made by old upstream history and new upstream history, unless they are identical, will cause merge conflicts between themselves that downstream will have hard time resolving) POV. While that description is all good, I think there should also be a discussion from the patchflow/workflow angle.

"Upstream has rebased" almost implies that it has its own upstream (i.e. "My upstream" is not the toplevel upstream, but is a subsystem tree or something).

Rebasing upstream is bad, but an upstream that backmerges from its own upstream too often is equally bad, and the reason of the badness, viewed from the workflow angle, shares exactly the same component.

It means that the mid-level upstream in question is not focused enough.
Cf.
    http://article.gmane.org/gmane.linux.kernel/681763
    http://article.gmane.org/gmane.linux.kernel/684030
    http://article.gmane.org/gmane.linux.kernel/684073
    http://article.gmane.org/gmane.linux.kernel/684091
    http://article.gmane.org/gmane.linux.kernel/638511
Thomas Rast· Sep 3, 2008, 05:38 UTC · re: Junio C Hamano · lore

Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase

Junio C Hamano wrote:
Show 6 quoted lines
> Thomas Rast <trast@student.ethz.ch> writes:
> > +HELP, MY UPSTREAM HAS REBASED!
> > +------------------------------
> 
> I read this section only once, but it looked reasonable as a recovery
> procedure to me.

Thanks a lot for your comments, I will look into the links you gave me.

It occured to me that rebase's ability to skip existing commits can effectively replace the entire manual component of finding out when the topic branch started. Which makes it far less scary. :-(

Maybe I'll write something about editing with 'rebase -i' instead, which breaks the automatic skips again.

- Thomas
-- 
Thomas Rast
trast@student.ethz.ch
Thomas Rast· Sep 11, 2008, 15:38 UTC · re: Thomas Rast · lore

[PATCH 0/2.5] Documentation: new upstream rebase recovery section in git-rebase

So here's the follow-up I promised.
Junio C Hamano <gitster@pobox.com> wrote:
Show 11 quoted lines
>
> Thomas Rast <trast@student.ethz.ch> writes:
> > - Is it perhaps too verbose, or in the wrong place?  I did not want to
> >   detract from the feature descriptions that the manpage should first
> >   and foremost contain.  Chances that a user will "accidentally" read
> >   the section at this position and length seem fairly low however.
> 
> It feels on a bit too repetitive side, but I think this is going in the
> right direction.  How about dropping the earlier part of the change to
> Notes section (but keep "See also" which is a good guide for understanding
> the said "implications")?

I rewrote it to include the actual rebase behaviour and some scenarios that arise from 'rebase -i', 'commit --amend' etc., then tried to shorten the section as far as I could. Hopefully this cut down on the repetitions. Unfortunately it still grew longer due to the extra content. The second patch then includes references to that section in the appropriate manpages.

The third patch is again RFC, and I made it regarding this section:
Show 14 quoted lines
> The additions you made are all about why rebasing public history is bad
> from mechanisms [...] POV.
> While that description is all good, I think there should also be a
> discussion from the patchflow/workflow angle.
> 
> "Upstream has rebased" almost implies that it has its own upstream
> (i.e. "My upstream" is not the toplevel upstream, but is a subsystem tree
> or something).
> 
> Rebasing upstream is bad, but an upstream that backmerges from its own
> upstream too often is equally bad, and the reason of the badness, viewed
> from the workflow angle, shares exactly the same component.
> 
> It means that the mid-level upstream in question is not focused enough.

I noticed that there is no manpage in which we document such workflows anyway. There is a short definition of 'topic branch' in glossary-content.txt, and a parenthetical definition in user-manual.txt in a sort of "linux.git howto". Nothing longer, however.

  [I learned what I know from Linus's Google Tech Talk[1], Tv's more
  recent EuroPython talk[2], looking at git.git, and mail such as the
  ones you linked.  I recommended [2] to people who asked about topic
  branches on #git a few times.]

So this is an attempt to make a "workflow reference". I tried to strike a balance between "just" a reference (the Rule/Recipe blocks) and more of a tutorial approach which explains the reasons. I would again greatly appreciate comments.

- Thomas
Thomas Rast (2+1):
  Documentation: new upstream rebase recovery section in git-rebase
  Documentation: Refer to git-rebase(1) to warn against rewriting
  Documentation: add manpage about workflows

[1] http://video.google.com/videoplay?docid=-2199332044603874737 [2] http://blip.tv/file/1114793/

Thomas Rast· Sep 11, 2008, 15:38 UTC · re: Thomas Rast · lore

[PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase

Documents how to recover if the upstream that you pull from has rebased the branches you depend your work on. Hopefully this can also serve as a warning to potential rebasers.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-rebase.txt |  103 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 98 insertions(+), 5 deletions(-)
Show changes to Documentation/git-rebase.txt +98 −5
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 59c1b02..ba5255d 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -257,11 +257,10 @@ include::merge-strategies.txt[]
 
 NOTES
 -----
-When you rebase a branch, you are changing its history in a way that
-will cause problems for anyone who already has a copy of the branch
-in their repository and tries to pull updates from you.  You should
-understand the implications of using 'git-rebase' on a repository that
-you share.
+
+You should understand the implications of using 'git-rebase' on a
+repository that you share.  See also RECOVERING FROM UPSTREAM REBASE
+below.
 
 When the git-rebase command is run, it will first execute a "pre-rebase"
 hook if one exists.  You can use this hook to do sanity checks and
@@ -396,6 +395,100 @@ consistent (they compile, pass the testsuite, etc.) you should use
 after each commit, test, and amend the commit if fixes are necessary.
 
 
+RECOVERING FROM UPSTREAM REBASE
+-------------------------------
+
+This section briefly explains the problems that arise from rebasing or
+rewriting published branches, and shows how to recover.  As you will
+see, the process is rather tedious, so we emphasize again: 'Avoid
+rewriting published history.'  This goes for `rebase`, `commit
+--amend`, `reset HEAD^` and `filter-branch` alike.
+
+To illustrate, suppose you are in a situation where someone develops a
+'subsystem' branch, and you are working on a 'topic' that is dependent
+on this 'subsystem'.  You might end up with a history like the
+following:
+
+------------
+    o---o---o---o---o  master
+	 \
+	  o---o---o---o---o  subsystem
+			   \
+			    *---*---*  topic
+------------
+
+If 'subsystem' is rebased against master, the following happens:
+
+------------
+    o---o---o---o---o  master
+	|	     \
+	|	      o'--o'--o'--o'--o'  subsystem
+	\
+	 o---o---o---o---o---*---*---*	topic
+------------
+
+Note that while we have marked your own commits with a '*', there is
+nothing that distinguishes them from the commits that previously were
+on 'subsystem'.  Luckily, 'git-rebase' knows to skip commits that are
+textually the same as commits in the upstream.  So if you say
+(assuming you're on 'topic')
+------------
+    git rebase subsystem
+------------
+you will end up with the fixed history
+------------
+    o---o---o---o---o  master
+		     \
+		      o'--o'--o'--o'--o'  subsystem
+					\
+					 *'--*'--*'  topic
+------------
+
+This becomes a ripple effect to anyone downstream of the first rebase:
+anyone downstream from 'topic' now needs to rebase too, and so on.
+
+Things get more complicated if your upstream used `git rebase
+--interactive` (or `commit --amend` or `reset --hard HEAD^`).  Label
+the example history as follows:
+
+------------
+    o---o---o---o---o  master
+	 \
+	  A---B---C---D---E  subsystem
+			   \
+			    X---Y---Z  topic
+------------
+
+Now suppose the 'subsystem' maintainer decides to clean up his history
+with an interactive rebase.  He edits commits A and D (marked with a
+`*`), decides to remove D entirely and moves B to the front.  This
+results in
+
+------------
+    o---o---o---o---o  master
+	|	     \
+	|	      A*--C*--E'--B'  subsystem
+	\
+	 A---B---C---D---E---X---Y---Z	topic
+------------
+
+'git-rebase' can still tell that E'=E and B'=B, so a plain `git rebase
+subsystem` would not duplicate those commits.  However, it would
+**resurrect** D (which may succeed silently!) and try to apply the
+original versions of A and C (probably resulting in conflicts).
+
+To fix this, you have to manually transplant your own part of the
+history to the new branch head.  Looking at `git log`, you should be
+able to determine that three commits on 'topic' are yours.  Again
+assuming you are already on 'topic', you can do
+------------
+    git rebase --onto subsystem HEAD~3
+------------
+to put things right.  Of course, this again ripples onwards:
+'everyone' downstream from 'subsystem' will have to 'manually' rebase
+all their work!
+
+
 Authors
 ------
 Written by Junio C Hamano <gitster@pobox.com> and
-- 
1.6.0.1.470.g200b
Thomas Rast· Sep 11, 2008, 15:38 UTC · re: Thomas Rast · lore

[PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting

This points readers at the "Recovering from upstream rebase" warning in git-rebase(1) when we talk about rewriting published history in the 'reset', 'commit --amend', and 'filter-branch' documentation.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-commit.txt        |    4 ++++
 Documentation/git-filter-branch.txt |    4 +++-
 Documentation/git-reset.txt         |    4 +++-
 3 files changed, 10 insertions(+), 2 deletions(-)
Show changes to 3 files +10 −2

Documentation/git-commit.txt, Documentation/git-filter-branch.txt, Documentation/git-reset.txt

diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index eb05b0f..eeba58d 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -144,6 +144,10 @@ It is a rough equivalent for:
 ------
 but can be used to amend a merge commit.
 --
++
+You should understand the implications of rewriting history if you
+amend a commit that has already been published.  (See the "RECOVERING
+FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].)
 
 -i::
 --include::
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index b0e710d..fed6de6 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -36,7 +36,9 @@ the objects and will not converge with the original branch.  You will not
 be able to easily push and distribute the rewritten branch on top of the
 original branch.  Please do not use this command if you do not know the
 full implications, and avoid using it anyway, if a simple single commit
-would suffice to fix your problem.
+would suffice to fix your problem.  (See the "RECOVERING FROM UPSTREAM
+REBASE" section in linkgit:git-rebase[1] for further information about
+rewriting published history.)
 
 Always verify that the rewritten version is correct: The original refs,
 if different from the rewritten ones, will be stored in the namespace
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 6abaeac..52aab5e 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -82,7 +82,9 @@ $ git reset --hard HEAD~3   <1>
 +
 <1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad
 and you do not want to ever see them again.  Do *not* do this if
-you have already given these commits to somebody else.
+you have already given these commits to somebody else.  (See the
+"RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for
+the implications of doing so.)
 
 Undo a commit, making it a topic branch::
 +
-- 
1.6.0.1.470.g200b
Thomas Rast· Sep 11, 2008, 15:39 UTC · re: Thomas Rast · lore

[RFC PATCH] Documentation: add manpage about workflows

This attempts to make a manpage about workflows that is both handy to point people at it and as a beginner's introduction.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/Makefile         |    2 +-
 Documentation/gitworkflows.txt |  326 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 327 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/gitworkflows.txt
Show changes to 2 files +327 −1

Documentation/Makefile, Documentation/gitworkflows.txt

diff --git a/Documentation/Makefile b/Documentation/Makefile
index ded0e40..e33ddcb 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
 	gitrepository-layout.txt
 MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
 	gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
-	gitdiffcore.txt
+	gitdiffcore.txt gitworkflows.txt
 
 MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
 MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
new file mode 100644
index 0000000..3462000
--- /dev/null
+++ b/Documentation/gitworkflows.txt
@@ -0,0 +1,326 @@
+gitworkflows(7)
+===============
+
+NAME
+----
+gitworkflows - An overview of recommended workflows with git
+
+SYNOPSIS
+--------
+git *
+
+
+DESCRIPTION
+-----------
+
+This tutorial gives a brief overview of workflows recommended to
+use, and collaborate with, Git.
+
+While the prose tries to motivate each of them, we formulate a set of
+'rules' for quick reference.  Do not always take them literally; you
+should value good reasons higher than following a random manpage to
+the letter.
+
+
+SEPARATE CHANGES
+----------------
+
+As a general rule, you should try to split your changes into small
+logical steps, and commit each of them.  They should be consistent,
+working independently of any later commits, pass the test suite, etc.
+
+To achieve this, try to commit your new work at least every couple
+hours.  You can always go back and edit the commits with `git rebase
+--interactive` to further improve the history before you publish it.
+
+
+MANAGING BRANCHES
+-----------------
+
+In the following, we will assume there are 'developers', 'testers' and
+'users'.  Even if the "Testers" are actually an automated test suite
+and all "Users" are developers themselves, try to think in these terms
+as you follow a software change through its life cycle.
+
+Usually a change evolves in a few steps:
+
+* The developers implement a few iterations until it "seems to work".
+
+* The testers play with it, report bugs, test the fixes, eventually
+  clearing the change for stable releases.
+
+* As the users work with the new feature, they report bugs which will
+  have to be fixed.
+
+In the following sections we discuss some problems that arise from
+such a "change flow", and how to solve them with Git.
+
+We consider a fictional project with (supported) stable branch
+'maint', main testing/development branch 'master' and "bleeding edge"
+branch 'next'.  We collectively call these three branches 'main
+branches'.
+
+
+Merging upwards
+~~~~~~~~~~~~~~~
+
+Since Git is quite good at merges, one should try to use them to
+propagate changes.  For example, if a bug is fixed, you would want to
+apply the corresponding fix to all main branches.
+
+A quick moment of thought reveals that you cannot do this by merging
+"downwards" to older releases, since that would merge 'all' changes.
+Hence the following:
+
+.Merge upwards
+[caption="Rule: "]
+=====================================
+Always commit your fixes to the oldest supported branch that require
+them.  Then (periodically) merge the main branches upwards into each
+other.
+=====================================
+
+This gives a very controlled flow of fixes.  If you notice that you
+have applied a fix to e.g. 'master' that is also required in 'maint',
+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
+downwards.  This will happen a few times and is nothing to worry about
+unless you do it all the time.
+
+
+Topic branches
+~~~~~~~~~~~~~~
+
+Any nontrivial feature will require several patches to implement, and
+may get extra bugfixes or improvements during its lifetime.  If all
+such commits were in one long linear history chain (e.g. if they were
+all committed directly to, 'master'), it becomes very hard to see how
+they belong together.
+
+The key concept here is "topic branches".  The name is pretty self
+explanatory, with a minor caveat that comes from the "merge upwards"
+rule above:
+
+.Topic branches
+[caption="Rule: "]
+=====================================
+Make a side branch for every topic. Fork it off at the oldest main
+branch that you will eventually want to merge it into.
+=====================================
+
+Many things can then be done very naturally:
+
+* To get the feature/bugfix into a main branch, simply merge it.  If
+  the topic has evolved further in the meantime, merge again.
+
+* If you find you need new features from an 'other' branch to continue
+  working on your topic, merge 'other' to 'topic'.  (However, do not
+  do this "just habitually", see below.)
+
+* If you find you forked off the wrong branch and want to move it
+  "back in time", use linkgit:git-rebase[1].
+
+Note that the last two points clash: a topic that has been merged
+elsewhere should not be rebased.  See the section on RECOVERING FROM
+UPSTREAM REBASE in linkgit:git-rebase[1].
+
+We should point out that "habitually" (regularly for no real reason)
+merging a main branch into your topics--and by extension, merging
+anything upstream into anything downstream on a regular basis--is
+frowned upon:
+
+.Merge to downstream only at well-defined points
+[caption="Rule: "]
+=====================================
+Do not merge to downstream except:
+
+* with a good reason (such as upstream API changes that affect you), or
+
+* at well-defined points such as when an upstream release has been tagged.
+=====================================
+
+Otherwise, the many resulting small merges will greatly clutter up
+history.  Anyone who later investigates the history of a file will
+have to find out whether that merge affected the topic in
+development.  Linus hates it.  An upstream might even inadvertently be
+merged into a "more stable" branch.  And so on.
+
+
+Integration branches
+~~~~~~~~~~~~~~~~~~~~
+
+If you followed the last paragraph, you will now have many small topic
+branches, and occasionally wonder how they interact.  Perhaps the
+result of merging them does not even work?  But on the other hand, we
+want to avoid merging them anywhere "stable" because such merges
+cannot easily be undone.
+
+The solution, of course, is to make a merge that we can undo: merge
+into a throw-away branch.
+
+.Integration branches
+[caption="Rule: "]
+=====================================
+To test the interaction of several topics, merge them into a
+throw-away branch.
+=====================================
+
+If you make it (very) clear that this branch is going to be deleted
+right after the testing, you can even publish this branch, for example
+to give the testers a chance to work with it, or other developers a
+chance to see if their in-progress work will be compatible.
+
+
+SHARING WORK
+------------
+
+After the last section, you should know how to manage topics.  In
+general, you will not be the only person working on the project, so
+you will have to share your work.
+
+Roughly speaking, there are two important workflows.  Their
+distinguishing mark is whether they can be used to propagate merges.
+Medium to large projects will typically employ some mixture of the
+two:
+
+* "Upstream" in the most general sense 'pushes' changes to the
+  repositor(ies) holding the main history.  Everyone can 'pull' from
+  there to stay up to date.
+
+* Frequent contributors, subsystem maintainers, etc. may use push/pull
+  to send their changes upstream.
+
+* The rest -- typically anyone more than one or two levels away from the
+  main maintainer -- send patches by mail.
+
+None of these boundaries are sharp, so find out what works best for
+you.
+
+
+Push/pull
+~~~~~~~~~
+
+There are three main tools that can be used for this:
+
+* linkgit:git-push[1] copies your branches to a remote repository,
+  usually to one that can be read by all involved parties;
+
+* linkgit:git-fetch[1] that copies remote branches to your repository;
+  and
+
+* linkgit:git-pull[1] that is fetch and merge in one go.
+
+Note the last point.  Do 'not' use 'git-pull' unless you actually want
+to merge the remote branch.
+
+Getting changes out is easy:
+
+.Push/pull: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git push <remote> <branch>` and tell everyone where they can fetch
+from.
+=====================================
+
+You will still have to tell people by other means, such as mail.  (Git
+provides the linkgit:request-pull[1] to send preformatted pull
+requests to upstream maintainers to simplify this task.)
+
+If you just want to get the newest copies of the main branches,
+staying up to date is easy too:
+
+.Push/pull: Staying up to date
+[caption="Recipe: "]
+=====================================
+Use `git fetch <remote>` or `git remote update` to stay up to date.
+=====================================
+
+Then simply fork your topic branches from the stable remotes as
+explained earlier.
+
+If you are a maintainer and would like to merge other people's topic
+branches to the main branches, they will typically send a request to
+do so by mail.  Such a request might say
+
+-------------------------------------
+Please pull from
+    git://some.server.somewhere/random/repo.git mytopic
+-------------------------------------
+
+In that case, 'git-pull' can do the fetch and merge in one go, as
+follows.
+
+.Push/pull: Merging remote topics
+[caption="Recipe: "]
+=====================================
+`git pull <url> <branch>`
+=====================================
+
+Occasionally, the maintainer may get merge conflicts when he tries to
+pull changes from downstream.  In this case, he can ask downstream to
+do the merge and resolve the conflicts themselves (perhaps they will
+know better how to react).  It is one of the rare cases where
+downstream 'should' merge from upstream.
+
+
+format-patch/am
+~~~~~~~~~~~~~~~
+
+If you are a contributor that sends changes upstream in the form of
+emails, you should use topic branches as usual (see above).  Then use
+linkgit:git-format-patch[1] to generate the corresponding emails
+(highly recommended over manually formatting them because it makes the
+maintainer's life easier).
+
+.format-patch/am: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git format-patch -M upstream..topic` and send out the resulting files.
+=====================================
+
+See the linkgit:git-format-patch[1] manpage for further usage notes.
+Also you should be aware that the maintainer may impose further
+restrictions, such as "Signed-off-by" requirements.
+
+If the maintainer tells you that your patch no longer applies to the
+current upstream, you will have to rebase your topic (you cannot use a
+merge because you cannot format-patch merges):
+
+.format-patch/am: Keeping topics up to date
+[caption="Recipe: "]
+=====================================
+`git rebase upstream`
+=====================================
+
+You can then fix the conflicts during the rebase.  Presumably you have
+not published your topic other than by mail, so rebasing it is not a
+problem.
+
+If you receive such a patch (as maintainer, or perhaps reader of the
+mailing list it was sent to), save the mail to a file and use
+'git-am':
+
+.format-patch/am: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git am < patch`
+=====================================
+
+One feature worth pointing out is the three-way merge, which can help
+if you get conflicts because of renames: `git am -3` will use index
+information contained in patches to reconstruct a merge base.  See
+linkgit:git-am[1] for other options.
+
+
+SEE ALSO
+--------
+linkgit:gittutorial[7],
+linkgit:git-push[1],
+linkgit:git-pull[1],
+linkgit:git-merge[1],
+linkgit:git-rebase[1],
+linkgit:git-format-patch[1],
+linkgit:git-am[1]
+
+GIT
+---
+Part of the linkgit:git[1] suite.
-- 
1.6.0.1.470.g200b
Jakub Narebski· Sep 11, 2008, 16:37 UTC · re: Thomas Rast · lore

Re: [RFC PATCH] Documentation: add manpage about workflows

Thomas Rast wrote:
> This attempts to make a manpage about workflows that is both handy to
> point people at it and as a beginner's introduction.
[...]
Very nice.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Thomas Rast· Sep 12, 2008, 07:26 UTC · re: Thomas Rast · lore

[RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows]

Thomas Rast wrote:
Show 7 quoted lines
> +.Merge upwards
> +[caption="Rule: "]
> +=====================================
> +Always commit your fixes to the oldest supported branch that require
> +them.  Then (periodically) merge the main branches upwards into each
> +other.
> +=====================================

Turns out that asciidoc, at least the 8.2.5 on my system, does not honour the custom caption when converting to manpages. They become numbered 'Example' blocks instead. Is there another way to get a similar result?

- Thomas
-- 
Thomas Rast
trast@student.ethz.ch
Santi Béjar· Sep 20, 2008, 00:22 UTC · re: Thomas Rast · lore

Re: [RFC PATCH] Documentation: add manpage about workflows

On Thu, Sep 11, 2008 at 5:39 PM, Thomas Rast <trast@student.ethz.ch> wrote:
Show 7 quoted lines
> This attempts to make a manpage about workflows that is both handy to
> point people at it and as a beginner's introduction.
>
> Signed-off-by: Thomas Rast <trast@student.ethz.ch>
> ---
>  Documentation/Makefile         |    2 +-
>  Documentation/gitworkflows.txt |  326 +
+++++++++++++++++++++++++++++++++++++++
It should be linked/advertised from other pages (git, tutorial, everyday?)
Show 5 quoted lines
> diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
> new file mode 100644
> index 0000000..3462000
> --- /dev/null
> +++ b/Documentation/gitworkflows.txt
[...]
> +To achieve this, try to commit your new work at least every couple
> +hours. You can always go back and edit the commits with `git rebase
> +--interactive` to further improve the history before you publish it.

I do not agree with this. I don´t much differences between a big patch and the same patch divided randomly.

To achieve this, try to commit when you are minimally satisfied with the new code or before large changes. You can always go back and edit the commits with `git rebase --interactive` to further improve the history before you publish it, or you could split a big patch as is explained in gitlink:git-stash.

Show 8 quoted lines
> +
> +
> +MANAGING BRANCHES
> +-----------------
> +
> +In the following, we will assume there are 'developers', 'testers' and
> +'users'.  Even if the "Testers" are actually an automated test suite
> +and all "Users" are developers themselves, try to think in these terms
"Testers" -> 'testers', ...
Show 19 quoted lines
> +as you follow a software change through its life cycle.
> +
> +Usually a change evolves in a few steps:
> +
> +* The developers implement a few iterations until it "seems to work".
> +
> +* The testers play with it, report bugs, test the fixes, eventually
> +  clearing the change for stable releases.
> +
> +* As the users work with the new feature, they report bugs which will
> +  have to be fixed.
> +
> +In the following sections we discuss some problems that arise from
> +such a "change flow", and how to solve them with Git.
> +
> +We consider a fictional project with (supported) stable branch
> +'maint', main testing/development branch 'master' and "bleeding edge"
> +branch 'next'.  We collectively call these three branches 'main
> +branches'.
You mention the next branch but it is not explained.
Show 11 quoted lines
> +
> +
> +Merging upwards
> +~~~~~~~~~~~~~~~
> +
> +Since Git is quite good at merges, one should try to use them to
> +propagate changes.  For example, if a bug is fixed, you would want to
> +apply the corresponding fix to all main branches.
> +
> +A quick moment of thought reveals that you cannot do this by merging
> +"downwards" to older releases, since that would merge 'all' changes.
all development changes
Show 43 quoted lines
> +Hence the following:
> +
> +.Merge upwards
> +[caption="Rule: "]
> +=====================================
> +Always commit your fixes to the oldest supported branch that require
> +them.  Then (periodically) merge the main branches upwards into each
> +other.
> +=====================================
> +
> +This gives a very controlled flow of fixes.  If you notice that you
> +have applied a fix to e.g. 'master' that is also required in 'maint',
> +you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
> +downwards.  This will happen a few times and is nothing to worry about
> +unless you do it all the time.
> +
> +
> +Topic branches
> +~~~~~~~~~~~~~~
> +
> +Any nontrivial feature will require several patches to implement, and
> +may get extra bugfixes or improvements during its lifetime.  If all
> +such commits were in one long linear history chain (e.g. if they were
> +all committed directly to, 'master'), it becomes very hard to see how
> +they belong together.
> +
> +The key concept here is "topic branches".  The name is pretty self
> +explanatory, with a minor caveat that comes from the "merge upwards"
> +rule above:
> +
> +.Topic branches
> +[caption="Rule: "]
> +=====================================
> +Make a side branch for every topic. Fork it off at the oldest main
> +branch that you will eventually want to merge it into.
> +=====================================
> +
> +Many things can then be done very naturally:
> +
> +* To get the feature/bugfix into a main branch, simply merge it.  If
> +  the topic has evolved further in the meantime, merge again.
> +
> +* If you find you need new features from an 'other' branch to continue
... from the branch 'other' to continue
Show 23 quoted lines
> +  working on your topic, merge 'other' to 'topic'.  (However, do not
> +  do this "just habitually", see below.)
> +
> +* If you find you forked off the wrong branch and want to move it
> +  "back in time", use linkgit:git-rebase[1].
> +
> +Note that the last two points clash: a topic that has been merged
> +elsewhere should not be rebased.  See the section on RECOVERING FROM
> +UPSTREAM REBASE in linkgit:git-rebase[1].
> +
> +We should point out that "habitually" (regularly for no real reason)
> +merging a main branch into your topics--and by extension, merging
> +anything upstream into anything downstream on a regular basis--is
> +frowned upon:
> +
> +.Merge to downstream only at well-defined points
> +[caption="Rule: "]
> +=====================================
> +Do not merge to downstream except:
> +
> +* with a good reason (such as upstream API changes that affect you), or
> +
> +* at well-defined points such as when an upstream release has been tagged.
Do not merge to downstream except with a good reasons:
* API changes that affect you branch
* your branch no longer merges cleanly
* when your branch is way not up-to-date.

And mainly at well-defined points, such as when an upstream release has been tagged, preferably stable release.

Show 7 quoted lines
> +=====================================
> +
> +Otherwise, the many resulting small merges will greatly clutter up
> +history.  Anyone who later investigates the history of a file will
> +have to find out whether that merge affected the topic in
> +development.  Linus hates it.  An upstream might even inadvertently be
> +merged into a "more stable" branch.  And so on.
Yes, the main point is that Linus hates it :-)
Show 36 quoted lines
> +
> +
> +Integration branches
> +~~~~~~~~~~~~~~~~~~~~
> +
> +If you followed the last paragraph, you will now have many small topic
> +branches, and occasionally wonder how they interact.  Perhaps the
> +result of merging them does not even work?  But on the other hand, we
> +want to avoid merging them anywhere "stable" because such merges
> +cannot easily be undone.
> +
> +The solution, of course, is to make a merge that we can undo: merge
> +into a throw-away branch.
> +
> +.Integration branches
> +[caption="Rule: "]
> +=====================================
> +To test the interaction of several topics, merge them into a
> +throw-away branch.
> +=====================================
> +
> +If you make it (very) clear that this branch is going to be deleted
> +right after the testing, you can even publish this branch, for example
> +to give the testers a chance to work with it, or other developers a
> +chance to see if their in-progress work will be compatible.
> +
> +
> +SHARING WORK
> +------------
> +
> +After the last section, you should know how to manage topics.  In
> +general, you will not be the only person working on the project, so
> +you will have to share your work.
> +
> +Roughly speaking, there are two important workflows.  Their
> +distinguishing mark is whether they can be used to propagate merges.
and one keeps the branch history while the other rewrite it.
> +Medium to large projects will typically employ some mixture of the
> +two:
I would remove this.
The different actors share their work as:
> +
> +* "Upstream" in the most general sense 'pushes' changes to the
> +  repositor(ies) holding the main history.  Everyone can 'pull' from
> +  there to stay up to date.
s/repositor(ies)/repository/
And:

She pull from her (trusted) downstreams, and applies the patches from the others.

> +
> +* Frequent contributors, subsystem maintainers, etc. may use push/pull
> +  to send their changes upstream.
?
Maybe:
* (Trusted) Downstreams act like the Upstreams but publish their
changes in their own repository.
Show 23 quoted lines
> +
> +* The rest -- typically anyone more than one or two levels away from the
> +  main maintainer -- send patches by mail.
> +
> +None of these boundaries are sharp, so find out what works best for
> +you.
> +
> +
> +Push/pull
> +~~~~~~~~~
> +
> +There are three main tools that can be used for this:
> +
> +* linkgit:git-push[1] copies your branches to a remote repository,
> +  usually to one that can be read by all involved parties;
> +
> +* linkgit:git-fetch[1] that copies remote branches to your repository;
> +  and
> +
> +* linkgit:git-pull[1] that is fetch and merge in one go.
> +
> +Note the last point.  Do 'not' use 'git-pull' unless you actually want
> +to merge the remote branch.
No need to repeat what is explained in the tutorial.
Show 11 quoted lines
> +
> +Getting changes out is easy:
> +
> +.Push/pull: Publishing branches/topics
> +[caption="Recipe: "]
> +=====================================
> +`git push <remote> <branch>` and tell everyone where they can fetch
> +from.
> +=====================================
> +
> +You will still have to tell people by other means, such as mail.  (Git
s/tell/inform/
> +provides the linkgit:request-pull[1] to send preformatted pull
> +requests to upstream maintainers to simplify this task.)
> +
Show 12 quoted lines
> +If you just want to get the newest copies of the main branches,
> +staying up to date is easy too:
> +
> +.Push/pull: Staying up to date
> +[caption="Recipe: "]
> +=====================================
> +Use `git fetch <remote>` or `git remote update` to stay up to date.
> +=====================================
> +
> +Then simply fork your topic branches from the stable remotes as
> +explained earlier.
> +
In tutorial.txt. And it applies to everybody (upstream, contributors,...)
Show 18 quoted lines
> +If you are a maintainer and would like to merge other people's topic
> +branches to the main branches, they will typically send a request to
> +do so by mail.  Such a request might say
> +
> +-------------------------------------
> +Please pull from
> +    git://some.server.somewhere/random/repo.git mytopic
> +-------------------------------------
> +
> +In that case, 'git-pull' can do the fetch and merge in one go, as
> +follows.
> +
> +.Push/pull: Merging remote topics
> +[caption="Recipe: "]
> +=====================================
> +`git pull <url> <branch>`
> +=====================================
> +

In tutorial. I think they are well explained in the tutorial. No need to repeat it here. You could just mentions the tools and the recipies.

Show 25 quoted lines
> +Occasionally, the maintainer may get merge conflicts when he tries to
> +pull changes from downstream.  In this case, he can ask downstream to
> +do the merge and resolve the conflicts themselves (perhaps they will
> +know better how to react).  It is one of the rare cases where
> +downstream 'should' merge from upstream.
> +
> +
> +format-patch/am
> +~~~~~~~~~~~~~~~
> +
> +If you are a contributor that sends changes upstream in the form of
> +emails, you should use topic branches as usual (see above).  Then use
> +linkgit:git-format-patch[1] to generate the corresponding emails
> +(highly recommended over manually formatting them because it makes the
> +maintainer's life easier).
> +
> +.format-patch/am: Publishing branches/topics
> +[caption="Recipe: "]
> +=====================================
> +`git format-patch -M upstream..topic` and send out the resulting files.
> +=====================================
> +
> +See the linkgit:git-format-patch[1] manpage for further usage notes.
> +Also you should be aware that the maintainer may impose further
> +restrictions, such as "Signed-off-by" requirements.
the further restrictions are not only for git-format-patch users.
Show 10 quoted lines
> +
> +If the maintainer tells you that your patch no longer applies to the
> +current upstream, you will have to rebase your topic (you cannot use a
> +merge because you cannot format-patch merges):
> +
> +.format-patch/am: Keeping topics up to date
> +[caption="Recipe: "]
> +=====================================
> +`git rebase upstream`
> +=====================================
git rebase <upstream>
Show 6 quoted lines
> +
> +You can then fix the conflicts during the rebase.  Presumably you have
> +not published your topic other than by mail, so rebasing it is not a
> +problem.
> +
> +If you receive such a patch (as maintainer, or perhaps reader of the
as a reader
Show 29 quoted lines
> +mailing list it was sent to), save the mail to a file and use
> +'git-am':
> +
> +.format-patch/am: Publishing branches/topics
> +[caption="Recipe: "]
> +=====================================
> +`git am < patch`
> +=====================================
> +
> +One feature worth pointing out is the three-way merge, which can help
> +if you get conflicts because of renames: `git am -3` will use index
> +information contained in patches to reconstruct a merge base.  See
> +linkgit:git-am[1] for other options.
> +
> +
> +SEE ALSO
> +--------
> +linkgit:gittutorial[7],
> +linkgit:git-push[1],
> +linkgit:git-pull[1],
> +linkgit:git-merge[1],
> +linkgit:git-rebase[1],
> +linkgit:git-format-patch[1],
> +linkgit:git-am[1]
> +
> +GIT
> +---
> +Part of the linkgit:git[1] suite.
> --
Santi-
Dmitry Potapov· Sep 21, 2008, 20:26 UTC · re: Thomas Rast · lore

Re: [RFC PATCH] Documentation: add manpage about workflows

On Thu, Sep 11, 2008 at 05:39:45PM +0200, Thomas Rast wrote:
> This attempts to make a manpage about workflows that is both handy to
> point people at it and as a beginner's introduction.

Thank you for your attempt. It is clearly a missing part of the Git documentation. I have a few comments to it below.

Show 6 quoted lines
> +SEPARATE CHANGES
> +----------------
> +
> +As a general rule, you should try to split your changes into small
> +logical steps, and commit each of them.  They should be consistent,
> +working independently of any later commits, pass the test suite, etc.

I would rather add some explanation why it is a good idea. Something like this:

"This makes the review process much easier, as well as, makes git bisect much more useful in finding the cause of regressions."

> +
> +To achieve this, try to commit your new work at least every couple
> +hours.  You can always go back and edit the commits with `git rebase
> +--interactive` to further improve the history before you publish it.

I like the idea of this paragraph but not its wording. Maybe this will be better (just a variant):

"To achieve this, try to split your work in small steps from the very beginning. It is always easier to squash a few commits together than splitting one big commit into a few. Don't be afraid making steps too small or that they are not perfect yet. You can always go back later and edit the commits with `git rebase --interactive` before you publish it."

Show 15 quoted lines
> +
> +MANAGING BRANCHES
> +-----------------
> +
> +In the following, we will assume there are 'developers', 'testers' and
> +'users'.  Even if the "Testers" are actually an automated test suite
> +and all "Users" are developers themselves, try to think in these terms
> +as you follow a software change through its life cycle.
> +
> +Usually a change evolves in a few steps:
> +
> +* The developers implement a few iterations until it "seems to work".
> +
> +* The testers play with it, report bugs, test the fixes, eventually
> +  clearing the change for stable releases.
Perhaps, the above two points are the most controversial in my opinion.

First, I would expect developers to implement a few iterations until it (their work) passes the automated test suite and peer review. Only then their work is merged into 'next' (or into a similar branch, which constitute that this series is published now).

Second, I am not sure what you meant by testers clears changes for stable releases, especially after you stated "Testers" may be an automated test suite. Whether some change is included is always a conscious decision of the project maintainer. The fact that some change has passed all tests successfully only clears it for including into 'next'.

Show 11 quoted lines
> +
> +* As the users work with the new feature, they report bugs which will
> +  have to be fixed.
> +
> +In the following sections we discuss some problems that arise from
> +such a "change flow", and how to solve them with Git.
> +
> +We consider a fictional project with (supported) stable branch
> +'maint', main testing/development branch 'master' and "bleeding edge"
> +branch 'next'.  We collectively call these three branches 'main
> +branches'.

The idea of 'next' is not obvious from your above explanation. When I started to learn how Git workflow works, I read something like above and was very puzzled what is the purpose of having two development branches: 'master' and 'next'. Only later I realized that it is necessary to give flexibility in making decisions of what should be included in the next stable release and what may need more "cooking" to prove their reliability and usefulness.

Show 8 quoted lines
> +
> +
> +Merging upwards
> +~~~~~~~~~~~~~~~
> +
> +Since Git is quite good at merges, one should try to use them to
> +propagate changes.  For example, if a bug is fixed, you would want to
> +apply the corresponding fix to all main branches.

The first and second sentences are a bit disconnected here. I would rather write the second one like this: "An example of such a change can be a bug fix, which should be applied to all main branches."

Another thing is that I am not sure that the provided reason for doing so ("Git is quite good at merges") is good enough. It can be said that Git is quite good at cherry-picking too. Yet, we use merge, because it allows to deal with large number of patches easier. Merge can be easily visualized and understood as every merge point means that all changes before it are included. However, to being able use merge, the developer has to start from the oldest branch that will include this change. This is a clear restriction over the anarchic nature of cherry-picking (where you can introduce a change to an arbitrary branch and then cherry-pick to others), but it pays off in the long run by better maintainability of the project. Thus the recommended practice is a strong preference to use merge over cherry-picking. It does not mean that cherry-picking should be completely excluded. Occasionally, it may be useful.

> +
> +A quick moment of thought reveals that you cannot do this by merging
> +"downwards" to older releases, since that would merge 'all' changes.

IMHO, expressions such as "a quick moment of thought reveals..." is more suitable for blogs than for serious documentation.

Show 9 quoted lines
> +Hence the following:
> +
> +.Merge upwards
> +[caption="Rule: "]
> +=====================================
> +Always commit your fixes to the oldest supported branch that require
> +them.  Then (periodically) merge the main branches upwards into each
> +other.
> +=====================================

Perhaps, it is worth to note here that a non-trivial fixes can be implemented as topic branches, which starts from the oldest branch that needs them.

Show 16 quoted lines
> +
> +This gives a very controlled flow of fixes.  If you notice that you
> +have applied a fix to e.g. 'master' that is also required in 'maint',
> +you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
> +downwards.  This will happen a few times and is nothing to worry about
> +unless you do it all the time.
> +
> +
> +Topic branches
> +~~~~~~~~~~~~~~
> +
> +Any nontrivial feature will require several patches to implement, and
> +may get extra bugfixes or improvements during its lifetime.  If all
> +such commits were in one long linear history chain (e.g. if they were
> +all committed directly to, 'master'), it becomes very hard to see how
> +they belong together.

There is a far more important reason to use topic branches than ecstatic pleasure from being able to see related changes grouped together in the history. The main reason to use topic branches is to facilitate parallel development. Though the idea that anyone commit to the main development branch ('master') is very appealing due to its simplicity, it leads to problems down the road. Namely, not all good sounding ideas turns out good in reality.

In the workflow where everyone commits to 'master' there are only two ways to deal with that. The first approach is not let developers to commit their changes until they have completely finished their work and passed all tests and code-review, and their work deemed important enough to be included in the next feature release. The second approach is to commit their work in progress in the hope that it will succeed, and if not then to rollback changes.

Neither of these two approaches is satisfactory, especially for large projects. The first approach means that developers are under a great stress due to inability to save their work in progress, they accumulate a huge patch, which is very difficult to review, often include some other changes unrelated to the stated goal, and makes the history of the project nearly useless for bisecting (linkgit:git-bisect[1]) when it comes to finding a regression. The second approach means that the project history gets contaminating with a great number of changes that eventually didn't work out. Moreover, reverting changes that are belong to some failed work may extremely difficult as other changes intervene with them. So, this reverting is hardly ever done completely in practice if it is done at all, which leads to a lot of garbage in the source code. Obviously, the history of this project is completely useless for bisecting as many commits do not really work if they are compiled at all. Also, this approach leads to an extremely long stabilization period as it is determined by the time when slowest going work will be in good shape for release.

Using topic branches immune to that problem as feature are included into 'master' when they are ready. Moreover, feature branches unless they are "publish" can go through cycles of testing, review, and interactive rebasing to edit and improve individual commits. Thus the finally published history is clean and easy to bisect.

> +
> +Roughly speaking, there are two important workflows.
I think it would make sense to name them here.
> Their
> +distinguishing mark is whether they can be used to propagate merges.

Perhaps, it would be better to say: "They are distinguished by the ability to propagate merges."

However, this is not the only distinguish between them. Besides, I am not sure how this one is connected with the rest of the paragraph:

Show 5 quoted lines
> +Medium to large projects will typically employ some mixture of the
> +two:
> +
> +* "Upstream" in the most general sense 'pushes' changes to the
> +  repositor(ies) holding the main history.

IMHO, it would be better: s/the main history/the official history of the project/

> Everyone can 'pull' from there to stay up to date.

Would that entrench the wrong idea that one needs to do 'pull' habitually? And the habitual 'pull' results in habitual 'merge'.

> +
> +* Frequent contributors, subsystem maintainers, etc. may use push/pull
> +  to send their changes upstream.

This is nitpicking, but you cannot use 'pull' to send changes. However, I suppose you meant to make your repository available for other people to pull from it.

> +
> +* The rest -- typically anyone more than one or two levels away from the
> +  main maintainer -- send patches by mail.

After reading "mixture of the two:" above, I expected these two being named, but instead I can see three points. So, it is confusing.

Show 9 quoted lines
> +If the maintainer tells you that your patch no longer applies to the
> +current upstream, you will have to rebase your topic (you cannot use a
> +merge because you cannot format-patch merges):
> +
> +.format-patch/am: Keeping topics up to date
> +[caption="Recipe: "]
> +=====================================
> +`git rebase upstream`
> +=====================================

Maybe, git pull --rebase is better advice here as it will also fetch the latest changes from the upstream.

Show 17 quoted lines
> +
> +You can then fix the conflicts during the rebase.  Presumably you have
> +not published your topic other than by mail, so rebasing it is not a
> +problem.
> +
> +If you receive such a patch (as maintainer, or perhaps reader of the
> +mailing list it was sent to), save the mail to a file and use
> +'git-am':
> +
> +.format-patch/am: Publishing branches/topics
> +[caption="Recipe: "]
> +=====================================
> +`git am < patch`
> +=====================================
> +
> +One feature worth pointing out is the three-way merge, which can help
> +if you get conflicts because of renames:

Could it not be any other reason besides renames? Maybe it is better to drop "because of renames" here.

> `git am -3` will use index
> +information contained in patches

Because the word "index" is often used in Git in the different meaning (a.k.a cache), I would re-write this sentence to avoid confusion as:

"`git am -3` will use information contained in index lines of patches"
> to reconstruct a merge base.  See

If I did not know how git am -3 works, reading this would make me think that git am somehow manage to figure out a common ancestor (commit), while it uses index lines of the patch to learn the identity of the blob that was used as the starting point to create the patch, and if this blob is available locally, git am -3 performs 3-way merge.

So, "reconstruct a merge base" is hardly appropriate here.
Dmitry
Thomas Rast· Sep 30, 2008, 16:05 UTC · re: Dmitry Potapov · lore

Re: [RFC PATCH] Documentation: add manpage about workflows

As a quick status update, mostly to show that I haven't forgotten about this topic:

Thanks Santi and Dmitry for your comments. You have raised some very good points, and I attempted to fix these issues.

Unfortunately, in some places I got stuck trying to work out good explanations for the workings of git.git, and some of the newer rearrangements left the lead of "Merging branches" in a dire state. I'll see if I can find a good solution myself, but suggestions would be welcome in any case. The WIP text is below, and I'll follow up with an interdiff to the last version.

- Thomas

--- 8< --- gitworkflows(7) ===============

NAME ---- gitworkflows - An overview of recommended workflows with git

SYNOPSIS -------- git *

DESCRIPTION -----------

This document attempts to write down and motivate some of the workflow elements used for `git.git` itself. Many ideas apply in general, though the full workflow is rarely required for smaller projects with fewer people involved.

We formulate a set of 'rules' for quick reference, while the prose tries to motivate each of them. Do not always take them literally; you should value good reasons for your actions higher than manpages such as this one.

SEPARATE CHANGES ----------------

As a general rule, you should try to split your changes into small logical steps, and commit each of them. They should be consistent, working independently of any later commits, pass the test suite, etc. This makes the review process much easier, and the history much more useful for later inspection and analysis, for example with linkgit:git-blame[1] and linkgit:git-bisect[1].

To achieve this, try to split your work into small steps from the very beginning. It is always easier to squash a few commits together than to split one big commit into several. Don't be afraid of making too small or imperfect steps along the way. You can always go back later and edit the commits with `git rebase \--interactive` before you publish them.

MANAGING BRANCHES -----------------

Usually a feature (or other change) evolves in stages: it "graduates" from patch to the testing branches and on to stable releases. During this process, it may require fixes or improvements. XXX terrible paragraph XXX

Merges (as opposed to cherry-picks, see below) greatly simplify handling large numbers of commits, so a scalable workflow needs to use merges. Fortunately Git is very good at merging.

XXX non sequitur XXX In the following sections we discuss some problems that arise from such a "change flow", and how to solve them with Git.

Graduation ~~~~~~~~~~

As a given feature goes from experimental to stable, it also "graduates" between the corresponding branches of the software. `git.git` uses the following 'main branches':

* 'master' tracks the commits that should go into the next release;
* 'maint' tracks the commits that should go into the next "maintenance
  release", i.e., update of the last released stable version; and
* 'next' is intended as a testing branch for people who like to use
  more experimental stuff.
There is a fourth official branch that is used slightly differently:
* 'pu' (proposed updates) is an integration branch for things that are
  not quite ready for inclusion yet (see "Integration Branches"
  below).

Conceptually, the feature enters at an unstable branch (usually 'next' or 'pu'), and "graduates" to 'master' for the next release once it is considered stable enough.

Merging upwards ~~~~~~~~~~~~~~~

As explained above, features conceptually "graduate downwards" to older releases. This cannot be done by actually merging downwards, however, since that would merge 'all' changes on the unstable branch into the stable one. Hence the following:

.Merge upwards [caption="Rule: "] ===================================== Always commit your fixes to the oldest supported branch that require them. Then (periodically) merge the main branches upwards into each other. =====================================

This gives a very controlled flow of fixes. If you notice that you have applied a fix to e.g. 'master' that is also required in 'maint', you will need to cherry-pick it (using linkgit:git-cherry-pick[1]) downwards. This will happen a few times and is nothing to worry about unless you do it very frequently.

Topic branches ~~~~~~~~~~~~~~

Any nontrivial feature will require several patches to implement, and may get extra bugfixes or improvements during its lifetime.

Committing everything directly on the main branches leads to many problems: Bad commits cannot be undone, so they must be reverted one by one, which creates confusing histories and further error potential when you forget to revert part of a group of changes. Working in parallel mixes up the changes, creating further confusion.

The key concept here is "topic branches". The name is pretty self explanatory, with a caveat that comes from the "merge upwards" rule above:

.Topic branches [caption="Rule: "] ===================================== Make a side branch for every topic (feature, bugfix, ...). Fork it off at the oldest main branch that you will eventually want to merge it into. =====================================

Many things can then be done very naturally:
* To get the feature/bugfix into a main branch, simply merge it.  If
  the topic has evolved further in the meantime, merge again.
* If you find you need new features from the branch 'other' to continue
  working on your topic, merge 'other' to 'topic'.  (However, do not
  do this "just habitually", see below.)
* If you find you forked off the wrong branch and want to move it
  "back in time", use linkgit:git-rebase[1].

Note that the last two points clash: a topic that has been merged elsewhere should not be rebased. See the section on RECOVERING FROM UPSTREAM REBASE in linkgit:git-rebase[1].

We should point out that "habitually" (regularly for no real reason) merging a main branch into your topics -- and by extension, merging anything upstream into anything downstream on a regular basis -- is frowned upon:

.Merge to downstream only at well-defined points [caption="Rule: "] ===================================== Do not merge to downstream except:

* with a good reason: upstream API changes affect your branch; your
  branch no longer merges to upstream cleanly; etc.
* at well-defined points such as when an upstream release has been tagged.
=====================================

Otherwise, the many resulting small merges will greatly clutter up history. Anyone who later investigates the history of a file will have to find out whether that merge affected the topic in development. An upstream might even inadvertently be merged into a "more stable" branch. And so on.

Integration branches ~~~~~~~~~~~~~~~~~~~~

If you followed the last paragraph, you will now have many small topic branches, and occasionally wonder how they interact. Perhaps the result of merging them does not even work? But on the other hand, we want to avoid merging them anywhere "stable" because such merges cannot easily be undone.

The solution, of course, is to make a merge that we can undo: merge into a throw-away branch.

.Integration branches [caption="Rule: "] ===================================== To test the interaction of several topics, merge them into a throw-away branch. =====================================

If you make it (very) clear that this branch is going to be deleted right after the testing, you can even publish this branch, for example to give the testers a chance to work with it, or other developers a chance to see if their in-progress work will be compatible. `git.git` has such an official integration branch called 'pu'. You must never base any work on such a throw-away branch!

SHARING WORK ------------

After the last section, you should know how to manage topics. In general, you will not be the only person working on the project, so you will have to share your work.

Roughly speaking, there are two important workflows: push/pull and format-patch/am. The important difference is that push/pull can propagate merges, while format-patch cannot. Medium to large projects will typically employ some mixture of the two:

* "Upstream" in the most general sense 'pushes' changes to the
  repositor(ies) holding the official history of the project.
  Everyone can 'fetch' from there to stay up to date.
* Frequent contributors, subsystem maintainers, etc. may push to a
  public repository to make their changes available to upstream.
* The rest -- typically anyone more than one or two levels away from the
  main maintainer -- send patches by mail.

None of these boundaries are sharp, so find out what works best for you.

Push/pull ~~~~~~~~~

There are three main tools that can be used for this:
* linkgit:git-push[1] copies your branches to a remote repository,
  usually to one that can be read by all involved parties;
* linkgit:git-fetch[1] that copies remote branches to your repository;
  and
* linkgit:git-pull[1] that does fetch and merge in one go.

Note the last point. Do 'not' use 'git-pull' unless you actually want to merge the remote branch.

Getting changes out is easy:

.Push/pull: Publishing branches/topics [caption="Recipe: "] ===================================== `git push <remote> <branch>` and tell everyone where they can fetch from. =====================================

You will still have to tell people by other means, such as mail. (Git provides the linkgit:request-pull[1] to send preformatted pull requests to upstream maintainers to simplify this task.)

If you just want to get the newest copies of the main branches, staying up to date is easy too:

.Push/pull: Staying up to date [caption="Recipe: "] ===================================== Use `git fetch <remote>` or `git remote update` to stay up to date. =====================================

Then simply fork your topic branches from the stable remotes as explained earlier.

If you are a maintainer and would like to merge other people's topic branches to the main branches, they will typically send a request to do so by mail. Such a request might say

-------------------------------------
Please pull from
    git://some.server.somewhere/random/repo.git mytopic
-------------------------------------

In that case, 'git-pull' can do the fetch and merge in one go, as follows.

.Push/pull: Merging remote topics [caption="Recipe: "] ===================================== `git pull <url> <branch>` =====================================

Occasionally, the maintainer may get merge conflicts when he tries to pull changes from downstream. In this case, he can ask downstream to do the merge and resolve the conflicts themselves (perhaps they will know better how to resolve them). It is one of the rare cases where downstream 'should' merge from upstream.

format-patch/am ~~~~~~~~~~~~~~~

If you are a contributor that sends changes upstream in the form of emails, you should use topic branches as usual (see above). Then use linkgit:git-format-patch[1] to generate the corresponding emails (highly recommended over manually formatting them because it makes the maintainer's life easier).

.format-patch/am: Publishing branches/topics
[caption="Recipe: "]
=====================================
* `git format-patch -M upstream..topic` to turn them into preformatted
  patch files
* `git send-email --to=<recipient> <patches>`
=====================================

See the linkgit:git-format-patch[1] and linkgit:git-send-email[1] manpages for further usage notes. Also you should be aware that the maintainer may impose further restrictions, such as "Signed-off-by" requirements.

If the maintainer tells you that your patch no longer applies to the current upstream, you will have to rebase your topic (you cannot use a merge because you cannot format-patch merges):

.format-patch/am: Keeping topics up to date [caption="Recipe: "] ===================================== `git pull --rebase <url> <branch>` =====================================

You can then fix the conflicts during the rebase. Presumably you have not published your topic other than by mail, so rebasing it is not a problem.

If you receive such a patch (as maintainer, or perhaps as a reader of the mailing list it was sent to), save the mail to a file and use 'git-am':

.format-patch/am: Publishing branches/topics [caption="Recipe: "] ===================================== `git am < patch` =====================================

One feature worth pointing out is the three-way merge, which can help if you get conflicts: `git am -3` will use index information contained in patches to figure out the merge base. See linkgit:git-am[1] for other options.

SEE ALSO -------- linkgit:gittutorial[7], linkgit:git-push[1], linkgit:git-pull[1], linkgit:git-merge[1], linkgit:git-rebase[1], linkgit:git-format-patch[1], linkgit:git-send-email[1], linkgit:git-am[1]

GIT --- Part of the linkgit:git[1] suite.

Thomas Rast· Sep 30, 2008, 16:07 UTC · re: Thomas Rast · lore

Re: [RFC PATCH] Documentation: add manpage about workflows

I wrote:
> The WIP text is below, and I'll follow up with an interdiff to the
> last version.
Show changes to Documentation/gitworkflows.txt +89 −60
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
index b4b43da..87c2270 100644
--- a/Documentation/gitworkflows.txt
+++ b/Documentation/gitworkflows.txt
@@ -13,13 +13,15 @@ git *
 DESCRIPTION
 -----------
 
-This tutorial gives a brief overview of workflows recommended to
-use, and collaborate with, Git.
+This document attempts to write down and motivate some of the workflow
+elements used for `git.git` itself.  Many ideas apply in general,
+though the full workflow is rarely required for smaller projects with
+fewer people involved.
 
-While the prose tries to motivate each of them, we formulate a set of
-'rules' for quick reference.  Do not always take them literally; you
-should value good reasons higher than following a random manpage to
-the letter.
+We formulate a set of 'rules' for quick reference, while the prose
+tries to motivate each of them.  Do not always take them literally;
+you should value good reasons for your actions higher than manpages
+such as this one.
 
 
 SEPARATE CHANGES
@@ -28,49 +30,68 @@ SEPARATE CHANGES
 As a general rule, you should try to split your changes into small
 logical steps, and commit each of them.  They should be consistent,
 working independently of any later commits, pass the test suite, etc.
+This makes the review process much easier, and the history much more
+useful for later inspection and analysis, for example with
+linkgit:git-blame[1] and linkgit:git-bisect[1].
 
-To achieve this, try to commit your new work at least every couple
-hours.  You can always go back and edit the commits with `git rebase
---interactive` to further improve the history before you publish it.
+To achieve this, try to split your work into small steps from the very
+beginning. It is always easier to squash a few commits together than
+to split one big commit into several.  Don't be afraid of making too
+small or imperfect steps along the way. You can always go back later
+and edit the commits with `git rebase \--interactive` before you
+publish them.
 
 
 MANAGING BRANCHES
 -----------------
 
-In the following, we will assume there are 'developers', 'testers' and
-'users'.  Even if the "Testers" are actually an automated test suite
-and all "Users" are developers themselves, try to think in these terms
-as you follow a software change through its life cycle.
+Usually a feature (or other change) evolves in stages: it "graduates"
+from patch to the testing branches and on to stable releases.  During
+this process, it may require fixes or improvements.  XXX terrible
+paragraph XXX
 
-Usually a change evolves in a few steps:
+Merges (as opposed to cherry-picks, see below) greatly simplify
+handling large numbers of commits, so a scalable workflow needs to use
+merges.  Fortunately Git is very good at merging.
 
-* The developers implement a few iterations until it "seems to work".
+XXX non sequitur XXX
+In the following sections we discuss some problems that arise from
+such a "change flow", and how to solve them with Git.
 
-* The testers play with it, report bugs, test the fixes, eventually
-  clearing the change for stable releases.
 
-* As the users work with the new feature, they report bugs which will
-  have to be fixed.
+Graduation
+~~~~~~~~~~
 
-In the following sections we discuss some problems that arise from
-such a "change flow", and how to solve them with Git.
+As a given feature goes from experimental to stable, it also
+"graduates" between the corresponding branches of the software.
+`git.git` uses the following 'main branches':
+
+* 'master' tracks the commits that should go into the next release;
+
+* 'maint' tracks the commits that should go into the next "maintenance
+  release", i.e., update of the last released stable version; and
 
-We consider a fictional project with (supported) stable branch
-'maint', main testing/development branch 'master' and "bleeding edge"
-branch 'next'.  We collectively call these three branches 'main
-branches'.
+* 'next' is intended as a testing branch for people who like to use
+  more experimental stuff.
+
+There is a fourth official branch that is used slightly differently:
+
+* 'pu' (proposed updates) is an integration branch for things that are
+  not quite ready for inclusion yet (see "Integration Branches"
+  below).
+
+Conceptually, the feature enters at an unstable branch (usually 'next'
+or 'pu'), and "graduates" to 'master' for the next release once it is
+considered stable enough.
 
 
 Merging upwards
 ~~~~~~~~~~~~~~~
 
-Since Git is quite good at merges, one should try to use them to
-propagate changes.  For example, if a bug is fixed, you would want to
-apply the corresponding fix to all main branches.
-
-A quick moment of thought reveals that you cannot do this by merging
-"downwards" to older releases, since that would merge 'all' changes.
-Hence the following:
+As explained above, features conceptually "graduate downwards" to
+older releases.  This cannot be done by actually merging downwards,
+however, since that would merge 'all' changes on the unstable branch
+into the stable one.  Hence the following:
 
 .Merge upwards
 [caption="Rule: "]
@@ -84,27 +105,31 @@ This gives a very controlled flow of fixes.  If you notice that you
 have applied a fix to e.g. 'master' that is also required in 'maint',
 you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
 downwards.  This will happen a few times and is nothing to worry about
-unless you do it all the time.
+unless you do it very frequently.
 
 
 Topic branches
 ~~~~~~~~~~~~~~
 
 Any nontrivial feature will require several patches to implement, and
-may get extra bugfixes or improvements during its lifetime.  If all
-such commits were in one long linear history chain (e.g., if they were
-all committed directly to 'master'), it becomes very hard to see how
-they belong together.
+may get extra bugfixes or improvements during its lifetime.
+
+Committing everything directly on the main branches leads to many
+problems: Bad commits cannot be undone, so they must be reverted one
+by one, which creates confusing histories and further error potential
+when you forget to revert part of a group of changes.  Working in
+parallel mixes up the changes, creating further confusion.
 
 The key concept here is "topic branches".  The name is pretty self
-explanatory, with a minor caveat that comes from the "merge upwards"
-rule above:
+explanatory, with a caveat that comes from the "merge upwards" rule
+above:
 
 .Topic branches
 [caption="Rule: "]
 =====================================
-Make a side branch for every topic. Fork it off at the oldest main
-branch that you will eventually want to merge it into.
+Make a side branch for every topic (feature, bugfix, ...). Fork it off
+at the oldest main branch that you will eventually want to merge it
+into.
 =====================================
 
 Many things can then be done very naturally:
@@ -112,7 +137,7 @@ Many things can then be done very naturally:
 * To get the feature/bugfix into a main branch, simply merge it.  If
   the topic has evolved further in the meantime, merge again.
 
-* If you find you need new features from an 'other' branch to continue
+* If you find you need new features from the branch 'other' to continue
   working on your topic, merge 'other' to 'topic'.  (However, do not
   do this "just habitually", see below.)
 
@@ -133,16 +158,17 @@ frowned upon:
 =====================================
 Do not merge to downstream except:
 
-* with a good reason (such as upstream API changes that affect you), or
+* with a good reason: upstream API changes affect your branch; your
+  branch no longer merges to upstream cleanly; etc.
 
 * at well-defined points such as when an upstream release has been tagged.
 =====================================
 
 Otherwise, the many resulting small merges will greatly clutter up
 history.  Anyone who later investigates the history of a file will
-have to find out whether that merge affected the topic in
-development.  Linus hates it.  An upstream might even inadvertently be
-merged into a "more stable" branch.  And so on.
+have to find out whether that merge affected the topic in development.
+An upstream might even inadvertently be merged into a "more stable"
+branch.  And so on.
 
 
 Integration branches
@@ -167,7 +193,9 @@ throw-away branch.
 If you make it (very) clear that this branch is going to be deleted
 right after the testing, you can even publish this branch, for example
 to give the testers a chance to work with it, or other developers a
-chance to see if their in-progress work will be compatible.
+chance to see if their in-progress work will be compatible.  `git.git`
+has such an official integration branch called 'pu'.  You must never
+base any work on such a throw-away branch!
 
 
 SHARING WORK
@@ -177,17 +205,17 @@ After the last section, you should know how to manage topics.  In
 general, you will not be the only person working on the project, so
 you will have to share your work.
 
-Roughly speaking, there are two important workflows.  Their
-distinguishing mark is whether they can be used to propagate merges.
-Medium to large projects will typically employ some mixture of the
-two:
+Roughly speaking, there are two important workflows: push/pull and
+format-patch/am.  The important difference is that push/pull can
+propagate merges, while format-patch cannot.  Medium to large projects
+will typically employ some mixture of the two:
 
 * "Upstream" in the most general sense 'pushes' changes to the
-  repositor(ies) holding the main history.  Everyone can 'pull' from
-  there to stay up to date.
+  repositor(ies) holding the official history of the project.
+  Everyone can 'fetch' from there to stay up to date.
 
-* Frequent contributors, subsystem maintainers, etc. may use push/pull
-  to send their changes upstream.
+* Frequent contributors, subsystem maintainers, etc. may push to a
+  public repository to make their changes available to upstream.
 
 * The rest -- typically anyone more than one or two levels away from the
   main maintainer -- send patches by mail.
@@ -291,15 +319,15 @@ merge because you cannot format-patch merges):
 .format-patch/am: Keeping topics up to date
 [caption="Recipe: "]
 =====================================
-`git rebase upstream`
+`git pull --rebase <url> <branch>`
 =====================================
 
 You can then fix the conflicts during the rebase.  Presumably you have
 not published your topic other than by mail, so rebasing it is not a
 problem.
 
-If you receive such a patch (as maintainer, or perhaps reader of the
-mailing list it was sent to), save the mail to a file and use
+If you receive such a patch (as maintainer, or perhaps as a reader of
+the mailing list it was sent to), save the mail to a file and use
 'git-am':
 
 .format-patch/am: Publishing branches/topics
@@ -309,9 +337,9 @@ mailing list it was sent to), save the mail to a file and use
 =====================================
 
 One feature worth pointing out is the three-way merge, which can help
-if you get conflicts because of renames: `git am -3` will use index
-information contained in patches to reconstruct a merge base.  See
-linkgit:git-am[1] for other options.
+if you get conflicts: `git am -3` will use index information contained
+in patches to figure out the merge base.  See linkgit:git-am[1] for
+other options.
 
 
 SEE ALSO
Santi Béjar· Oct 1, 2008, 09:54 UTC · re: Thomas Rast · lore

Re: [RFC PATCH] Documentation: add manpage about workflows

On Tue, Sep 30, 2008 at 6:05 PM, Thomas Rast <trast@student.ethz.ch> wrote:
Show 5 quoted lines
> As a quick status update, mostly to show that I haven't forgotten
> about this topic:
>
> Thanks Santi and Dmitry for your comments.  You have raised some very
> good points, and I attempted to fix these issues.
Thanks for you document.
Show 10 quoted lines
>
> Unfortunately, in some places I got stuck trying to work out good
> explanations for the workings of git.git, and some of the newer
> rearrangements left the lead of "Merging branches" in a dire state.
> I'll see if I can find a good solution myself, but suggestions would
> be welcome in any case.  The WIP text is below, and I'll follow up
> with an interdiff to the last version.
>
> - Thomas
>
[...]
Show 18 quoted lines
>
> SEPARATE CHANGES
> ----------------
>
> As a general rule, you should try to split your changes into small
> logical steps, and commit each of them.  They should be consistent,
> working independently of any later commits, pass the test suite, etc.
> This makes the review process much easier, and the history much more
> useful for later inspection and analysis, for example with
> linkgit:git-blame[1] and linkgit:git-bisect[1].
>
> To achieve this, try to split your work into small steps from the very
> beginning. It is always easier to squash a few commits together than
> to split one big commit into several.  Don't be afraid of making too
> small or imperfect steps along the way. You can always go back later
> and edit the commits with `git rebase \--interactive` before you
> publish them.
>

I know it is against the recommendation but I think it makes sense to explain how you can split big patches testing them as is explained in gitlink:git-stash.

[...]
Show 11 quoted lines
> Graduation
> ~~~~~~~~~~
>
> As a given feature goes from experimental to stable, it also
> "graduates" between the corresponding branches of the software.
> `git.git` uses the following 'main branches':
>
> * 'master' tracks the commits that should go into the next release;
>
> * 'maint' tracks the commits that should go into the next "maintenance
>  release", i.e., update of the last released stable version; and

The "logical" order would be 'maint', 'master', 'next', 'pu', each one should fast-forward to the next one.

>
> * 'next' is intended as a testing branch for people who like to use
>  more experimental stuff.

The key point is not "more experimental stuff", but 'master' material but not stable enough.

[...]
Show 25 quoted lines
> Integration branches
> ~~~~~~~~~~~~~~~~~~~~
>
> If you followed the last paragraph, you will now have many small topic
> branches, and occasionally wonder how they interact.  Perhaps the
> result of merging them does not even work?  But on the other hand, we
> want to avoid merging them anywhere "stable" because such merges
> cannot easily be undone.
>
> The solution, of course, is to make a merge that we can undo: merge
> into a throw-away branch.
>
> .Integration branches
> [caption="Rule: "]
> =====================================
> To test the interaction of several topics, merge them into a
> throw-away branch.
> =====================================
>
> If you make it (very) clear that this branch is going to be deleted
> right after the testing, you can even publish this branch, for example
> to give the testers a chance to work with it, or other developers a
> chance to see if their in-progress work will be compatible.  `git.git`
> has such an official integration branch called 'pu'. You must never
> base any work on such a throw-away branch!
Maybe this last sentence should go in the "Rule:".
Show 8 quoted lines
>
>
> SHARING WORK
> ------------
>
> After the last section, you should know how to manage topics.  In
> general, you will not be the only person working on the project, so
> you will have to share your work.

Sharing work is explained in the tutorials, maybe this section should be about "distributed workflows".

>
> Roughly speaking, there are two important workflows: push/pull and
> format-patch/am.
A more descriptive name could be the "merge workflow" and the "patch workflow".
>  The important difference is that push/pull can
> propagate merges, while format-patch cannot.

Like I said in the other mail, the key is that one preserves the history (including merges) and the other not. This is what makes possible the push/pull workflow, that all the branches should fast-forward (and this should be said somewhere)

>  Medium to large projects
> will typically employ some mixture of the two:
s/:/./
Although I think it should be deleted. And what about litle projects?
Different roles do uses different workflows:
>
> * "Upstream" in the most general sense 'pushes' changes to the
>  repositor(ies) holding the official history of the project.
>  Everyone can 'fetch' from there to stay up to date.

s/pushes/publishes/ s/fetch/merge/

>
> * Frequent contributors, subsystem maintainers, etc. may push to a
>  public repository to make their changes available to upstream.
s/push/publish/
Or:
* Frequent contributors, subsystem maintainers, etc. may publish to a
public repository to make their changes available to upstream, or to
their downstreams (acting as upstream to them)
>
> * The rest -- typically anyone more than one or two levels away from the
>  main maintainer -- send patches by mail.
In the "distributed workflows" this would be:
* "Upstream" merges the branches from subsystem maintainers, applies
the 'patches' from others (including themselves) and publishes to the
main repository. See link:howto/maintain-git.txt to see how it is done
in git.git)
* "Subsystem maintainers" act as "upstream" but publishes to a
different repository/branch.
* Frequent contributors, etc, publish their changes in another repository.
* The rest ...
Show 9 quoted lines
>
> None of these boundaries are sharp, so find out what works best for
> you.
>
>
> Push/pull
> ~~~~~~~~~
>
> There are three main tools that can be used for this:

Sorry, but I don't see the point explaining how to publish the branches, or keep them up to date.

Show 12 quoted lines
>
> If you are a maintainer and would like to merge other people's topic
> branches to the main branches, they will typically send a request to
> do so by mail.  Such a request might say
>
> -------------------------------------
> Please pull from
>    git://some.server.somewhere/random/repo.git mytopic
> -------------------------------------
>
> In that case, 'git-pull' can do the fetch and merge in one go, as
> follows.
Or:
Then, you can merge them with just:
Show 6 quoted lines
> .Push/pull: Merging remote topics
> [caption="Recipe: "]
> =====================================
> `git pull <url> <branch>`
> =====================================
>

Use "<url> <branch>" or "git://some.server.somewhere/random/repo.git mytopic" in the recipies, but not both.

[...]
>
> format-patch/am
> ~~~~~~~~~~~~~~~
s/.*/patch workflow/
Show 19 quoted lines
>
> If you are a contributor that sends changes upstream in the form of
> emails, you should use topic branches as usual (see above).  Then use
> linkgit:git-format-patch[1] to generate the corresponding emails
> (highly recommended over manually formatting them because it makes the
> maintainer's life easier).
>
> .format-patch/am: Publishing branches/topics
> [caption="Recipe: "]
> =====================================
> * `git format-patch -M upstream..topic` to turn them into preformatted
>  patch files
> * `git send-email --to=<recipient> <patches>`
> =====================================
>
> See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]
> manpages for further usage notes.  Also you should be aware that the
> maintainer may impose further restrictions, such as "Signed-off-by"
> requirements.
The restrictions and the Signed-off-by also applies to the other workflows.
Show 48 quoted lines
>
> If the maintainer tells you that your patch no longer applies to the
> current upstream, you will have to rebase your topic (you cannot use a
> merge because you cannot format-patch merges):
>
> .format-patch/am: Keeping topics up to date
> [caption="Recipe: "]
> =====================================
> `git pull --rebase <url> <branch>`
> =====================================
>
> You can then fix the conflicts during the rebase.  Presumably you have
> not published your topic other than by mail, so rebasing it is not a
> problem.
>
> If you receive such a patch (as maintainer, or perhaps as a reader of
> the mailing list it was sent to), save the mail to a file and use
> 'git-am':
>
> .format-patch/am: Publishing branches/topics
> [caption="Recipe: "]
> =====================================
> `git am < patch`
> =====================================
>
> One feature worth pointing out is the three-way merge, which can help
> if you get conflicts: `git am -3` will use index information contained
> in patches to figure out the merge base.  See linkgit:git-am[1] for
> other options.
>
>
> SEE ALSO
> --------
> linkgit:gittutorial[7],
> linkgit:git-push[1],
> linkgit:git-pull[1],
> linkgit:git-merge[1],
> linkgit:git-rebase[1],
> linkgit:git-format-patch[1],
> linkgit:git-send-email[1],
> linkgit:git-am[1]
>
> GIT
> ---
> Part of the linkgit:git[1] suite.
>
>
>
Thomas Rast· Oct 9, 2008, 11:42 UTC · re: Santi Béjar · lore

[RFC PATCH v2] Documentation: add manpage about workflows

This attempts to make a manpage about workflows that is both handy to point people at it and as a beginner's introduction.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

[Apologies if some of the Cc's were sent twice; I got a bounce because of non-ASCII headers and was unable to tell if any were delivered.]

Let's try another iteration.

I decided the "MANAGING BRANCHES" introduction paragraph was a good place to (finally) mention the points about merge vs. cherry-pick raised by Dmitry earlier.

I think I've addressed the other concerns, except for the "SHARING WORK" section, now renamed to "DISTRIBUTED WORKFLOWS":

Santi Béjar wrote:
> Sorry, but I don't see the point explaining how to publish the
> branches, or keep them up to date.

I feel it needs to be explained _somewhere_, since pull is designed to make the merge workflow as easy as possible, and then push/fetch are needed to complete the picture (especially so since I'm trying to make a point of highlighting when not to use pull). Maybe you can/want to convince me otherwise.

And note that push is not explained in gittutorial.txt, only linked. It is explained in gitcore-tutorial.txt, but that says

  However, an understanding of these low-level tools can be helpful if
  you want to understand git's internals.

in the introduction. I don't really expect any user to read any further after hearing that everything in there is "low-level". Maybe some tutorial cleanup would be in order.

Other than that, I'll wait for some more comments, then polish up the commit message and submit "for real".

Interdiff will follow, as before.
- Thomas
 Documentation/Makefile         |    2 +-
 Documentation/gitworkflows.txt |  362 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 363 insertions(+), 1 deletions(-)
Show changes to 2 files +363 −1

Documentation/Makefile, Documentation/gitworkflows.txt

diff --git a/Documentation/Makefile b/Documentation/Makefile
index ded0e40..e33ddcb 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
 	gitrepository-layout.txt
 MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
 	gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
-	gitdiffcore.txt
+	gitdiffcore.txt gitworkflows.txt
 
 MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
 MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
new file mode 100644
index 0000000..037ace5
--- /dev/null
+++ b/Documentation/gitworkflows.txt
@@ -0,0 +1,362 @@
+gitworkflows(7)
+===============
+
+NAME
+----
+gitworkflows - An overview of recommended workflows with git
+
+SYNOPSIS
+--------
+git *
+
+
+DESCRIPTION
+-----------
+
+This document attempts to write down and motivate some of the workflow
+elements used for `git.git` itself.  Many ideas apply in general,
+though the full workflow is rarely required for smaller projects with
+fewer people involved.
+
+We formulate a set of 'rules' for quick reference, while the prose
+tries to motivate each of them.  Do not always take them literally;
+you should value good reasons for your actions higher than manpages
+such as this one.
+
+
+SEPARATE CHANGES
+----------------
+
+As a general rule, you should try to split your changes into small
+logical steps, and commit each of them.  They should be consistent,
+working independently of any later commits, pass the test suite, etc.
+This makes the review process much easier, and the history much more
+useful for later inspection and analysis, for example with
+linkgit:git-blame[1] and linkgit:git-bisect[1].
+
+To achieve this, try to split your work into small steps from the very
+beginning. It is always easier to squash a few commits together than
+to split one big commit into several.  Don't be afraid of making too
+small or imperfect steps along the way. You can always go back later
+and edit the commits with `git rebase \--interactive` before you
+publish them.  You can use `git stash save \--keep-index` to run the
+test suite independent of other uncommitted changes; see the EXAMPLES
+section of linkgit:git-stash[1].
+
+
+MANAGING BRANCHES
+-----------------
+
+There are two main tools that can be used to include changes from one
+branch on another: linkgit:git-merge[1] and
+linkgit:git-cherry-pick[1].
+
+Merges have many advantages, so we try to solve as many problems as
+possible with merges alone.  Cherry-picking is still occasionally
+useful; see "Merging upwards" below for an example.
+
+Most importantly, merging works at the branch level, while
+cherry-picking works at the commit level.  This means that a merge can
+carry over the changes from 1, 10, or 1000 commits with equal ease,
+which in turn means the workflow scales much better to a large number
+of contributors (and contributions).  Merges are also easier to
+understand because a merge commit is a "promise" that all changes from
+all its parents are now included.
+
+There is a tradeoff of course: merges require a more careful branch
+management.  The following subsections discuss the important points.
+
+
+Graduation
+~~~~~~~~~~
+
+As a given feature goes from experimental to stable, it also
+"graduates" between the corresponding branches of the software.
+`git.git` uses the following 'main branches':
+
+* 'maint' tracks the commits that should go into the next "maintenance
+  release", i.e., update of the last released stable version;
+
+* 'master' tracks the commits that should go into the next release;
+
+* 'next' is intended as a testing branch for topics not stable enough
+  for master yet.
+
+There is a fourth official branch that is used slightly differently:
+
+* 'pu' (proposed updates) is an integration branch for things that are
+  not quite ready for inclusion yet (see "Integration Branches"
+  below).
+
+Each of the four branches is usually a direct descendant of the one
+above it.
+
+Conceptually, the feature enters at an unstable branch (usually 'next'
+or 'pu'), and "graduates" to 'master' for the next release once it is
+considered stable enough.
+
+
+Merging upwards
+~~~~~~~~~~~~~~~
+
+The "downwards graduation" discussed above cannot be done by actually
+merging downwards, however, since that would merge 'all' changes on
+the unstable branch into the stable one.  Hence the following:
+
+.Merge upwards
+[caption="Rule: "]
+=====================================
+Always commit your fixes to the oldest supported branch that require
+them.  Then (periodically) merge the main branches upwards into each
+other.
+=====================================
+
+This gives a very controlled flow of fixes.  If you notice that you
+have applied a fix to e.g. 'master' that is also required in 'maint',
+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
+downwards.  This will happen a few times and is nothing to worry about
+unless you do it very frequently.
+
+
+Topic branches
+~~~~~~~~~~~~~~
+
+Any nontrivial feature will require several patches to implement, and
+may get extra bugfixes or improvements during its lifetime.
+
+Committing everything directly on the main branches leads to many
+problems: Bad commits cannot be undone, so they must be reverted one
+by one, which creates confusing histories and further error potential
+when you forget to revert part of a group of changes.  Working in
+parallel mixes up the changes, creating further confusion.
+
+The key concept here is "topic branches".  The name is pretty self
+explanatory, with a caveat that comes from the "merge upwards" rule
+above:
+
+.Topic branches
+[caption="Rule: "]
+=====================================
+Make a side branch for every topic (feature, bugfix, ...). Fork it off
+at the oldest main branch that you will eventually want to merge it
+into.
+=====================================
+
+Many things can then be done very naturally:
+
+* To get the feature/bugfix into a main branch, simply merge it.  If
+  the topic has evolved further in the meantime, merge again.
+
+* If you find you need new features from the branch 'other' to continue
+  working on your topic, merge 'other' to 'topic'.  (However, do not
+  do this "just habitually", see below.)
+
+* If you find you forked off the wrong branch and want to move it
+  "back in time", use linkgit:git-rebase[1].
+
+Note that the last two points clash: a topic that has been merged
+elsewhere should not be rebased.  See the section on RECOVERING FROM
+UPSTREAM REBASE in linkgit:git-rebase[1].
+
+We should point out that "habitually" (regularly for no real reason)
+merging a main branch into your topics -- and by extension, merging
+anything upstream into anything downstream on a regular basis -- is
+frowned upon:
+
+.Merge to downstream only at well-defined points
+[caption="Rule: "]
+=====================================
+Do not merge to downstream except:
+
+* with a good reason: upstream API changes affect your branch; your
+  branch no longer merges to upstream cleanly; etc.
+
+* at well-defined points such as when an upstream release has been tagged.
+=====================================
+
+Otherwise, the many resulting small merges will greatly clutter up
+history.  Anyone who later investigates the history of a file will
+have to find out whether that merge affected the topic in development.
+An upstream might even inadvertently be merged into a "more stable"
+branch.  And so on.
+
+
+Integration branches
+~~~~~~~~~~~~~~~~~~~~
+
+If you followed the last paragraph, you will now have many small topic
+branches, and occasionally wonder how they interact.  Perhaps the
+result of merging them does not even work?  But on the other hand, we
+want to avoid merging them anywhere "stable" because such merges
+cannot easily be undone.
+
+The solution, of course, is to make a merge that we can undo: merge
+into a throw-away branch.
+
+.Integration branches
+[caption="Rule: "]
+=====================================
+To test the interaction of several topics, merge them into a
+throw-away branch.  You must never base any work on such a branch!
+=====================================
+
+If you make it (very) clear that this branch is going to be deleted
+right after the testing, you can even publish this branch, for example
+to give the testers a chance to work with it, or other developers a
+chance to see if their in-progress work will be compatible.  `git.git`
+has such an official integration branch called 'pu'.
+
+
+DISTRIBUTED WORKFLOWS
+---------------------
+
+After the last section, you should know how to manage topics.  In
+general, you will not be the only person working on the project, so
+you will have to share your work.
+
+Roughly speaking, there are two important workflows: merge and patch.
+The important difference is that the merge workflow can propagate full
+history, including merges, while patches cannot.  Both workflows can
+be used in parallel: in `git.git`, only subsystem maintainers use
+the merge workflow, while everyone else sends patches.
+
+Note that the maintainer(s) may impose restrictions, such as
+"Signed-off-by" requirements, that all commits/patches submitted for
+inclusion must adhere to.  Consult your project's documentation for
+more information.
+
+
+Merge workflow
+~~~~~~~~~~~~~~
+
+The merge workflow works by copying branches between upstream and
+downstream.  Upstream can merge contributions into the official
+history; downstream base their work on the official history.
+
+There are three main tools that can be used for this:
+
+* linkgit:git-push[1] copies your branches to a remote repository,
+  usually to one that can be read by all involved parties;
+
+* linkgit:git-fetch[1] that copies remote branches to your repository;
+  and
+
+* linkgit:git-pull[1] that does fetch and merge in one go.
+
+Note the last point.  Do 'not' use 'git-pull' unless you actually want
+to merge the remote branch.
+
+Getting changes out is easy:
+
+.Push/pull: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git push <remote> <branch>` and tell everyone where they can fetch
+from.
+=====================================
+
+You will still have to tell people by other means, such as mail.  (Git
+provides the linkgit:request-pull[1] to send preformatted pull
+requests to upstream maintainers to simplify this task.)
+
+If you just want to get the newest copies of the main branches,
+staying up to date is easy too:
+
+.Push/pull: Staying up to date
+[caption="Recipe: "]
+=====================================
+Use `git fetch <remote>` or `git remote update` to stay up to date.
+=====================================
+
+Then simply fork your topic branches from the stable remotes as
+explained earlier.
+
+If you are a maintainer and would like to merge other people's topic
+branches to the main branches, they will typically send a request to
+do so by mail.  Such a request looks like
+
+-------------------------------------
+Please pull from
+    <url> <branch>
+-------------------------------------
+
+In that case, 'git-pull' can do the fetch and merge in one go, as
+follows.
+
+.Push/pull: Merging remote topics
+[caption="Recipe: "]
+=====================================
+`git pull <url> <branch>`
+=====================================
+
+Occasionally, the maintainer may get merge conflicts when he tries to
+pull changes from downstream.  In this case, he can ask downstream to
+do the merge and resolve the conflicts themselves (perhaps they will
+know better how to resolve them).  It is one of the rare cases where
+downstream 'should' merge from upstream.
+
+
+Patch workflow
+~~~~~~~~~~~~~~
+
+If you are a contributor that sends changes upstream in the form of
+emails, you should use topic branches as usual (see above).  Then use
+linkgit:git-format-patch[1] to generate the corresponding emails
+(highly recommended over manually formatting them because it makes the
+maintainer's life easier).
+
+.format-patch/am: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+* `git format-patch -M upstream..topic` to turn them into preformatted
+  patch files
+* `git send-email --to=<recipient> <patches>`
+=====================================
+
+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]
+manpages for further usage notes.
+
+If the maintainer tells you that your patch no longer applies to the
+current upstream, you will have to rebase your topic (you cannot use a
+merge because you cannot format-patch merges):
+
+.format-patch/am: Keeping topics up to date
+[caption="Recipe: "]
+=====================================
+`git pull --rebase <url> <branch>`
+=====================================
+
+You can then fix the conflicts during the rebase.  Presumably you have
+not published your topic other than by mail, so rebasing it is not a
+problem.
+
+If you receive such a patch series (as maintainer, or perhaps as a
+reader of the mailing list it was sent to), save the mails to files,
+create a new topic branch and use 'git-am' to import the commits:
+
+.format-patch/am: Importing patches
+[caption="Recipe: "]
+=====================================
+`git am < patch`
+=====================================
+
+One feature worth pointing out is the three-way merge, which can help
+if you get conflicts: `git am -3` will use index information contained
+in patches to figure out the merge base.  See linkgit:git-am[1] for
+other options.
+
+
+SEE ALSO
+--------
+linkgit:gittutorial[7],
+linkgit:git-push[1],
+linkgit:git-pull[1],
+linkgit:git-merge[1],
+linkgit:git-rebase[1],
+linkgit:git-format-patch[1],
+linkgit:git-send-email[1],
+linkgit:git-am[1]
+
+GIT
+---
+Part of the linkgit:git[1] suite.
-- 
tg: (2de69d4..) t/doc-workflows (depends on: origin/master t/doc-rebase-warn t/doc-rebase-refer)
Thomas Rast· Oct 9, 2008, 11:42 UTC · re: Thomas Rast · lore

[Interdiff] [RFC PATCH v2] Documentation: add manpage about workflows

---
I wrote:
> Interdiff will follow, as before.
Show changes to Documentation/gitworkflows.txt +57 −52
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
index 87c2270..037ace5 100644
--- a/Documentation/gitworkflows.txt
+++ b/Documentation/gitworkflows.txt
@@ -39,24 +39,32 @@ beginning. It is always easier to squash a few commits together than
 to split one big commit into several.  Don't be afraid of making too
 small or imperfect steps along the way. You can always go back later
 and edit the commits with `git rebase \--interactive` before you
-publish them.
+publish them.  You can use `git stash save \--keep-index` to run the
+test suite independent of other uncommitted changes; see the EXAMPLES
+section of linkgit:git-stash[1].
 
 
 MANAGING BRANCHES
 -----------------
 
-Usually a feature (or other change) evolves in stages: it "graduates"
-from patch to the testing branches and on to stable releases.  During
-this process, it may require fixes or improvements.  XXX terrible
-paragraph XXX
+There are two main tools that can be used to include changes from one
+branch on another: linkgit:git-merge[1] and
+linkgit:git-cherry-pick[1].
 
-Merges (as opposed to cherry-picks, see below) greatly simplify
-handling large numbers of commits, so a scalable workflow needs to use
-merges.  Fortunately Git is very good at merging.
+Merges have many advantages, so we try to solve as many problems as
+possible with merges alone.  Cherry-picking is still occasionally
+useful; see "Merging upwards" below for an example.
 
-XXX non sequitur XXX
-In the following sections we discuss some problems that arise from
-such a "change flow", and how to solve them with Git.
+Most importantly, merging works at the branch level, while
+cherry-picking works at the commit level.  This means that a merge can
+carry over the changes from 1, 10, or 1000 commits with equal ease,
+which in turn means the workflow scales much better to a large number
+of contributors (and contributions).  Merges are also easier to
+understand because a merge commit is a "promise" that all changes from
+all its parents are now included.
+
+There is a tradeoff of course: merges require a more careful branch
+management.  The following subsections discuss the important points.
 
 
 Graduation
@@ -66,13 +74,13 @@ As a given feature goes from experimental to stable, it also
 "graduates" between the corresponding branches of the software.
 `git.git` uses the following 'main branches':
 
-* 'master' tracks the commits that should go into the next release;
-
 * 'maint' tracks the commits that should go into the next "maintenance
-  release", i.e., update of the last released stable version; and
+  release", i.e., update of the last released stable version;
 
-* 'next' is intended as a testing branch for people who like to use
-  more experimental stuff.
+* 'master' tracks the commits that should go into the next release;
+
+* 'next' is intended as a testing branch for topics not stable enough
+  for master yet.
 
 There is a fourth official branch that is used slightly differently:
 
@@ -80,6 +88,9 @@ There is a fourth official branch that is used slightly differently:
   not quite ready for inclusion yet (see "Integration Branches"
   below).
 
+Each of the four branches is usually a direct descendant of the one
+above it.
+
 Conceptually, the feature enters at an unstable branch (usually 'next'
 or 'pu'), and "graduates" to 'master' for the next release once it is
 considered stable enough.
@@ -88,10 +99,9 @@ considered stable enough.
 Merging upwards
 ~~~~~~~~~~~~~~~
 
-As explained above, features conceptually "graduate downwards" to
-older releases.  This cannot be done by actually merging downwards,
-however, since that would merge 'all' changes on the unstable branch
-into the stable one.  Hence the following:
+The "downwards graduation" discussed above cannot be done by actually
+merging downwards, however, since that would merge 'all' changes on
+the unstable branch into the stable one.  Hence the following:
 
 .Merge upwards
 [caption="Rule: "]
@@ -187,45 +197,41 @@ into a throw-away branch.
 [caption="Rule: "]
 =====================================
 To test the interaction of several topics, merge them into a
-throw-away branch.
+throw-away branch.  You must never base any work on such a branch!
 =====================================
 
 If you make it (very) clear that this branch is going to be deleted
 right after the testing, you can even publish this branch, for example
 to give the testers a chance to work with it, or other developers a
 chance to see if their in-progress work will be compatible.  `git.git`
-has such an official integration branch called 'pu'.  You must never
-base any work on such a throw-away branch!
+has such an official integration branch called 'pu'.
 
 
-SHARING WORK
-------------
+DISTRIBUTED WORKFLOWS
+---------------------
 
 After the last section, you should know how to manage topics.  In
 general, you will not be the only person working on the project, so
 you will have to share your work.
 
-Roughly speaking, there are two important workflows: push/pull and
-format-patch/am.  The important difference is that push/pull can
-propagate merges, while format-patch cannot.  Medium to large projects
-will typically employ some mixture of the two:
+Roughly speaking, there are two important workflows: merge and patch.
+The important difference is that the merge workflow can propagate full
+history, including merges, while patches cannot.  Both workflows can
+be used in parallel: in `git.git`, only subsystem maintainers use
+the merge workflow, while everyone else sends patches.
 
-* "Upstream" in the most general sense 'pushes' changes to the
-  repositor(ies) holding the official history of the project.
-  Everyone can 'fetch' from there to stay up to date.
+Note that the maintainer(s) may impose restrictions, such as
+"Signed-off-by" requirements, that all commits/patches submitted for
+inclusion must adhere to.  Consult your project's documentation for
+more information.
 
-* Frequent contributors, subsystem maintainers, etc. may push to a
-  public repository to make their changes available to upstream.
-
-* The rest -- typically anyone more than one or two levels away from the
-  main maintainer -- send patches by mail.
-
-None of these boundaries are sharp, so find out what works best for
-you.
 
+Merge workflow
+~~~~~~~~~~~~~~
 
-Push/pull
-~~~~~~~~~
+The merge workflow works by copying branches between upstream and
+downstream.  Upstream can merge contributions into the official
+history; downstream base their work on the official history.
 
 There are three main tools that can be used for this:
 
@@ -267,11 +273,11 @@ explained earlier.
 
 If you are a maintainer and would like to merge other people's topic
 branches to the main branches, they will typically send a request to
-do so by mail.  Such a request might say
+do so by mail.  Such a request looks like
 
 -------------------------------------
 Please pull from
-    git://some.server.somewhere/random/repo.git mytopic
+    <url> <branch>
 -------------------------------------
 
 In that case, 'git-pull' can do the fetch and merge in one go, as
@@ -290,8 +296,8 @@ know better how to resolve them).  It is one of the rare cases where
 downstream 'should' merge from upstream.
 
 
-format-patch/am
-~~~~~~~~~~~~~~~
+Patch workflow
+~~~~~~~~~~~~~~
 
 If you are a contributor that sends changes upstream in the form of
 emails, you should use topic branches as usual (see above).  Then use
@@ -308,9 +314,7 @@ maintainer's life easier).
 =====================================
 
 See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]
-manpages for further usage notes.  Also you should be aware that the
-maintainer may impose further restrictions, such as "Signed-off-by"
-requirements.
+manpages for further usage notes.
 
 If the maintainer tells you that your patch no longer applies to the
 current upstream, you will have to rebase your topic (you cannot use a
@@ -326,11 +330,11 @@ You can then fix the conflicts during the rebase.  Presumably you have
 not published your topic other than by mail, so rebasing it is not a
 problem.
 
-If you receive such a patch (as maintainer, or perhaps as a reader of
-the mailing list it was sent to), save the mail to a file and use
-'git-am':
+If you receive such a patch series (as maintainer, or perhaps as a
+reader of the mailing list it was sent to), save the mails to files,
+create a new topic branch and use 'git-am' to import the commits:
 
-.format-patch/am: Publishing branches/topics
+.format-patch/am: Importing patches
 [caption="Recipe: "]
 =====================================
 `git am < patch`
Junio C Hamano· Oct 9, 2008, 12:50 UTC · re: Thomas Rast · lore

Re: [RFC PATCH v2] Documentation: add manpage about workflows

Thomas Rast <trast@student.ethz.ch> writes:
Show 16 quoted lines
> diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
> new file mode 100644
> index 0000000..037ace5
> --- /dev/null
> +++ b/Documentation/gitworkflows.txt
> @@ -0,0 +1,362 @@
> +gitworkflows(7)
> +===============
> ...
> +DESCRIPTION
> +-----------
> +
> +This document attempts to write down and motivate some of the workflow
> +elements used for `git.git` itself.  Many ideas apply in general,
> +though the full workflow is rarely required for smaller projects with
> +fewer people involved.

Hmm. Even though I have to wonder if the workflow used in git.git should be treated as a representative BCP. For one thing, git.git is on the smaller end of the spectrum (from the point of view of the size of the codebase, but not from the size of the contributor base), it is something we know well enough and probably is a good place to take examples from.

Show 14 quoted lines
> +Graduation
> +~~~~~~~~~~
> +
> +As a given feature goes from experimental to stable, it also
> +"graduates" between the corresponding branches of the software.
> +`git.git` uses the following 'main branches':
> +
> +* 'maint' tracks the commits that should go into the next "maintenance
> +  release", i.e., update of the last released stable version;
> +
> +* 'master' tracks the commits that should go into the next release;
> +
> +* 'next' is intended as a testing branch for topics not stable enough
> +  for master yet.
s/not stable enough/being tested for stability/;s/ yet//;

The point being that commits on next are deemed stable enough from code inspection but are kept out of master for a while because your maintainer wants to be extra careful.

Show 15 quoted lines
> +Topic branches
> +~~~~~~~~~~~~~~
> +
> +Any nontrivial feature will require several patches to implement, and
> +may get extra bugfixes or improvements during its lifetime.
> +
> +Committing everything directly on the main branches leads to many
> +problems: Bad commits cannot be undone, so they must be reverted one
> +by one, which creates confusing histories and further error potential
> +when you forget to revert part of a group of changes.  Working in
> +parallel mixes up the changes, creating further confusion.
> +
> +The key concept here is "topic branches".  The name is pretty self
> +explanatory, with a caveat that comes from the "merge upwards" rule
> +above:

I'd reword the first sentence --- Use of "Topic branches" solves these problems.

Show 19 quoted lines
> +We should point out that "habitually" (regularly for no real reason)
> +merging a main branch into your topics -- and by extension, merging
> +anything upstream into anything downstream on a regular basis -- is
> +frowned upon:
> +
> +.Merge to downstream only at well-defined points
> +[caption="Rule: "]
> +=====================================
> +Do not merge to downstream except:
> +
> +* with a good reason: upstream API changes affect your branch; your
> +  branch no longer merges to upstream cleanly; etc.
> +
> +* at well-defined points such as when an upstream release has been tagged.
> +=====================================
> +
> +Otherwise, the many resulting small merges will greatly clutter up
> +history.  Anyone who later investigates the history of a file will
> +have to find out whether that merge affected the topic in development.

This description misses the most important reason why merging into topic branches is not a good idea. Once you merge a general purpose integration branch such as master into a topic branch, the branch ceases to be about the single topic. It becomes "the topic and other unrelated changes mixed together".

> +Integration branches
> +~~~~~~~~~~~~~~~~~~~~

Nomenclature. I think we use the word "integration branches" to mean the stable branches such as maint/master/next, not the ones you use for throw-away test merges.

Always merging upward is a good rule, and this is when used with topic branches, there is one twist you did not mention but is worth knowing about. A topic that is meant to eventually merge into older integration branch (e.g. maint) does not necessarily have to be merged to its final destination branch first. I often do this:

	git checkout tr/maint-fix-bla maint
        git am -s fix-mail-from-thomas.txt
        git checkout next
        git merge tr/maint-fix-bla
        ... cook further, perhaps adding more commits to
        ... tr/maint-fix-bla topic and merging the result to next;
	... and then when the topic appears to be stable do:
	git checkout master
        git merge tr/maint-fix-bla
	... and later
        git checkout maint
        git merge tr/maint-fix-bla
	git branch -d tr/maint-fix-bla

This keeps older integration branches stale, until the topic really gets proven to be regression-free in the field. This workflow is safer and more suitable for a final integration branch to which a known breakage is better than an unintended regression. An alternative would be what the reader would assume from your description of merging upwards, which would look like this:

	git checkout tr/maint-fix-bla maint
        git am -s fix-mail-from-thomas.txt
        git checkout maint
        git merge tr/maint-fix-bla
	git checkout master
        git merge maint
        git checkout next
	git merge master

This can regress maint unintentionally and then the regression is propagated upwards to contaminate all integration branches.

Thomas Rast· Oct 19, 2008, 15:20 UTC · re: Junio C Hamano · lore

[RFC PATCH v3] Documentation: add manpage about workflows

This attempts to make a manpage about workflows that is both handy to point people at it and as a beginner's introduction.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
Show 6 quoted lines
> > +Integration branches
> > +~~~~~~~~~~~~~~~~~~~~
> 
> Nomenclature.  I think we use the word "integration branches" to mean the
> stable branches such as maint/master/next, not the ones you use for
> throw-away test merges.

I renamed those, and now call 'pu' a "throw-away integration branch", which is sort of unwieldy but I can't think of a good short name.

Full interdiff follows, as before.
 Documentation/Makefile         |    2 +-
 Documentation/gitworkflows.txt |  364 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 365 insertions(+), 1 deletions(-)
Show changes to 2 files +365 −1

Documentation/Makefile, Documentation/gitworkflows.txt

diff --git a/Documentation/Makefile b/Documentation/Makefile
index ded0e40..e33ddcb 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
 	gitrepository-layout.txt
 MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
 	gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
-	gitdiffcore.txt
+	gitdiffcore.txt gitworkflows.txt
 
 MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
 MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
new file mode 100644
index 0000000..7fe9f72
--- /dev/null
+++ b/Documentation/gitworkflows.txt
@@ -0,0 +1,364 @@
+gitworkflows(7)
+===============
+
+NAME
+----
+gitworkflows - An overview of recommended workflows with git
+
+SYNOPSIS
+--------
+git *
+
+
+DESCRIPTION
+-----------
+
+This document attempts to write down and motivate some of the workflow
+elements used for `git.git` itself.  Many ideas apply in general,
+though the full workflow is rarely required for smaller projects with
+fewer people involved.
+
+We formulate a set of 'rules' for quick reference, while the prose
+tries to motivate each of them.  Do not always take them literally;
+you should value good reasons for your actions higher than manpages
+such as this one.
+
+
+SEPARATE CHANGES
+----------------
+
+As a general rule, you should try to split your changes into small
+logical steps, and commit each of them.  They should be consistent,
+working independently of any later commits, pass the test suite, etc.
+This makes the review process much easier, and the history much more
+useful for later inspection and analysis, for example with
+linkgit:git-blame[1] and linkgit:git-bisect[1].
+
+To achieve this, try to split your work into small steps from the very
+beginning. It is always easier to squash a few commits together than
+to split one big commit into several.  Don't be afraid of making too
+small or imperfect steps along the way. You can always go back later
+and edit the commits with `git rebase \--interactive` before you
+publish them.  You can use `git stash save \--keep-index` to run the
+test suite independent of other uncommitted changes; see the EXAMPLES
+section of linkgit:git-stash[1].
+
+
+MANAGING BRANCHES
+-----------------
+
+There are two main tools that can be used to include changes from one
+branch on another: linkgit:git-merge[1] and
+linkgit:git-cherry-pick[1].
+
+Merges have many advantages, so we try to solve as many problems as
+possible with merges alone.  Cherry-picking is still occasionally
+useful; see "Merging upwards" below for an example.
+
+Most importantly, merging works at the branch level, while
+cherry-picking works at the commit level.  This means that a merge can
+carry over the changes from 1, 10, or 1000 commits with equal ease,
+which in turn means the workflow scales much better to a large number
+of contributors (and contributions).  Merges are also easier to
+understand because a merge commit is a "promise" that all changes from
+all its parents are now included.
+
+There is a tradeoff of course: merges require a more careful branch
+management.  The following subsections discuss the important points.
+
+
+Graduation
+~~~~~~~~~~
+
+As a given feature goes from experimental to stable, it also
+"graduates" between the corresponding branches of the software.
+`git.git` uses the following 'integration branches':
+
+* 'maint' tracks the commits that should go into the next "maintenance
+  release", i.e., update of the last released stable version;
+
+* 'master' tracks the commits that should go into the next release;
+
+* 'next' is intended as a testing branch for topics being tested for
+  stability for master.
+
+There is a fourth official branch that is used slightly differently:
+
+* 'pu' (proposed updates) is an integration branch for things that are
+  not quite ready for inclusion yet (see "Integration Branches"
+  below).
+
+Each of the four branches is usually a direct descendant of the one
+above it.
+
+Conceptually, the feature enters at an unstable branch (usually 'next'
+or 'pu'), and "graduates" to 'master' for the next release once it is
+considered stable enough.
+
+
+Merging upwards
+~~~~~~~~~~~~~~~
+
+The "downwards graduation" discussed above cannot be done by actually
+merging downwards, however, since that would merge 'all' changes on
+the unstable branch into the stable one.  Hence the following:
+
+.Merge upwards
+[caption="Rule: "]
+=====================================
+Always commit your fixes to the oldest supported branch that require
+them.  Then (periodically) merge the integration branches upwards into each
+other.
+=====================================
+
+This gives a very controlled flow of fixes.  If you notice that you
+have applied a fix to e.g. 'master' that is also required in 'maint',
+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
+downwards.  This will happen a few times and is nothing to worry about
+unless you do it very frequently.
+
+
+Topic branches
+~~~~~~~~~~~~~~
+
+Any nontrivial feature will require several patches to implement, and
+may get extra bugfixes or improvements during its lifetime.
+
+Committing everything directly on the integration branches leads to many
+problems: Bad commits cannot be undone, so they must be reverted one
+by one, which creates confusing histories and further error potential
+when you forget to revert part of a group of changes.  Working in
+parallel mixes up the changes, creating further confusion.
+
+Use of "topic branches" solves these problems.  The name is pretty
+self explanatory, with a caveat that comes from the "merge upwards"
+rule above:
+
+.Topic branches
+[caption="Rule: "]
+=====================================
+Make a side branch for every topic (feature, bugfix, ...). Fork it off
+at the oldest integration branch that you will eventually want to merge it
+into.
+=====================================
+
+Many things can then be done very naturally:
+
+* To get the feature/bugfix into an integration branch, simply merge
+  it.  If the topic has evolved further in the meantime, merge again.
+  (Note that you do not necessarily have to merge it to the oldest
+  integration branch first.  For example, you can first merge a bugfix
+  to 'next', give it some testing time, and merge to 'maint' when you
+  know it is stable.)
+
+* If you find you need new features from the branch 'other' to continue
+  working on your topic, merge 'other' to 'topic'.  (However, do not
+  do this "just habitually", see below.)
+
+* If you find you forked off the wrong branch and want to move it
+  "back in time", use linkgit:git-rebase[1].
+
+Note that the last point clashes with the other two: a topic that has
+been merged elsewhere should not be rebased.  See the section on
+RECOVERING FROM UPSTREAM REBASE in linkgit:git-rebase[1].
+
+We should point out that "habitually" (regularly for no real reason)
+merging an integration branch into your topics -- and by extension,
+merging anything upstream into anything downstream on a regular basis
+-- is frowned upon:
+
+.Merge to downstream only at well-defined points
+[caption="Rule: "]
+=====================================
+Do not merge to downstream except with a good reason: upstream API
+changes affect your branch; your branch no longer merges to upstream
+cleanly; etc.
+=====================================
+
+Otherwise, the topic that was merged to suddenly contains more than a
+single (well-separated) change.  The many resulting small merges will
+greatly clutter up history.  Anyone who later investigates the history
+of a file will have to find out whether that merge affected the topic
+in development.  An upstream might even inadvertently be merged into a
+"more stable" branch.  And so on.
+
+
+Throw-away integration
+~~~~~~~~~~~~~~~~~~~~~~
+
+If you followed the last paragraph, you will now have many small topic
+branches, and occasionally wonder how they interact.  Perhaps the
+result of merging them does not even work?  But on the other hand, we
+want to avoid merging them anywhere "stable" because such merges
+cannot easily be undone.
+
+The solution, of course, is to make a merge that we can undo: merge
+into a throw-away branch.
+
+.Throw-away integration branches
+[caption="Rule: "]
+=====================================
+To test the interaction of several topics, merge them into a
+throw-away branch.  You must never base any work on such a branch!
+=====================================
+
+If you make it (very) clear that this branch is going to be deleted
+right after the testing, you can even publish this branch, for example
+to give the testers a chance to work with it, or other developers a
+chance to see if their in-progress work will be compatible.  `git.git`
+has such an official throw-away integration branch called 'pu'.
+
+
+DISTRIBUTED WORKFLOWS
+---------------------
+
+After the last section, you should know how to manage topics.  In
+general, you will not be the only person working on the project, so
+you will have to share your work.
+
+Roughly speaking, there are two important workflows: merge and patch.
+The important difference is that the merge workflow can propagate full
+history, including merges, while patches cannot.  Both workflows can
+be used in parallel: in `git.git`, only subsystem maintainers use
+the merge workflow, while everyone else sends patches.
+
+Note that the maintainer(s) may impose restrictions, such as
+"Signed-off-by" requirements, that all commits/patches submitted for
+inclusion must adhere to.  Consult your project's documentation for
+more information.
+
+
+Merge workflow
+~~~~~~~~~~~~~~
+
+The merge workflow works by copying branches between upstream and
+downstream.  Upstream can merge contributions into the official
+history; downstream base their work on the official history.
+
+There are three main tools that can be used for this:
+
+* linkgit:git-push[1] copies your branches to a remote repository,
+  usually to one that can be read by all involved parties;
+
+* linkgit:git-fetch[1] that copies remote branches to your repository;
+  and
+
+* linkgit:git-pull[1] that does fetch and merge in one go.
+
+Note the last point.  Do 'not' use 'git-pull' unless you actually want
+to merge the remote branch.
+
+Getting changes out is easy:
+
+.Push/pull: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git push <remote> <branch>` and tell everyone where they can fetch
+from.
+=====================================
+
+You will still have to tell people by other means, such as mail.  (Git
+provides the linkgit:request-pull[1] to send preformatted pull
+requests to upstream maintainers to simplify this task.)
+
+If you just want to get the newest copies of the integration branches,
+staying up to date is easy too:
+
+.Push/pull: Staying up to date
+[caption="Recipe: "]
+=====================================
+Use `git fetch <remote>` or `git remote update` to stay up to date.
+=====================================
+
+Then simply fork your topic branches from the stable remotes as
+explained earlier.
+
+If you are a maintainer and would like to merge other people's topic
+branches to the integration branches, they will typically send a
+request to do so by mail.  Such a request looks like
+
+-------------------------------------
+Please pull from
+    <url> <branch>
+-------------------------------------
+
+In that case, 'git-pull' can do the fetch and merge in one go, as
+follows.
+
+.Push/pull: Merging remote topics
+[caption="Recipe: "]
+=====================================
+`git pull <url> <branch>`
+=====================================
+
+Occasionally, the maintainer may get merge conflicts when he tries to
+pull changes from downstream.  In this case, he can ask downstream to
+do the merge and resolve the conflicts themselves (perhaps they will
+know better how to resolve them).  It is one of the rare cases where
+downstream 'should' merge from upstream.
+
+
+Patch workflow
+~~~~~~~~~~~~~~
+
+If you are a contributor that sends changes upstream in the form of
+emails, you should use topic branches as usual (see above).  Then use
+linkgit:git-format-patch[1] to generate the corresponding emails
+(highly recommended over manually formatting them because it makes the
+maintainer's life easier).
+
+.format-patch/am: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+* `git format-patch -M upstream..topic` to turn them into preformatted
+  patch files
+* `git send-email --to=<recipient> <patches>`
+=====================================
+
+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]
+manpages for further usage notes.
+
+If the maintainer tells you that your patch no longer applies to the
+current upstream, you will have to rebase your topic (you cannot use a
+merge because you cannot format-patch merges):
+
+.format-patch/am: Keeping topics up to date
+[caption="Recipe: "]
+=====================================
+`git pull --rebase <url> <branch>`
+=====================================
+
+You can then fix the conflicts during the rebase.  Presumably you have
+not published your topic other than by mail, so rebasing it is not a
+problem.
+
+If you receive such a patch series (as maintainer, or perhaps as a
+reader of the mailing list it was sent to), save the mails to files,
+create a new topic branch and use 'git-am' to import the commits:
+
+.format-patch/am: Importing patches
+[caption="Recipe: "]
+=====================================
+`git am < patch`
+=====================================
+
+One feature worth pointing out is the three-way merge, which can help
+if you get conflicts: `git am -3` will use index information contained
+in patches to figure out the merge base.  See linkgit:git-am[1] for
+other options.
+
+
+SEE ALSO
+--------
+linkgit:gittutorial[7],
+linkgit:git-push[1],
+linkgit:git-pull[1],
+linkgit:git-merge[1],
+linkgit:git-rebase[1],
+linkgit:git-format-patch[1],
+linkgit:git-send-email[1],
+linkgit:git-am[1]
+
+GIT
+---
+Part of the linkgit:git[1] suite.
-- 
tg: (50ea8e5..) t/doc-workflows (depends on: origin/master t/doc-rebase-warn t/doc-rebase-refer)
Thomas Rast· Oct 19, 2008, 15:20 UTC · re: Thomas Rast · lore

[Interdiff] [RFC PATCH v3] Documentation: add manpage about workflows

---
 Documentation/gitworkflows.txt |   72 ++++++++++++++++++++-------------------
 1 files changed, 37 insertions(+), 35 deletions(-)
Show changes to Documentation/gitworkflows.txt +37 −35
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
index 037ace5..7fe9f72 100644
--- a/Documentation/gitworkflows.txt
+++ b/Documentation/gitworkflows.txt
@@ -72,15 +72,15 @@ Graduation
 
 As a given feature goes from experimental to stable, it also
 "graduates" between the corresponding branches of the software.
-`git.git` uses the following 'main branches':
+`git.git` uses the following 'integration branches':
 
 * 'maint' tracks the commits that should go into the next "maintenance
   release", i.e., update of the last released stable version;
 
 * 'master' tracks the commits that should go into the next release;
 
-* 'next' is intended as a testing branch for topics not stable enough
-  for master yet.
+* 'next' is intended as a testing branch for topics being tested for
+  stability for master.
 
 There is a fourth official branch that is used slightly differently:
 
@@ -107,7 +107,7 @@ the unstable branch into the stable one.  Hence the following:
 [caption="Rule: "]
 =====================================
 Always commit your fixes to the oldest supported branch that require
-them.  Then (periodically) merge the main branches upwards into each
+them.  Then (periodically) merge the integration branches upwards into each
 other.
 =====================================
 
@@ -124,28 +124,32 @@ Topic branches
 Any nontrivial feature will require several patches to implement, and
 may get extra bugfixes or improvements during its lifetime.
 
-Committing everything directly on the main branches leads to many
+Committing everything directly on the integration branches leads to many
 problems: Bad commits cannot be undone, so they must be reverted one
 by one, which creates confusing histories and further error potential
 when you forget to revert part of a group of changes.  Working in
 parallel mixes up the changes, creating further confusion.
 
-The key concept here is "topic branches".  The name is pretty self
-explanatory, with a caveat that comes from the "merge upwards" rule
-above:
+Use of "topic branches" solves these problems.  The name is pretty
+self explanatory, with a caveat that comes from the "merge upwards"
+rule above:
 
 .Topic branches
 [caption="Rule: "]
 =====================================
 Make a side branch for every topic (feature, bugfix, ...). Fork it off
-at the oldest main branch that you will eventually want to merge it
+at the oldest integration branch that you will eventually want to merge it
 into.
 =====================================
 
 Many things can then be done very naturally:
 
-* To get the feature/bugfix into a main branch, simply merge it.  If
-  the topic has evolved further in the meantime, merge again.
+* To get the feature/bugfix into an integration branch, simply merge
+  it.  If the topic has evolved further in the meantime, merge again.
+  (Note that you do not necessarily have to merge it to the oldest
+  integration branch first.  For example, you can first merge a bugfix
+  to 'next', give it some testing time, and merge to 'maint' when you
+  know it is stable.)
 
 * If you find you need new features from the branch 'other' to continue
   working on your topic, merge 'other' to 'topic'.  (However, do not
@@ -154,35 +158,33 @@ Many things can then be done very naturally:
 * If you find you forked off the wrong branch and want to move it
   "back in time", use linkgit:git-rebase[1].
 
-Note that the last two points clash: a topic that has been merged
-elsewhere should not be rebased.  See the section on RECOVERING FROM
-UPSTREAM REBASE in linkgit:git-rebase[1].
+Note that the last point clashes with the other two: a topic that has
+been merged elsewhere should not be rebased.  See the section on
+RECOVERING FROM UPSTREAM REBASE in linkgit:git-rebase[1].
 
 We should point out that "habitually" (regularly for no real reason)
-merging a main branch into your topics -- and by extension, merging
-anything upstream into anything downstream on a regular basis -- is
-frowned upon:
+merging an integration branch into your topics -- and by extension,
+merging anything upstream into anything downstream on a regular basis
+-- is frowned upon:
 
 .Merge to downstream only at well-defined points
 [caption="Rule: "]
 =====================================
-Do not merge to downstream except:
-
-* with a good reason: upstream API changes affect your branch; your
-  branch no longer merges to upstream cleanly; etc.
-
-* at well-defined points such as when an upstream release has been tagged.
+Do not merge to downstream except with a good reason: upstream API
+changes affect your branch; your branch no longer merges to upstream
+cleanly; etc.
 =====================================
 
-Otherwise, the many resulting small merges will greatly clutter up
-history.  Anyone who later investigates the history of a file will
-have to find out whether that merge affected the topic in development.
-An upstream might even inadvertently be merged into a "more stable"
-branch.  And so on.
+Otherwise, the topic that was merged to suddenly contains more than a
+single (well-separated) change.  The many resulting small merges will
+greatly clutter up history.  Anyone who later investigates the history
+of a file will have to find out whether that merge affected the topic
+in development.  An upstream might even inadvertently be merged into a
+"more stable" branch.  And so on.
 
 
-Integration branches
-~~~~~~~~~~~~~~~~~~~~
+Throw-away integration
+~~~~~~~~~~~~~~~~~~~~~~
 
 If you followed the last paragraph, you will now have many small topic
 branches, and occasionally wonder how they interact.  Perhaps the
@@ -193,7 +195,7 @@ cannot easily be undone.
 The solution, of course, is to make a merge that we can undo: merge
 into a throw-away branch.
 
-.Integration branches
+.Throw-away integration branches
 [caption="Rule: "]
 =====================================
 To test the interaction of several topics, merge them into a
@@ -204,7 +206,7 @@ If you make it (very) clear that this branch is going to be deleted
 right after the testing, you can even publish this branch, for example
 to give the testers a chance to work with it, or other developers a
 chance to see if their in-progress work will be compatible.  `git.git`
-has such an official integration branch called 'pu'.
+has such an official throw-away integration branch called 'pu'.
 
 
 DISTRIBUTED WORKFLOWS
@@ -259,7 +261,7 @@ You will still have to tell people by other means, such as mail.  (Git
 provides the linkgit:request-pull[1] to send preformatted pull
 requests to upstream maintainers to simplify this task.)
 
-If you just want to get the newest copies of the main branches,
+If you just want to get the newest copies of the integration branches,
 staying up to date is easy too:
 
 .Push/pull: Staying up to date
@@ -272,8 +274,8 @@ Then simply fork your topic branches from the stable remotes as
 explained earlier.
 
 If you are a maintainer and would like to merge other people's topic
-branches to the main branches, they will typically send a request to
-do so by mail.  Such a request looks like
+branches to the integration branches, they will typically send a
+request to do so by mail.  Such a request looks like
 
 -------------------------------------
 Please pull from
-- 
1.6.0.2.916.g8e7f4
Junio C Hamano· Oct 19, 2008, 20:07 UTC · re: Thomas Rast · lore

Re: [RFC PATCH v3] Documentation: add manpage about workflows

Thomas Rast <trast@student.ethz.ch> writes:
> This attempts to make a manpage about workflows that is both handy to
> point people at it and as a beginner's introduction.
Is this still "RFC PATCH" or meant for application?

I did not find many things that I find objectionable. On the other hand, I am not a good person to judge if this documentation is easily understandable by beginners (anymore). Do others who interact regularly with new people have comments?

Marcus Griep· Sep 12, 2008, 01:15 UTC · re: Thomas Rast · lore

Re: [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase

Thomas Rast wrote:
> +Now suppose the 'subsystem' maintainer decides to clean up his history
> +with an interactive rebase.  He edits commits A and D (marked with a
> +`*`), decides to remove D entirely and moves B to the front.  This
> +results in

Minor correction: -+with an interactive rebase. He edits commits A and D (marked with a ++with an interactive rebase. He edits commits A and C (marked with a

Show 10 quoted lines
> +To fix this, you have to manually transplant your own part of the
> +history to the new branch head.  Looking at `git log`, you should be
> +able to determine that three commits on 'topic' are yours.  Again
> +assuming you are already on 'topic', you can do
> +------------
> +    git rebase --onto subsystem HEAD~3
> +------------
> +to put things right.  Of course, this again ripples onwards:
> +'everyone' downstream from 'subsystem' will have to 'manually' rebase
> +all their work!

I like this documentation because it provides another clear case of how the '--onto' option is used.

-- 
Marcus Griep
GPG Key ID: 0x5E968152
——
http://www.boohaunt.net
את.ψο´
Junio C Hamano· Sep 13, 2008, 05:08 UTC · re: Thomas Rast · lore

Re: [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase

Thomas Rast <trast@student.ethz.ch> writes:
Show 5 quoted lines
> +RECOVERING FROM UPSTREAM REBASE
> +-------------------------------
> +
> +This section briefly explains the problems that arise from rebasing or
> +rewriting published branches, and shows how to recover.

The largest issue of "The problem" is that the person who rebases causes this problem to others, _forcing_ his downstream to recover. This intro needs to make it clear the distinction between the person who rebases, who suffers is forced to recover as the consequence.

Show 13 quoted lines
> +    o---o---o---o---o  master
> +         \
> +          o---o---o---o---o  subsystem
> +                           \
> +                            *---*---*  topic
>...
> +If 'subsystem' is rebased against master, the following happens:
>...
> +    o---o---o---o---o  master
> +        |            \
> +        |             o'--o'--o'--o'--o'  subsystem
> +        \
> +         o---o---o---o---o---*---*---*  topic

Make the original upstream a bit longer in the "after" picture, explaining that "your upstream subsystem rebased on top of its own upstream after it gets updated", so that the part that are unchanged in two pictures are not drawn differently like you did above.

In other words, draw it like this. It is much easier to see what's changed and what's unchanged, if the part that hasn't changed stayed unchanged in the picture:

       o---o---o---o---o  master
            \
             o---o---o---o---o  subsystem
                              \
                               *---*---*  topic
       o---o---o---o---o---o---o---o  master
            \                       \ 
             o---o---o---o---o       o'--o'--o'--o'--o' subsystem
                              \
                               *---*---*  topic
Show 5 quoted lines
> +Note that while we have marked your own commits with a '*', there is
> +nothing that distinguishes them from the commits that previously were
> +on 'subsystem'.  Luckily, 'git-rebase' knows to skip commits that are
> +textually the same as commits in the upstream.  So if you say
> +(assuming you're on 'topic')

There is no luck involved in "git rebase" knowing how to do this -- this is by design.

But more importantly, at this point, there is a break in the flow of thought in this section. Step back and read what you wrote, pretending as if you are reading the section for the first time, and notice:

 * The readers were shown how the topology before and after the
   subsystem's rebase looked like;
 * The readers haven't been told what you are trying teach them now.  Yes,
   I know that you are going to tell them how to transplant their own
   commits on top of updated subsystem, but they don't know that yet;
 * Some of the readers may not even understand why it is a bad idea to
   keep building on top of the old subsystem without rebasing on top of
   the rebased subsystem at this point.

Only when the readers know that the objective is to transplant these three top commits, they would start appreciating the difficulty (i.e. you cannot tell the commits apart by looking at the topology alone) of rebase the reader has to do, and the smart (i.e. if you are lucky, the rebase your upstream did may have been a simple one) git-rebase uses to help them.

It would suffice to insert something like this before "Note that...".
        To continue working from here, you need to transplant your own
        commits (marked as '*') on top of the "subsystem", which is now
        rebased.
But see footnote below.
> +This becomes a ripple effect to anyone downstream of the first rebase:
> +anyone downstream from 'topic' now needs to rebase too, and so on.
This calls for a stronger wording than "needs to", perhaps "forced to".
> +Things get more complicated if your upstream used `git rebase
> +--interactive` (or `commit --amend` or `reset --hard HEAD^`).

I do not think this section is absolutely necessary. The upstream may have done a simple rebase, which may have conflicted with the changes in its own upstream.

Show 8 quoted lines
> +To fix this, you have to manually transplant your own part of the
> +history to the new branch head.  Looking at `git log`, you should be
> +able to determine that three commits on 'topic' are yours.  Again
> +assuming you are already on 'topic', you can do
> +------------
> +    git rebase --onto subsystem HEAD~3
> +------------
> +to put things right.

HEAD~3 would _work_, but it often is easier to visualize this (perhaps in your head, or in "gitk HEAD origin origin@{1}"):

       o---o---o---o---o---o---o---o  master
            \                       \ 
             o---o---o---o---o       o'--o'--o'--o'--o' subsystem
                              \
                               *---*---*  topic
and say:
    $ git rebase --onto subsystem subsystem@{1}

The reflog reference "1" may be larger depending on the number of times you fetched from them without rebasing, though.

[Footnote]

You did not cover why midstream rebase _forces_ downstream to rebase. If the leaf-level person did not know better, or did not care, starting from this topology:

       o---o---o---o---o---o---o---o  master
            \                       \ 
             o---o---o---o---o       o'--o'--o'--o'--o' subsystem
                              \
                               *---*---*  topic

the leaf person can keep building on top of the old topic, and later when the topic is mature, have subsystem merge the result. If the rebase the subsystem did was simple enough, the merge will be easy to resolve (both sides modifying the same way).

       o---o---o---o---o---o---o---o  master
            \                       \ 
             o---o---o---o---o       o'--o'--o'--o'--o'--M subsystem
                              \                         /
                               *---*---*---*---*---*---*

The problem is that the resulting history will keep two copies of the morally equivalent commits from the subsystem. You know that, and I know that, but the purpose of the document is to explain it to people who do not know it yet.

Thomas Rast· Sep 13, 2008, 16:10 UTC · re: Junio C Hamano · lore

[PATCH 0/3] Documentation: rebase and workflows

Junio C Hamano wrote:
>

First of all, thanks for your excellent criticism of my patch. (Thanks also to Marcus for spotting the typo, though I eventually decided to remove the corresponding part again.)

I'm rerolling the entire series, with a few improvements to 3/3, and following that with an interdiff. 1/3 is almost a complete rewrite. (I realise that 3/3 is not really related to the first two, so we may eventually have to split it off the series if it takes more time.)

All snipped comments have been addressed ... hopefully ;-)
> In other words, draw it like this.  It is much easier to see what's
> changed and what's unchanged, if the part that hasn't changed stayed
> unchanged in the picture:
[...]
Show 5 quoted lines
>        o---o---o---o---o---o---o---o  master
>             \                       \ 
>              o---o---o---o---o       o'--o'--o'--o'--o' subsystem
>                               \
>                                *---*---*  topic

I had the old one in the other style to emphasise that all commits on 'topic' are "indistinguishable" w.r.t. source. But this indeed makes for nicer graphs.

Show 6 quoted lines
> Thomas Rast <trast@student.ethz.ch> writes:
> > +on 'subsystem'.  Luckily, 'git-rebase' knows to skip commits that are
> > +textually the same as commits in the upstream.  So if you say
> 
> There is no luck involved in "git rebase" knowing how to do this -- this
> is by design.
Luckily for the user! :-)
> But more importantly, at this point, there is a break in the flow of
> thought in this section.  Step back and read what you wrote, pretending as
> if you are reading the section for the first time, and notice:
[...]

Indeed, you are right. I stole your "merge without rebase" drawing, and added a paragraph about the reasons for a rebase. However:

> The problem is that the resulting history will keep two copies of the
> morally equivalent commits from the subsystem.  You know that, and I know
> that, but the purpose of the document is to explain it to people who do
> not know it yet.

Maybe that's just me, but I always thought the duplication argument was a bit weak. I think reasons such as "resurrects changes that have been (presumably for a reason) undone" are far scarier and more likely to stop users from rebasing. Eventually, I omitted it to keep the justification paragraph shorter, but if others feel the same, maybe it should go in.

- Thomas
Thomas Rast (3):
  Documentation: new upstream rebase recovery section in git-rebase
  Documentation: Refer to git-rebase(1) to warn against rewriting
  Documentation: add manpage about workflows
 Documentation/Makefile              |    2 +-
 Documentation/git-commit.txt        |    4 +
 Documentation/git-filter-branch.txt |    4 +-
 Documentation/git-rebase.txt        |  129 +++++++++++++-
 Documentation/git-reset.txt         |    4 +-
 Documentation/gitworkflows.txt      |  330 +++++++++++++++++++++++++++++++++++
 6 files changed, 465 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/gitworkflows.txt
Thomas Rast· Sep 13, 2008, 16:11 UTC · re: Thomas Rast · lore

[PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase

Documents how to recover if the upstream that you pull from has rebased the branches you depend your work on. Hopefully this can also serve as a warning to potential rebasers.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
See the series leader for discussion.
 Documentation/git-rebase.txt |  129 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 124 insertions(+), 5 deletions(-)
Show changes to Documentation/git-rebase.txt +124 −5
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 59c1b02..a2f686c 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -257,11 +257,10 @@ include::merge-strategies.txt[]
 
 NOTES
 -----
-When you rebase a branch, you are changing its history in a way that
-will cause problems for anyone who already has a copy of the branch
-in their repository and tries to pull updates from you.  You should
-understand the implications of using 'git-rebase' on a repository that
-you share.
+
+You should understand the implications of using 'git-rebase' on a
+repository that you share.  See also RECOVERING FROM UPSTREAM REBASE
+below.
 
 When the git-rebase command is run, it will first execute a "pre-rebase"
 hook if one exists.  You can use this hook to do sanity checks and
@@ -396,6 +395,126 @@ consistent (they compile, pass the testsuite, etc.) you should use
 after each commit, test, and amend the commit if fixes are necessary.
 
 
+RECOVERING FROM UPSTREAM REBASE
+-------------------------------
+
+Rebasing (or any other form of rewriting) a branch that others have
+based work on is a bad idea: anyone downstream of it is forced to
+manually fix their history.  This section explains how to do the fix
+from the downstream's point of view.  The real fix, however, would be
+to avoid rebasing the upstream in the first place.
+
+To illustrate, suppose you are in a situation where someone develops a
+'subsystem' branch, and you are working on a 'topic' that is dependent
+on this 'subsystem'.  You might end up with a history like the
+following:
+
+------------
+    o---o---o---o---o---o---o---o---o  master
+	 \
+	  o---o---o---o---o  subsystem
+			   \
+			    *---*---*  topic
+------------
+
+If 'subsystem' is rebased against 'master', the following happens:
+
+------------
+    o---o---o---o---o---o---o---o  master
+	 \			 \
+	  o---o---o---o---o	  o'--o'--o'--o'--o'  subsystem
+			   \
+			    *---*---*  topic
+------------
+
+If you now continue development as usual, and eventually merge 'topic'
+to 'subsystem', the commits will remain duplicated forever:
+
+------------
+    o---o---o---o---o---o---o---o  master
+	 \			 \
+	  o---o---o---o---o	  o'--o'--o'--o'--o'--M	 subsystem
+			   \			     /
+			    *---*---*-..........-*--*  topic
+------------
+
+Such duplicates are generally frowned upon because they clutter up
+history, making it harder to follow.  To clean things up, you need to
+transplant the commits on 'topic' to the new 'subsystem' tip, i.e.,
+rebase 'topic'.  This becomes a ripple effect: anyone downstream from
+'topic' is forced to rebase too, and so on!
+
+There are two kinds of fixes, discussed in the following subsections:
+
+Easy case: The changes are literally the same.::
+
+	This happens if the 'subsystem' rebase was a simple rebase and
+	had no conflicts.
+
+Hard case: The changes are not the same.::
+
+	This happens if the 'subsystem' rebase had conflicts, or used
+	`\--interactive` to omit, edit, or squash commits; or if the
+	upstream used one of `commit \--amend`, `reset`, or
+	`filter-branch`.
+
+
+The easy case
+~~~~~~~~~~~~~
+
+Only works if the changes (patch IDs based on the diff contents) on
+'subsystem' are literally the same before and after the rebase.
+
+In that case, the fix is easy because 'git-rebase' knows to skip
+changes that are already present in the new upstream.  So if you say
+(assuming you're on 'topic')
+------------
+    git rebase subsystem
+------------
+you will end up with the fixed history
+------------
+    o---o---o---o---o---o---o---o  master
+				 \
+				  o'--o'--o'--o'--o'  subsystem
+						   \
+						    *---*---*  topic
+------------
+
+
+The hard case
+~~~~~~~~~~~~~
+
+Things get more complicated if the 'subsystem' changes do not exactly
+correspond to the pre-rebase ones.
+
+NOTE: While an "easy case recovery" sometimes appears to be successful
+      even in the hard case, it may have unintended consequences.  For
+      example, a commit that was removed via `git rebase
+      \--interactive` will be **resurrected**!
+
+The idea is to manually tell 'git-rebase' "where the old 'subsystem'
+ended and your 'topic' began", that is, what the old merge-base
+between them was.  You will have to find a way to name the last commit
+of the old 'subsystem', for example:
+
+* With the 'subsystem' reflog: after 'git-fetch', the old tip of
+  'subsystem' is at `subsystem@\{1}`.  Subsequent fetches will
+  increase the number.  (See linkgit:git-reflog[1].)
+
+* Relative to the tip of 'topic': knowing that your 'topic' has three
+  commits, the old tip of 'subsystem' must be `topic~3`.
+
+You can then transplant the old `subsystem..topic` to the new tip by
+saying (for the reflog case, and assuming you are on 'topic' already):
+------------
+    git rebase --onto subsystem subsystem@{1}
+------------
+
+The ripple effect of a "hard case" recovery is especially bad:
+'everyone' downstream from 'topic' will now have to perform a "hard
+case" recovery too!
+
+
 Authors
 ------
 Written by Junio C Hamano <gitster@pobox.com> and
-- 
1.6.0.2.408.g3709
Thomas Rast· Sep 13, 2008, 16:11 UTC · re: Thomas Rast · lore

[PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting

This points readers at the "Recovering from upstream rebase" warning in git-rebase(1) when we talk about rewriting published history in the 'reset', 'commit --amend', and 'filter-branch' documentation.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-commit.txt        |    4 ++++
 Documentation/git-filter-branch.txt |    4 +++-
 Documentation/git-reset.txt         |    4 +++-
 3 files changed, 10 insertions(+), 2 deletions(-)
Show changes to 3 files +10 −2

Documentation/git-commit.txt, Documentation/git-filter-branch.txt, Documentation/git-reset.txt

diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index eb05b0f..eeba58d 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -144,6 +144,10 @@ It is a rough equivalent for:
 ------
 but can be used to amend a merge commit.
 --
++
+You should understand the implications of rewriting history if you
+amend a commit that has already been published.  (See the "RECOVERING
+FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].)
 
 -i::
 --include::
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index b0e710d..fed6de6 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -36,7 +36,9 @@ the objects and will not converge with the original branch.  You will not
 be able to easily push and distribute the rewritten branch on top of the
 original branch.  Please do not use this command if you do not know the
 full implications, and avoid using it anyway, if a simple single commit
-would suffice to fix your problem.
+would suffice to fix your problem.  (See the "RECOVERING FROM UPSTREAM
+REBASE" section in linkgit:git-rebase[1] for further information about
+rewriting published history.)
 
 Always verify that the rewritten version is correct: The original refs,
 if different from the rewritten ones, will be stored in the namespace
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 6abaeac..52aab5e 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -82,7 +82,9 @@ $ git reset --hard HEAD~3   <1>
 +
 <1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad
 and you do not want to ever see them again.  Do *not* do this if
-you have already given these commits to somebody else.
+you have already given these commits to somebody else.  (See the
+"RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for
+the implications of doing so.)
 
 Undo a commit, making it a topic branch::
 +
-- 
1.6.0.2.408.g3709
Thomas Rast· Sep 13, 2008, 16:11 UTC · re: Thomas Rast · lore

[PATCH 3/3] Documentation: add manpage about workflows

This attempts to make a manpage about workflows that is both handy to point people at it and as a beginner's introduction.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

Interdiff follows. The important change is that the format-patch recipe says to use send-email, hopefully keeping people from damaging their patches via cut&paste.

Unfortunately I still don't know how to make the blocks look right in manpage format.

 Documentation/Makefile         |    2 +-
 Documentation/gitworkflows.txt |  330 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 331 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/gitworkflows.txt
Show changes to 2 files +331 −1

Documentation/Makefile, Documentation/gitworkflows.txt

diff --git a/Documentation/Makefile b/Documentation/Makefile
index ded0e40..e33ddcb 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
 	gitrepository-layout.txt
 MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
 	gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
-	gitdiffcore.txt
+	gitdiffcore.txt gitworkflows.txt
 
 MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
 MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
new file mode 100644
index 0000000..b4b43da
--- /dev/null
+++ b/Documentation/gitworkflows.txt
@@ -0,0 +1,330 @@
+gitworkflows(7)
+===============
+
+NAME
+----
+gitworkflows - An overview of recommended workflows with git
+
+SYNOPSIS
+--------
+git *
+
+
+DESCRIPTION
+-----------
+
+This tutorial gives a brief overview of workflows recommended to
+use, and collaborate with, Git.
+
+While the prose tries to motivate each of them, we formulate a set of
+'rules' for quick reference.  Do not always take them literally; you
+should value good reasons higher than following a random manpage to
+the letter.
+
+
+SEPARATE CHANGES
+----------------
+
+As a general rule, you should try to split your changes into small
+logical steps, and commit each of them.  They should be consistent,
+working independently of any later commits, pass the test suite, etc.
+
+To achieve this, try to commit your new work at least every couple
+hours.  You can always go back and edit the commits with `git rebase
+--interactive` to further improve the history before you publish it.
+
+
+MANAGING BRANCHES
+-----------------
+
+In the following, we will assume there are 'developers', 'testers' and
+'users'.  Even if the "Testers" are actually an automated test suite
+and all "Users" are developers themselves, try to think in these terms
+as you follow a software change through its life cycle.
+
+Usually a change evolves in a few steps:
+
+* The developers implement a few iterations until it "seems to work".
+
+* The testers play with it, report bugs, test the fixes, eventually
+  clearing the change for stable releases.
+
+* As the users work with the new feature, they report bugs which will
+  have to be fixed.
+
+In the following sections we discuss some problems that arise from
+such a "change flow", and how to solve them with Git.
+
+We consider a fictional project with (supported) stable branch
+'maint', main testing/development branch 'master' and "bleeding edge"
+branch 'next'.  We collectively call these three branches 'main
+branches'.
+
+
+Merging upwards
+~~~~~~~~~~~~~~~
+
+Since Git is quite good at merges, one should try to use them to
+propagate changes.  For example, if a bug is fixed, you would want to
+apply the corresponding fix to all main branches.
+
+A quick moment of thought reveals that you cannot do this by merging
+"downwards" to older releases, since that would merge 'all' changes.
+Hence the following:
+
+.Merge upwards
+[caption="Rule: "]
+=====================================
+Always commit your fixes to the oldest supported branch that require
+them.  Then (periodically) merge the main branches upwards into each
+other.
+=====================================
+
+This gives a very controlled flow of fixes.  If you notice that you
+have applied a fix to e.g. 'master' that is also required in 'maint',
+you will need to cherry-pick it (using linkgit:git-cherry-pick[1])
+downwards.  This will happen a few times and is nothing to worry about
+unless you do it all the time.
+
+
+Topic branches
+~~~~~~~~~~~~~~
+
+Any nontrivial feature will require several patches to implement, and
+may get extra bugfixes or improvements during its lifetime.  If all
+such commits were in one long linear history chain (e.g., if they were
+all committed directly to 'master'), it becomes very hard to see how
+they belong together.
+
+The key concept here is "topic branches".  The name is pretty self
+explanatory, with a minor caveat that comes from the "merge upwards"
+rule above:
+
+.Topic branches
+[caption="Rule: "]
+=====================================
+Make a side branch for every topic. Fork it off at the oldest main
+branch that you will eventually want to merge it into.
+=====================================
+
+Many things can then be done very naturally:
+
+* To get the feature/bugfix into a main branch, simply merge it.  If
+  the topic has evolved further in the meantime, merge again.
+
+* If you find you need new features from an 'other' branch to continue
+  working on your topic, merge 'other' to 'topic'.  (However, do not
+  do this "just habitually", see below.)
+
+* If you find you forked off the wrong branch and want to move it
+  "back in time", use linkgit:git-rebase[1].
+
+Note that the last two points clash: a topic that has been merged
+elsewhere should not be rebased.  See the section on RECOVERING FROM
+UPSTREAM REBASE in linkgit:git-rebase[1].
+
+We should point out that "habitually" (regularly for no real reason)
+merging a main branch into your topics -- and by extension, merging
+anything upstream into anything downstream on a regular basis -- is
+frowned upon:
+
+.Merge to downstream only at well-defined points
+[caption="Rule: "]
+=====================================
+Do not merge to downstream except:
+
+* with a good reason (such as upstream API changes that affect you), or
+
+* at well-defined points such as when an upstream release has been tagged.
+=====================================
+
+Otherwise, the many resulting small merges will greatly clutter up
+history.  Anyone who later investigates the history of a file will
+have to find out whether that merge affected the topic in
+development.  Linus hates it.  An upstream might even inadvertently be
+merged into a "more stable" branch.  And so on.
+
+
+Integration branches
+~~~~~~~~~~~~~~~~~~~~
+
+If you followed the last paragraph, you will now have many small topic
+branches, and occasionally wonder how they interact.  Perhaps the
+result of merging them does not even work?  But on the other hand, we
+want to avoid merging them anywhere "stable" because such merges
+cannot easily be undone.
+
+The solution, of course, is to make a merge that we can undo: merge
+into a throw-away branch.
+
+.Integration branches
+[caption="Rule: "]
+=====================================
+To test the interaction of several topics, merge them into a
+throw-away branch.
+=====================================
+
+If you make it (very) clear that this branch is going to be deleted
+right after the testing, you can even publish this branch, for example
+to give the testers a chance to work with it, or other developers a
+chance to see if their in-progress work will be compatible.
+
+
+SHARING WORK
+------------
+
+After the last section, you should know how to manage topics.  In
+general, you will not be the only person working on the project, so
+you will have to share your work.
+
+Roughly speaking, there are two important workflows.  Their
+distinguishing mark is whether they can be used to propagate merges.
+Medium to large projects will typically employ some mixture of the
+two:
+
+* "Upstream" in the most general sense 'pushes' changes to the
+  repositor(ies) holding the main history.  Everyone can 'pull' from
+  there to stay up to date.
+
+* Frequent contributors, subsystem maintainers, etc. may use push/pull
+  to send their changes upstream.
+
+* The rest -- typically anyone more than one or two levels away from the
+  main maintainer -- send patches by mail.
+
+None of these boundaries are sharp, so find out what works best for
+you.
+
+
+Push/pull
+~~~~~~~~~
+
+There are three main tools that can be used for this:
+
+* linkgit:git-push[1] copies your branches to a remote repository,
+  usually to one that can be read by all involved parties;
+
+* linkgit:git-fetch[1] that copies remote branches to your repository;
+  and
+
+* linkgit:git-pull[1] that does fetch and merge in one go.
+
+Note the last point.  Do 'not' use 'git-pull' unless you actually want
+to merge the remote branch.
+
+Getting changes out is easy:
+
+.Push/pull: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git push <remote> <branch>` and tell everyone where they can fetch
+from.
+=====================================
+
+You will still have to tell people by other means, such as mail.  (Git
+provides the linkgit:request-pull[1] to send preformatted pull
+requests to upstream maintainers to simplify this task.)
+
+If you just want to get the newest copies of the main branches,
+staying up to date is easy too:
+
+.Push/pull: Staying up to date
+[caption="Recipe: "]
+=====================================
+Use `git fetch <remote>` or `git remote update` to stay up to date.
+=====================================
+
+Then simply fork your topic branches from the stable remotes as
+explained earlier.
+
+If you are a maintainer and would like to merge other people's topic
+branches to the main branches, they will typically send a request to
+do so by mail.  Such a request might say
+
+-------------------------------------
+Please pull from
+    git://some.server.somewhere/random/repo.git mytopic
+-------------------------------------
+
+In that case, 'git-pull' can do the fetch and merge in one go, as
+follows.
+
+.Push/pull: Merging remote topics
+[caption="Recipe: "]
+=====================================
+`git pull <url> <branch>`
+=====================================
+
+Occasionally, the maintainer may get merge conflicts when he tries to
+pull changes from downstream.  In this case, he can ask downstream to
+do the merge and resolve the conflicts themselves (perhaps they will
+know better how to resolve them).  It is one of the rare cases where
+downstream 'should' merge from upstream.
+
+
+format-patch/am
+~~~~~~~~~~~~~~~
+
+If you are a contributor that sends changes upstream in the form of
+emails, you should use topic branches as usual (see above).  Then use
+linkgit:git-format-patch[1] to generate the corresponding emails
+(highly recommended over manually formatting them because it makes the
+maintainer's life easier).
+
+.format-patch/am: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+* `git format-patch -M upstream..topic` to turn them into preformatted
+  patch files
+* `git send-email --to=<recipient> <patches>`
+=====================================
+
+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]
+manpages for further usage notes.  Also you should be aware that the
+maintainer may impose further restrictions, such as "Signed-off-by"
+requirements.
+
+If the maintainer tells you that your patch no longer applies to the
+current upstream, you will have to rebase your topic (you cannot use a
+merge because you cannot format-patch merges):
+
+.format-patch/am: Keeping topics up to date
+[caption="Recipe: "]
+=====================================
+`git rebase upstream`
+=====================================
+
+You can then fix the conflicts during the rebase.  Presumably you have
+not published your topic other than by mail, so rebasing it is not a
+problem.
+
+If you receive such a patch (as maintainer, or perhaps reader of the
+mailing list it was sent to), save the mail to a file and use
+'git-am':
+
+.format-patch/am: Publishing branches/topics
+[caption="Recipe: "]
+=====================================
+`git am < patch`
+=====================================
+
+One feature worth pointing out is the three-way merge, which can help
+if you get conflicts because of renames: `git am -3` will use index
+information contained in patches to reconstruct a merge base.  See
+linkgit:git-am[1] for other options.
+
+
+SEE ALSO
+--------
+linkgit:gittutorial[7],
+linkgit:git-push[1],
+linkgit:git-pull[1],
+linkgit:git-merge[1],
+linkgit:git-rebase[1],
+linkgit:git-format-patch[1],
+linkgit:git-send-email[1],
+linkgit:git-am[1]
+
+GIT
+---
+Part of the linkgit:git[1] suite.
-- 
1.6.0.2.408.g3709
Thomas Rast· Sep 13, 2008, 16:11 UTC · re: Thomas Rast · lore

Interdiff: [3/3] Documentation: add manpage about workflows

---
 Documentation/gitworkflows.txt |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)
Show changes to Documentation/gitworkflows.txt +14 −10
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
index 3462000..b4b43da 100644
--- a/Documentation/gitworkflows.txt
+++ b/Documentation/gitworkflows.txt
@@ -92,8 +92,8 @@ Topic branches
 
 Any nontrivial feature will require several patches to implement, and
 may get extra bugfixes or improvements during its lifetime.  If all
-such commits were in one long linear history chain (e.g. if they were
-all committed directly to, 'master'), it becomes very hard to see how
+such commits were in one long linear history chain (e.g., if they were
+all committed directly to 'master'), it becomes very hard to see how
 they belong together.
 
 The key concept here is "topic branches".  The name is pretty self
@@ -124,8 +124,8 @@ elsewhere should not be rebased.  See the section on RECOVERING FROM
 UPSTREAM REBASE in linkgit:git-rebase[1].
 
 We should point out that "habitually" (regularly for no real reason)
-merging a main branch into your topics--and by extension, merging
-anything upstream into anything downstream on a regular basis--is
+merging a main branch into your topics -- and by extension, merging
+anything upstream into anything downstream on a regular basis -- is
 frowned upon:
 
 .Merge to downstream only at well-defined points
@@ -207,7 +207,7 @@ There are three main tools that can be used for this:
 * linkgit:git-fetch[1] that copies remote branches to your repository;
   and
 
-* linkgit:git-pull[1] that is fetch and merge in one go.
+* linkgit:git-pull[1] that does fetch and merge in one go.
 
 Note the last point.  Do 'not' use 'git-pull' unless you actually want
 to merge the remote branch.
@@ -258,7 +258,7 @@ follows.
 Occasionally, the maintainer may get merge conflicts when he tries to
 pull changes from downstream.  In this case, he can ask downstream to
 do the merge and resolve the conflicts themselves (perhaps they will
-know better how to react).  It is one of the rare cases where
+know better how to resolve them).  It is one of the rare cases where
 downstream 'should' merge from upstream.
 
 
@@ -274,12 +274,15 @@ maintainer's life easier).
 .format-patch/am: Publishing branches/topics
 [caption="Recipe: "]
 =====================================
-`git format-patch -M upstream..topic` and send out the resulting files.
+* `git format-patch -M upstream..topic` to turn them into preformatted
+  patch files
+* `git send-email --to=<recipient> <patches>`
 =====================================
 
-See the linkgit:git-format-patch[1] manpage for further usage notes.
-Also you should be aware that the maintainer may impose further
-restrictions, such as "Signed-off-by" requirements.
+See the linkgit:git-format-patch[1] and linkgit:git-send-email[1]
+manpages for further usage notes.  Also you should be aware that the
+maintainer may impose further restrictions, such as "Signed-off-by"
+requirements.
 
 If the maintainer tells you that your patch no longer applies to the
 current upstream, you will have to rebase your topic (you cannot use a
@@ -319,6 +322,7 @@ linkgit:git-pull[1],
 linkgit:git-merge[1],
 linkgit:git-rebase[1],
 linkgit:git-format-patch[1],
+linkgit:git-send-email[1],
 linkgit:git-am[1]
 
 GIT
-- 
1.6.0.2.408.g3709
Thomas Rast· Sep 9, 2008, 05:42 UTC · re: Junio C Hamano · lore

Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase

Junio C Hamano wrote:
> Any follow-up on this topic since:
> 
>     http://thread.gmane.org/gmane.comp.version-control.git/94701/focus=94761

I've been busy doing other work, sorry. I haven't forgotten though, and will definitely get back to it :-)

- Thomas
-- 
Thomas Rast
trast@student.ethz.ch

← back to recent threads