Home > Other > Merge Bubbles. No. Bad.

Merge Bubbles. No. Bad.

Hey you.. listen up!

I know, I know, I also felt the pain. Git: “Huuhh?? I have to commit and push? Uh.. And what’s the difference between git fetch and git pull?”

I know. But here’s something that will help: SVN and CVS are CVCS’s: Centralized Version Control Systems. Git is much closer to a file system. And please, don’t use Git like you used SVN or CVS.

Git repository example structureThe picture on the left is from a interesting talk on language developments from the creator of Clojure, Rick Hickey. You can find the talk here.

But it also (coincidentally) has a decent representation of how the Git ‘file’ system works. We can look at the two “trees” in this picture as branches in a Git repository.

However, what I really want you to take away from the minutes spent reading this is that you need to stop using Git as if it was SVN or CVS. You need to stop using merge unless you wanted to shout at everyone who looks at that merge commit later that “YES, I MERGED STUFF HERE!”.

This is the leap that Git has achieved: Git has made commits into a form of documentation. Commits with Git are so transparent and easy to manage and follow that everyone sees the commits — and wants to look at them.

However, most people use merge because they run into the following:

My teammate/colleague just committed something and I can no longer push to the repository!

So what do we do? What we do not do, is merge. Okay?

The first thing we do do is copy the name of the commit we’ve made. Now that the changes have been committed, that commit now exists on the “Git filesystem”, regardless of whether or not it’s part of a branch.

$ git commit -m"Added tests for new Fromungulator logic"
[master 0ca7df5] Added tests for new Fromungulator logic
 4 files changed, 3 insertions(+), 1 deletions(-)

0ca7df5 is of course your commit hash — or, if we’re thinking in terms of the Git file system, it’s the reference to the “git file” that contains your commit. Of course, if your colleague went ahead and pushed a commit to the repository before you could, you’ll see this:

$ git push origin master
To git@github.com:mrietveld/frunubucation.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:mrietveld/frunubucation.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

They lie.. Do not, I repeat, do not then go do this:

git pull origin master

(unless you’ve setup your branch with auto-rebasing. There’s a funny post about that here.)

There are lots of ways to avoid merge bubbles, but the fastest is probably to do the following:

git fetch origin
git rebase origin/master

Rebase! Man, I love git! Rebase is the equivalent to doing this:

git reset --hard HEAD^1
git merge --ff origin/master
git cherry-pick 0ca7df5

And once you’re done, you’ll want to push that commit to the origin repository:

git push origin master

Why do we nog cause merge bubbles? Because:

  • Merge bubbles make it hard to determine which commit caused which change in the code
  • Merge bubbles make it hard to retroactively fork off a branch from a different commit.

The first reason, determining which commit caused what, is really enough, though. That’s one of the main reasons you’re using a versioning system!

 

Advertisements
Categories: Other
  1. 5 June 2013 at 20:06

    A bit confused. First, I see:

    They lie.. Do not, I repeat, do not then go do this:

    git pull origin master

    followed by

    Actually, you can also probably just do a

    git pull origin master
    instead of the fetch and the merge.

    • mriet
      24 October 2013 at 15:05

      Oops.. good point! Thanks, I’ve updated the post.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: