git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase
@ 2008-09-02 20:18 Thomas Rast
  2008-09-02 21:39 ` Junio C Hamano
  2008-09-08 22:55 ` [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Junio C Hamano
  0 siblings, 2 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-02 20:18 UTC (permalink / raw
  To: git

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(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-02 20:18 [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
@ 2008-09-02 21:39 ` Junio C Hamano
  2008-09-03  5:38   ` Thomas Rast
  2008-09-08 22:55 ` [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Junio C Hamano
  1 sibling, 1 reply; 29+ messages in thread
From: Junio C Hamano @ 2008-09-02 21:39 UTC (permalink / raw
  To: Thomas Rast; +Cc: git

Thomas Rast <trast@student.ethz.ch> writes:

> 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

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-02 21:39 ` Junio C Hamano
@ 2008-09-03  5:38   ` Thomas Rast
  2008-09-11 15:38     ` [PATCH 0/2.5] " Thomas Rast
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-03  5:38 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 688 bytes --]

Junio C Hamano wrote:
> 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


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-02 20:18 [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
  2008-09-02 21:39 ` Junio C Hamano
@ 2008-09-08 22:55 ` Junio C Hamano
  2008-09-09  5:42   ` Thomas Rast
  1 sibling, 1 reply; 29+ messages in thread
From: Junio C Hamano @ 2008-09-08 22:55 UTC (permalink / raw
  To: Thomas Rast; +Cc: git

Any follow-up on this topic since:

    http://thread.gmane.org/gmane.comp.version-control.git/94701/focus=94761

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-08 22:55 ` [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Junio C Hamano
@ 2008-09-09  5:42   ` Thomas Rast
  0 siblings, 0 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-09  5:42 UTC (permalink / raw
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 314 bytes --]

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


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 0/2.5] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-03  5:38   ` Thomas Rast
@ 2008-09-11 15:38     ` Thomas Rast
  2008-09-11 15:38       ` [PATCH 1/2] " Thomas Rast
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-11 15:38 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

So here's the follow-up I promised.

Junio C Hamano <gitster@pobox.com> wrote:
>
> 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:

> 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/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-11 15:38     ` [PATCH 0/2.5] " Thomas Rast
@ 2008-09-11 15:38       ` Thomas Rast
  2008-09-11 15:38         ` [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
                           ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-11 15:38 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting
  2008-09-11 15:38       ` [PATCH 1/2] " Thomas Rast
@ 2008-09-11 15:38         ` Thomas Rast
  2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
  2008-09-12  1:15         ` [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase Marcus Griep
  2008-09-13  5:08         ` Junio C Hamano
  2 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-11 15:38 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC PATCH] Documentation: add manpage about workflows
  2008-09-11 15:38         ` [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
@ 2008-09-11 15:39           ` Thomas Rast
  2008-09-11 16:37             ` Jakub Narebski
                               ` (3 more replies)
  0 siblings, 4 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-11 15:39 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: add manpage about workflows
  2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
@ 2008-09-11 16:37             ` Jakub Narebski
  2008-09-12  7:26             ` [RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows] Thomas Rast
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 29+ messages in thread
From: Jakub Narebski @ 2008-09-11 16:37 UTC (permalink / raw
  To: git

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

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-11 15:38       ` [PATCH 1/2] " Thomas Rast
  2008-09-11 15:38         ` [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
@ 2008-09-12  1:15         ` Marcus Griep
  2008-09-13  5:08         ` Junio C Hamano
  2 siblings, 0 replies; 29+ messages in thread
From: Marcus Griep @ 2008-09-12  1:15 UTC (permalink / raw
  To: Thomas Rast; +Cc: git, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 1120 bytes --]

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

> +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
את.ψο´


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows]
  2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
  2008-09-11 16:37             ` Jakub Narebski
@ 2008-09-12  7:26             ` Thomas Rast
  2008-09-20  0:22             ` [RFC PATCH] Documentation: add manpage about workflows Santi Béjar
  2008-09-21 20:26             ` Dmitry Potapov
  3 siblings, 0 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-12  7:26 UTC (permalink / raw
  To: git

[-- Attachment #1: Type: text/plain, Size: 585 bytes --]

Thomas Rast wrote:
> +.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



[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-11 15:38       ` [PATCH 1/2] " Thomas Rast
  2008-09-11 15:38         ` [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
  2008-09-12  1:15         ` [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase Marcus Griep
@ 2008-09-13  5:08         ` Junio C Hamano
  2008-09-13 16:10           ` [PATCH 0/3] Documentation: rebase and workflows Thomas Rast
  2 siblings, 1 reply; 29+ messages in thread
From: Junio C Hamano @ 2008-09-13  5:08 UTC (permalink / raw
  To: Thomas Rast; +Cc: git

Thomas Rast <trast@student.ethz.ch> writes:

> +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.

> +    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

> +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.

> +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.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 0/3] Documentation: rebase and workflows
  2008-09-13  5:08         ` Junio C Hamano
@ 2008-09-13 16:10           ` Thomas Rast
  2008-09-13 16:11             ` [PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-13 16:10 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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:
[...]
>        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.

> 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

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase
  2008-09-13 16:10           ` [PATCH 0/3] Documentation: rebase and workflows Thomas Rast
@ 2008-09-13 16:11             ` Thomas Rast
  2008-09-13 16:11               ` [PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-13 16:11 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting
  2008-09-13 16:11             ` [PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
@ 2008-09-13 16:11               ` Thomas Rast
  2008-09-13 16:11                 ` [PATCH 3/3] Documentation: add manpage about workflows Thomas Rast
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-13 16:11 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/3] Documentation: add manpage about workflows
  2008-09-13 16:11               ` [PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
@ 2008-09-13 16:11                 ` Thomas Rast
  2008-09-13 16:11                   ` Interdiff: [3/3] " Thomas Rast
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Rast @ 2008-09-13 16:11 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

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

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Interdiff: [3/3] Documentation: add manpage about workflows
  2008-09-13 16:11                 ` [PATCH 3/3] Documentation: add manpage about workflows Thomas Rast
@ 2008-09-13 16:11                   ` Thomas Rast
  0 siblings, 0 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-13 16:11 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano

---
 Documentation/gitworkflows.txt |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: add manpage about workflows
  2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
  2008-09-11 16:37             ` Jakub Narebski
  2008-09-12  7:26             ` [RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows] Thomas Rast
@ 2008-09-20  0:22             ` Santi Béjar
  2008-09-21 20:26             ` Dmitry Potapov
  3 siblings, 0 replies; 29+ messages in thread
From: Santi Béjar @ 2008-09-20  0:22 UTC (permalink / raw
  To: Thomas Rast; +Cc: git, Junio C Hamano

On Thu, Sep 11, 2008 at 5:39 PM, Thomas Rast <trast@student.ethz.ch> wrote:
> 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?)
> 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.

> +
> +
> +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', ...

> +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.

> +
> +
> +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

> +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

> +  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.

> +=====================================
> +
> +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 :-)
> +
> +
> +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.
> +
> +* 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.

> +
> +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.)
> +


> +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,...)

> +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.

> +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.

> +
> +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>

> +
> +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

> +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-

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: add manpage about workflows
  2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
                               ` (2 preceding siblings ...)
  2008-09-20  0:22             ` [RFC PATCH] Documentation: add manpage about workflows Santi Béjar
@ 2008-09-21 20:26             ` Dmitry Potapov
  2008-09-30 16:05               ` Thomas Rast
  3 siblings, 1 reply; 29+ messages in thread
From: Dmitry Potapov @ 2008-09-21 20:26 UTC (permalink / raw
  To: Thomas Rast; +Cc: git, Junio C Hamano

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.

> +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."

> +
> +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'.

> +
> +* 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.

> +
> +
> +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.

> +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.

> +
> +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:

> +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.

> +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.

> +
> +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

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: add manpage about workflows
  2008-09-21 20:26             ` Dmitry Potapov
@ 2008-09-30 16:05               ` Thomas Rast
  2008-09-30 16:07                 ` Thomas Rast
  2008-10-01  9:54                 ` Santi Béjar
  0 siblings, 2 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-30 16:05 UTC (permalink / raw
  To: Dmitry Potapov; +Cc: git, Santi Béjar, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 12980 bytes --]

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.



[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: add manpage about workflows
  2008-09-30 16:05               ` Thomas Rast
@ 2008-09-30 16:07                 ` Thomas Rast
  2008-10-01  9:54                 ` Santi Béjar
  1 sibling, 0 replies; 29+ messages in thread
From: Thomas Rast @ 2008-09-30 16:07 UTC (permalink / raw
  To: Dmitry Potapov; +Cc: git, Santi Béjar, Junio C Hamano

I wrote:
> The WIP text is below, and I'll follow up with an interdiff to the
> last version.

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH] Documentation: add manpage about workflows
  2008-09-30 16:05               ` Thomas Rast
  2008-09-30 16:07                 ` Thomas Rast
@ 2008-10-01  9:54                 ` Santi Béjar
  2008-10-09 11:42                   ` [RFC PATCH v2] " Thomas Rast
  1 sibling, 1 reply; 29+ messages in thread
From: Santi Béjar @ 2008-10-01  9:54 UTC (permalink / raw
  To: Thomas Rast; +Cc: Dmitry Potapov, git, Junio C Hamano

On Tue, Sep 30, 2008 at 6:05 PM, Thomas Rast <trast@student.ethz.ch> wrote:
> 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.

>
> 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
>
[...]

>
> 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.

[...]

> 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.

[...]

> 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:".

>
>
> 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 ...

>
> 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.

>
> 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:

> .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/

>
> 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.

>
> 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.
>
>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [RFC PATCH v2] Documentation: add manpage about workflows
  2008-10-01  9:54                 ` Santi Béjar
@ 2008-10-09 11:42                   ` Thomas Rast
  2008-10-09 11:42                     ` [Interdiff] " Thomas Rast
  2008-10-09 12:50                     ` Junio C Hamano
  0 siblings, 2 replies; 29+ messages in thread
From: Thomas Rast @ 2008-10-09 11:42 UTC (permalink / raw
  To: git; +Cc: santi, Dmitry Potapov, Junio C Hamano

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(-)

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)

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Interdiff] [RFC PATCH v2] Documentation: add manpage about workflows
  2008-10-09 11:42                   ` [RFC PATCH v2] " Thomas Rast
@ 2008-10-09 11:42                     ` Thomas Rast
  2008-10-09 12:50                     ` Junio C Hamano
  1 sibling, 0 replies; 29+ messages in thread
From: Thomas Rast @ 2008-10-09 11:42 UTC (permalink / raw
  To: git; +Cc: santi, Dmitry Potapov, Junio C Hamano

---

I wrote:
> Interdiff will follow, as before.



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`

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH v2] Documentation: add manpage about workflows
  2008-10-09 11:42                   ` [RFC PATCH v2] " Thomas Rast
  2008-10-09 11:42                     ` [Interdiff] " Thomas Rast
@ 2008-10-09 12:50                     ` Junio C Hamano
  2008-10-19 15:20                       ` [RFC PATCH v3] " Thomas Rast
  1 sibling, 1 reply; 29+ messages in thread
From: Junio C Hamano @ 2008-10-09 12:50 UTC (permalink / raw
  To: Thomas Rast; +Cc: git, santi, Dmitry Potapov, Junio C Hamano

Thomas Rast <trast@student.ethz.ch> writes:

> 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.

> +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.

> +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.

> +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.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [RFC PATCH v3] Documentation: add manpage about workflows
  2008-10-09 12:50                     ` Junio C Hamano
@ 2008-10-19 15:20                       ` Thomas Rast
  2008-10-19 15:20                         ` [Interdiff] " Thomas Rast
  2008-10-19 20:07                         ` Junio C Hamano
  0 siblings, 2 replies; 29+ messages in thread
From: Thomas Rast @ 2008-10-19 15:20 UTC (permalink / raw
  To: Junio C Hamano; +Cc: git, santi, Dmitry Potapov

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>

---

> > +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(-)

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)

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Interdiff] [RFC PATCH v3] Documentation: add manpage about workflows
  2008-10-19 15:20                       ` [RFC PATCH v3] " Thomas Rast
@ 2008-10-19 15:20                         ` Thomas Rast
  2008-10-19 20:07                         ` Junio C Hamano
  1 sibling, 0 replies; 29+ messages in thread
From: Thomas Rast @ 2008-10-19 15:20 UTC (permalink / raw
  To: Junio C Hamano; +Cc: git, santi, Dmitry Potapov

---
 Documentation/gitworkflows.txt |   72 ++++++++++++++++++++-------------------
 1 files changed, 37 insertions(+), 35 deletions(-)

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

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC PATCH v3] Documentation: add manpage about workflows
  2008-10-19 15:20                       ` [RFC PATCH v3] " Thomas Rast
  2008-10-19 15:20                         ` [Interdiff] " Thomas Rast
@ 2008-10-19 20:07                         ` Junio C Hamano
  1 sibling, 0 replies; 29+ messages in thread
From: Junio C Hamano @ 2008-10-19 20:07 UTC (permalink / raw
  To: Thomas Rast; +Cc: git, santi, Dmitry Potapov

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?

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2008-10-19 20:08 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-02 20:18 [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
2008-09-02 21:39 ` Junio C Hamano
2008-09-03  5:38   ` Thomas Rast
2008-09-11 15:38     ` [PATCH 0/2.5] " Thomas Rast
2008-09-11 15:38       ` [PATCH 1/2] " Thomas Rast
2008-09-11 15:38         ` [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
2008-09-11 16:37             ` Jakub Narebski
2008-09-12  7:26             ` [RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows] Thomas Rast
2008-09-20  0:22             ` [RFC PATCH] Documentation: add manpage about workflows Santi Béjar
2008-09-21 20:26             ` Dmitry Potapov
2008-09-30 16:05               ` Thomas Rast
2008-09-30 16:07                 ` Thomas Rast
2008-10-01  9:54                 ` Santi Béjar
2008-10-09 11:42                   ` [RFC PATCH v2] " Thomas Rast
2008-10-09 11:42                     ` [Interdiff] " Thomas Rast
2008-10-09 12:50                     ` Junio C Hamano
2008-10-19 15:20                       ` [RFC PATCH v3] " Thomas Rast
2008-10-19 15:20                         ` [Interdiff] " Thomas Rast
2008-10-19 20:07                         ` Junio C Hamano
2008-09-12  1:15         ` [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase Marcus Griep
2008-09-13  5:08         ` Junio C Hamano
2008-09-13 16:10           ` [PATCH 0/3] Documentation: rebase and workflows Thomas Rast
2008-09-13 16:11             ` [PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
2008-09-13 16:11               ` [PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
2008-09-13 16:11                 ` [PATCH 3/3] Documentation: add manpage about workflows Thomas Rast
2008-09-13 16:11                   ` Interdiff: [3/3] " Thomas Rast
2008-09-08 22:55 ` [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Junio C Hamano
2008-09-09  5:42   ` Thomas Rast

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).