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 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.
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
(Optional step) You interactively rebase your topic branch
topic on its branching point (see
--fixup option for
commit and the
--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
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 to a teammate that reviews it against the tip of
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.
- No obsolete code in review.
- No spurious “foreign merges” reviews (the phenomenon you described in 1st).
- Opportunity to rewrite commits in a clean way.
- Instead of one branch
topic-0, there is three branches artifacts
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.