There is actually a third possbility—and most probably plenty of others, since GIT is more an implementation of a SCM framework than an implementation of a SCM methodology. This third possibility is based on rebase
.
The rebase
GIT subcommand takes a series of commit (typically from your branching point to the tip of your topic branch topic
) and replay them somewhere else (typically at the tip of your integration branch, e.g. master
). The rebase
subcommand produces new commits, which gives the opportunity of rearranging commits in a form that is easier to review. This yields a new series of commit, similar to what topic
used to be but appearing rooted at the top of the integration branch. This new branch is still called topic
by GIT, so that the old reference is discarded. I informally label topic-0
the original state of your branch and topic-1
and so on its various refactoring.
Here is my suggestion for your topic
branch:
(Optional step) You interactively rebase your topic branch topic
on its branching point (see --fixup
option for commit
and the -i
and --autosquash
options on rebase
), which gives you the opportunity to rewrite your commits in a way that is easier to review. This results in a branch topic-1
.
You rebase your topic branch at the top of your integration branch, is similar to doing a merge, but “does not pollute” history with a merge that is merely a software engineering artifact. This results in a branch topic-2
.
Send topic-2
to a teammate that reviews it against the tip of master
.
If topic-2
is okay then merge it to master.
NOTE The branches—where branch refers to the commit tree—will all be called the same by GIT, thus, at the end of the process, only the branch topic-2
has a name in GIT.
Pros:
- No obsolete code in review.
- No spurious “foreign merges” reviews (the phenomenon you described in 1st).
- Opportunity to rewrite commits in a clean way.
Cons:
- Instead of one branch
topic-0
, there is three branches artifacts topic-0
, topic-1
and topic-2
that are created in the commit tree. (Though at any time, only one of them has a name in GIT.)
In your 1st scenario «if someone merged something between "1." and "2."» refers to time spanning between the creation of the branch point and the time when you decide to merge. In this scenario «if someone merged something between "1." and "2."» refers to the time spanning between the rebase and the merge, which is usually very short. Thus in the scenario I provide, you can «lock» the master
branch for the time of the merge without disturbing signigicantly your workflow, while it is impractical in the 1st scenario.
If you are doing systematic code reviews, it is probably a good idea to rearrange commits in an adequate way (optional step).
Managing the intermediate branch artifacts only presents a difficulty if you share them between repositories.