From: Junio C Hamano <hidden> Date: 2016-06-15 22:45:17
Thomas Rast [off-list ref] 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/681763http://article.gmane.org/gmane.linux.kernel/684030http://article.gmane.org/gmane.linux.kernel/684073http://article.gmane.org/gmane.linux.kernel/684091http://article.gmane.org/gmane.linux.kernel/638511
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:17
Junio C Hamano wrote:
Thomas Rast [off-list ref] writes:
quoted
+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
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:21
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 <redacted>
---
Documentation/git-commit.txt | 4 ++++
Documentation/git-filter-branch.txt | 4 +++-
Documentation/git-reset.txt | 4 +++-
3 files changed, 10 insertions(+), 2 deletions(-)
@@ -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::
@@ -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
@@ -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:: +
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:21
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 <redacted>
---
Documentation/git-rebase.txt | 103 +++++++++++++++++++++++++++++++++++++++--
1 files changed, 98 insertions(+), 5 deletions(-)
@@ -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
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:21
So here's the follow-up I promised.
Junio C Hamano [off-list ref] wrote:
Thomas Rast [off-list ref] writes:
quoted
- 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/
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:21
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 <redacted>
---
Documentation/Makefile | 2 +-
Documentation/gitworkflows.txt | 326 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 327 insertions(+), 1 deletions(-)
create mode 100644 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.
From: Marcus Griep <hidden> Date: 2016-06-15 22:45:21
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
את.ψο´
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:21
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
On Thu, Sep 11, 2008 at 5:39 PM, Thomas Rast [off-list ref] 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 <redacted>
---
Documentation/Makefile | 2 +-
Documentation/gitworkflows.txt | 326 +
+++++++++++++++++++++++++++++++++++++++
It should be linked/advertised from other pages (git, tutorial, everyday?)
+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.
--
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
From: Thomas Rast <hidden> Date: 2016-06-15 22:45:25
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.
@@ -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
On Tue, Sep 30, 2008 at 6:05 PM, Thomas Rast [off-list ref] 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.
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.
@@ -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`
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(-)
@@ -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)