Reputation: 7407
There are two branches I am working with, master
and newFeature
. While building the "new feature", I added multiple commits to the newFeature
branch. My understanding of git merge
is that it will create a single commit on master
once the branches are merged, however when merged, master
now has the full commit history that is on newFeature
. For example-
master (pre-merge):
1=>2=>3
newVersion:
1=>2=>3=>4=>5=>6
master (actual results of merge):
1=>2=>3=>4=>5=>6
master (expected results of merge):
1=>2=>3=>6
Is there any way to remove the intermediary commits from newVersion
during the merge, and why isn't merge working as expected?
Upvotes: 10
Views: 7658
Reputation: 7407
The key to note here, is that no changes have been made to master
throughout the course of your work on newVersion
. In these situations, Git defaults to a "fast-forward" merge, which can essentially be thought of as taking all of the new commits from newVersion
and appending them to the most recent commit on master
(which does not separate the commit history that was done on newVersion
). This can be overridden with the --no-ff
flag, for example:
git merge newVersion --no-ff
Results in:
master (pre-merge):
1=>2=>3
newVersion:
1=>2=>3=>4=>5=>6
master (actual results of merge):
1=>2=>3=========>7
4=>5=>6
Note that, commit 7 represents the merge, and does not replace the commit history.
Reference: https://sandofsky.com/images/fast_forward.pdf
Alternatively, if you would prefer to consolidate the entire commit history of newVersion
into a single commit on master
(could be useful if they were simply minor commits throughout the progression of the "new version") you could run the merge with the --squash
flag. For example:
git merge --squash newVersion
Results in:
master (pre-merge):
1=>2=>3
newVersion:
1=>2=>3=>4=>5=>6
master (actual results of merge):
1=>2=>3=>7
Note that, 7 consolidates the commit history that was done in commit 4 - 6
Upvotes: 13
Reputation: 28752
It's not possible to have a final history that looks like what you want. Each commit in git is tied to its parent. Each commit contains a reference to its parent, so 6 explicitly references 5.
If you do actually want only the changes between 5 and 6 to be added on top of 1=>2=>3
, then you can use git cherry-pick newFeature
. This will create a new commit which has just the changes between 5 and 6, but applied on top of 3.
If you want all the changes from 4, 5, and 6 but you only want a single commit, then you can use the --squash
flag to git merge
. This will create a single new commit which contains all the changes from 4, 5, and 6. However, your history will not be 1=>2=>3=>6
, but 1=>2=>3=>7
where 7 is this new commit.
Note that if you choose the --squash
option, you can only do this once for each branch since by squashing, you're losing the information about what's different between the two branches.
Upvotes: 1