Can a merge change the commits history of a branch?
Apparently it can, see here – at least this is the way I see it.
Before merge. The remote branch
origin is on the left. Both branches are the same.
Now suppose both me and my friend have done some work, and my friend pushed his work first to the remote branch, and I have commited my work locally.
In this case I can’t simply
git push, because that would cause
commited by other to be removed from the remote repo (I think I could do `git push -f for that, but again – that would overwrite my friend’s commit).
The article suggests that
git pull origin master (which
fetches the changes from the
master branch and
merges it into my local
master branch) rewrites the history of commits in my local
master branch! How can it be? I thought a merge can only create a new merge commit, without altering the existing commits. But in this case, the commits order has changed – now the
commited by other comes first, then my
So, knowing that pull is the same as fetch (which updates the remote-tracking branch
origin/master that is stored locally on my PC) followed by merging the updated
origin/master into the local branch
master, would it produce the same result in this case – would that merge alter the order of past commits in the local
3 Solutions collect form web for “Can a merge change the commits history of a branch?”
But in this case, the commits order has changed – now the commited by other comes first, then my local commit.
This is not true – your local commit and the “committed by other” are peers, or siblings. The new merge commit has them both as parents. Does that make sense? Your commit history is not changed in the least.
I cannot seem to access the site you posted, but the title in the url refers to merging and rebasing, and avoiding “rebase hell”. Rebasing does indeed change your history; perhaps that is what the author was talking about.
Edit in response to comment: If you have
A-B-C locally and
A-B-D on the remote, after a fetch and merge your local will look like:
In other words, both
D will have
B as a parent, and both
D will be parents of
M. After you push, the remote branch will also look like this.
Now at first, you may think, “so my history does change, because
B used to have one child, and now it has two”. But git does not store pointers to children, it only stores pointers to parents. And
C still has the single parent
B, so your history did not change. And since
D still has the single parent
B, the remote’s history did not change either.
What David said is true, the two commits are siblings and the merge commit is their child. However, if you do want to functionality where the remote commit is pulled down “under” your local commit, you can do
git pull --rebase which will pull down all remote commits and then replay yours on top of them without the merge commit.
A merge takes two or more branches, and creates a commit that interleaves the changes in all parents (resolving conflicts, as needed; the user has to decide how).
git does not change history by itself.
To change history, you have to request that explicitly, via
git rebase or other commands explicitly designed for such surgery. Needless to say, they are dangerous, and must be used with utmost care.