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