user5539357
user5539357

Reputation: 1066

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 master at origin is on the left. Both branches are the same.

enter image description here

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.

enter image description here

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 origin repo's 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 local commit.

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 master branch?

enter image description here

Upvotes: 6

Views: 2727

Answers (3)

David Deutsch
David Deutsch

Reputation: 19035

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:

A--B--C--M
   \--D-/

In other words, both C and D will have B as a parent, and both C and 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.

Upvotes: 9

vonbrand
vonbrand

Reputation: 11831

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.

Upvotes: 0

nathan.medz
nathan.medz

Reputation: 1603

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.

Upvotes: 1

Related Questions