Reputation: 1641
Suppose this standard scenario:
Why? I want to maintain all dev history (so no squash, C2 C3 and C4) but when I merge into master I'd expect that dev and master ref both to C4. I don't see the need to create a new commit (and what should be the code differences between C4 and C5? They are identical), and I don't like that dev branch seems to be behind master while they contain the same code.
Can you explain to me why is that and if there is a better practice?
Upvotes: 5
Views: 2372
Reputation: 58
When you create a dev
branch from master
branch at commit C1 and add commits C2, C3, C4 on the dev
branch, the commit trees of both master
and dev
have diverged. Incorporating (specifically, "merge" and not "rebase") the changes from dev
branch to master
can be done in two ways -
Merging dev
into master
without fast-forwarding - The scenario you are facing falls under this category. What happens in non-Fast-forwarding scenarios is that your dev
branch "retains its identity" despite being merged into master
. The implication of this is that when you decide you do not want the changes brought in by the dev
branch to master
at a later point of time, you can easily revert the changes (multiple commits) brought in by the dev
branch with a single revert in master
on merge commit C5. The dev
branch retains its "identity" through the merge-commit C5 created at the time of merge. This method is typically favoured & frequently employed in merging pull requests. However, it comes with the additional overhead of 1 merge commit for every merge. Merge with no fast-forwarding can be done on the command-line with the following command on the master
branch-
git merge --no-ff dev
Note the --no-ff flag indicating "no fast-forwarding"
Diagrammatic Illustration of commit tree ofmaster
after the merge -
(dev)C2-C3-C4
/ \
(master)C1----------C5
Merging dev
into master
with fast-forwarding - This is the scenario you are expecting would happen upon merging dev
into master
via the pull request. In the case of fast-forwarding, the "identity" of the dev
branch is lost as illustrated below.
Diagrammatic Illustration of commit tree of master
after merge -
(master) C1-C2-C3-C4
In the figure for this case, at a later point in time (after more commits have been added to master
), if you decide to delete the changes brought in by dev
branch, you will not be able to exactly pinpoint at the commits which correspond to the dev
branch (especially if the dev
branch has been deleted). Thus, this is not the preferred method for merging pull requests where operations such as reverting are important. However, it is useful in scenarios where you are really sure the branch you are working on need not retain its identity. Fast-forwarding is also used in scenarios when you want to update your local copy of a branch with the branch it is tracking in the remote using git pull
. The git merge
command also resorts to fast-forwarding as its default behaviour.
Note -
Please note that fast-forwarding is only applicable for merging branch Y
into branch X
if
X
after Y
was split from it and,Y
after it's split from X
. If both X
and Y
have new commits after split, then a fast-forward is not possible.
Reference - https://confluence.atlassian.com/bitbucket/git-fast-forwards-and-branch-management-329977726.html
Upvotes: 5