Commit 310d188f authored by Junio C Hamano's avatar Junio C Hamano

Merge branch 'tr/workflow-doc'

* tr/workflow-doc:
  Documentation: add manpage about workflows
  Documentation: Refer to git-rebase(1) to warn against rewriting
  Documentation: new upstream rebase recovery section in git-rebase
parents adcb2e0f f948dd89
......@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
gitrepository-layout.txt
MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
gitdiffcore.txt
gitdiffcore.txt gitworkflows.txt
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
......
......@@ -145,6 +145,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
......
......@@ -259,11 +259,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
......@@ -398,6 +397,127 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
RECOVERING FROM UPSTREAM REBASE
-------------------------------
Rebasing (or any other form of rewriting) a branch that others have
based work on is a bad idea: anyone downstream of it is forced to
manually fix their history. This section explains how to do the fix
from the downstream's point of view. The real fix, however, would be
to avoid rebasing the upstream in the first place.
To illustrate, suppose you are in a situation where someone develops a
'subsystem' branch, and you are working on a 'topic' that is dependent
on this 'subsystem'. You might end up with a history like the
following:
------------
o---o---o---o---o---o---o---o---o master
\
o---o---o---o---o subsystem
\
*---*---* topic
------------
If 'subsystem' is rebased against 'master', the following happens:
------------
o---o---o---o---o---o---o---o master
\ \
o---o---o---o---o o'--o'--o'--o'--o' subsystem
\
*---*---* topic
------------
If you now continue development as usual, and eventually merge 'topic'
to 'subsystem', the commits from 'subsystem' will remain duplicated forever:
------------
o---o---o---o---o---o---o---o master
\ \
o---o---o---o---o o'--o'--o'--o'--o'--M subsystem
\ /
*---*---*-..........-*--* topic
------------
Such duplicates are generally frowned upon because they clutter up
history, making it harder to follow. To clean things up, you need to
transplant the commits on 'topic' to the new 'subsystem' tip, i.e.,
rebase 'topic'. This becomes a ripple effect: anyone downstream from
'topic' is forced to rebase too, and so on!
There are two kinds of fixes, discussed in the following subsections:
Easy case: The changes are literally the same.::
This happens if the 'subsystem' rebase was a simple rebase and
had no conflicts.
Hard case: The changes are not the same.::
This happens if the 'subsystem' rebase had conflicts, or used
`\--interactive` to omit, edit, or squash commits; or if the
upstream used one of `commit \--amend`, `reset`, or
`filter-branch`.
The easy case
~~~~~~~~~~~~~
Only works if the changes (patch IDs based on the diff contents) on
'subsystem' are literally the same before and after the rebase
'subsystem' did.
In that case, the fix is easy because 'git-rebase' knows to skip
changes that are already present in the new upstream. So if you say
(assuming you're on 'topic')
------------
$ git rebase subsystem
------------
you will end up with the fixed history
------------
o---o---o---o---o---o---o---o master
\
o'--o'--o'--o'--o' subsystem
\
*---*---* topic
------------
The hard case
~~~~~~~~~~~~~
Things get more complicated if the 'subsystem' changes do not exactly
correspond to the ones before the rebase.
NOTE: While an "easy case recovery" sometimes appears to be successful
even in the hard case, it may have unintended consequences. For
example, a commit that was removed via `git rebase
\--interactive` will be **resurrected**!
The idea is to manually tell 'git-rebase' "where the old 'subsystem'
ended and your 'topic' began", that is, what the old merge-base
between them was. You will have to find a way to name the last commit
of the old 'subsystem', for example:
* With the 'subsystem' reflog: after 'git-fetch', the old tip of
'subsystem' is at `[email protected]\{1}`. Subsequent fetches will
increase the number. (See linkgit:git-reflog[1].)
* Relative to the tip of 'topic': knowing that your 'topic' has three
commits, the old tip of 'subsystem' must be `topic~3`.
You can then transplant the old `subsystem..topic` to the new tip by
saying (for the reflog case, and assuming you are on 'topic' already):
------------
$ git rebase --onto subsystem [email protected]{1}
------------
The ripple effect of a "hard case" recovery is especially bad:
'everyone' downstream from 'topic' will now have to perform a "hard
case" recovery too!
Authors
------
Written by Junio C Hamano <[email protected]> and
......
......@@ -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::
+
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment