MegaManX
MegaManX

Reputation: 8918

Coming from mercurial to git - merging?

I have used mercurial for quite some time and now I switched to git, because my new team uses it as default version control tool.

Let me explain - In mercurial I clone project from bitbucket, i make some changes to project. Then I pull from bitbucket again and merge my changes with everything that has changed on bitbucket. Then i push everything.

Does it work same with git? I have cloned project, made some changes, done some commits to them, now i pulled project, and i want to merge. These previous steps work fine, but merging is a little different or at least it looks different to me. How do i merge my commits with new commits that i just pulled from server?

PS: Both my changes and changes on server have been done on main branch, i am not looking to merge 2 branches.

Upvotes: 1

Views: 254

Answers (4)

Yawar
Yawar

Reputation: 11607

My advice is stay away from git rebase/pull --rebase until you're comfortable with git branches. Now, the most important thing which I'm suprised no one has mentioned yet:

hg pull just gets new changesets to your local repo and does not affect your working copy.

git pull gets new commits and tries to automatically merge the just-pulled HEAD with your local HEAD. If you had uncommitted changes it could cause you some trouble.

Solution: for now at least, always use git fetch. This does not affect your working copy and lets you do merges on your own time, like with Mercurial. In other words, git fetch = hg pull.

Upvotes: 2

alternative
alternative

Reputation: 13002

You might claim that you are not intending to merge two branches, but fundamentally you are.

Consider the initial state: We have two heads, master and origin/master which both point to commit A. Then someone adds commits B and C and pushes to the origin remote, which you fetch. However, before you fetched, you added commits D, E, and F to your master branch, so after the fetch the DAG layout looks like this:

A ->  B -> C [origin/master]
|
\--> D -> E -> F [master]

And you want to push your changes to the origin repository. But your changes clearly conflict with the origin/master branch, to do this, you would have to merge origin/master and master.

Having a lot of merges can be ugly, so under a few important conditions we can perform a rebase instead. However, you have to be careful - you can't have pushed these changes to any other external repository or anything like that, or you will break anything else thats based on these commits. I also would not have anything else based off of your current master, because those commits will now be outdated.

Hence, you have two options:

  • Merge origin/master into master: git merge origin/master && git push origin master
  • Rebase master onto origin/master: git rebase origin/master && git push origin master

Both of these can be combined with git-fetch to create git-pull, which will automatically use the merging method unless you supply the option --rebase, in which case it performs a rebase instead.

Just remember to be careful with always using --rebase due to the nature of the rebase command.

Final state after using a merge:

A ->  B -> C -----> G
|                   |
\--> D -> E -> F ----

Final state after using a rebase:

A -> B -> C -> D -> E -> F

Upvotes: 1

Paul S
Paul S

Reputation: 7755

My understanding of it, coming as a fellow Mercurial user, is that in Git all heads must have unique names. Hence, it won't create a new head unless you give it a new name. So in Mercurial you might do this:

hg pull   / git pull
hg commit / git commit
hg commit / git commit

----B----C1----C2 

Where B is the base revision you originally pulled, and C1 and C2 are your changes. You then pull the updates from the server.

hg pull

----B----C1----C2
     \
      ----o----o----o

Git wont do this, as it would have had to create another head. Hence you have to rebase / graft your changes on top of the servers.

git pull --rebase

----B----o----o----o----C1----C2

The alternative is when you start your work in Git you create a name for your head. Git calls it a branch, Hg calls it a bookmark.

hg pull     / git pull
hg bookmark / git branch
hg commit   / git commit
hg commit   / git commit

----B----C1----C2 
                ^ New-Feature

Now the head has a name ("New-Feature" in this case). Now Git will happily pull, just like Hg.

hg pull / git pull

----B----C1----C2
     \          ^ New-Feature
      ----o----o----o

You can then merge in the same way too.

Upvotes: 1

Fred Foo
Fred Foo

Reputation: 363547

git pull --rebase origin master

pulls in changes and stacks your local changes on top.

However, making branches for just about every new feature is the intended workflow for Git, so you might want to learn about them anyway. Fast branching and merging is Git's killer feature.

Upvotes: 4

Related Questions