основное руководство Git для разработчиков (A Git core tutorial for developers)
BUNDLING YOUR WORK TOGETHER
It is likely that you will be working on more than one thing at a
time. It is easy to manage those more-or-less independent tasks
using branches with Git.
We have already seen how branches work previously, with "fun and
work" example using two branches. The idea is the same if there
are more than two branches. Let's say you started out from
"master" head, and have some new code in the "master" branch, and
two independent fixes in the "commit-fix" and "diff-fix"
branches:
$ git show-branch
! [commit-fix] Fix commit message normalization.
! [diff-fix] Fix rename detection.
* [master] Release candidate #1
---
+ [diff-fix] Fix rename detection.
+ [diff-fix~1] Better common substring algorithm.
+ [commit-fix] Fix commit message normalization.
* [master] Release candidate #1
++* [diff-fix~2] Pretty-print messages.
Both fixes are tested well, and at this point, you want to merge
in both of them. You could merge in diff-fix first and then
commit-fix next, like this:
$ git merge -m "Merge fix in diff-fix" diff-fix
$ git merge -m "Merge fix in commit-fix" commit-fix
Which would result in:
$ git show-branch
! [commit-fix] Fix commit message normalization.
! [diff-fix] Fix rename detection.
* [master] Merge fix in commit-fix
---
- [master] Merge fix in commit-fix
+ * [commit-fix] Fix commit message normalization.
- [master~1] Merge fix in diff-fix
+* [diff-fix] Fix rename detection.
+* [diff-fix~1] Better common substring algorithm.
* [master~2] Release candidate #1
++* [master~3] Pretty-print messages.
However, there is no particular reason to merge in one branch
first and the other next, when what you have are a set of truly
independent changes (if the order mattered, then they are not
independent by definition). You could instead merge those two
branches into the current branch at once. First let's undo what
we just did and start over. We would want to get the master
branch before these two merges by resetting it to master~2:
$ git reset --hard master~2
You can make sure git show-branch
matches the state before those
two git merge you just did. Then, instead of running two git
merge commands in a row, you would merge these two branch heads
(this is known as making an Octopus):
$ git merge commit-fix diff-fix
$ git show-branch
! [commit-fix] Fix commit message normalization.
! [diff-fix] Fix rename detection.
* [master] Octopus merge of branches 'diff-fix' and 'commit-fix'
---
- [master] Octopus merge of branches 'diff-fix' and 'commit-fix'
+ * [commit-fix] Fix commit message normalization.
+* [diff-fix] Fix rename detection.
+* [diff-fix~1] Better common substring algorithm.
* [master~1] Release candidate #1
++* [master~2] Pretty-print messages.
Note that you should not do Octopus just because you can. An
octopus is a valid thing to do and often makes it easier to view
the commit history if you are merging more than two independent
changes at the same time. However, if you have merge conflicts
with any of the branches you are merging in and need to hand
resolve, that is an indication that the development happened in
those branches were not independent after all, and you should
merge two at a time, documenting how you resolved the conflicts,
and the reason why you preferred changes made in one side over
the other. Otherwise it would make the project history harder to
follow, not easier.