Who we are

We are the developers of Plastic SCM, a full version control stack (not a Git variant). We work on the strongest branching and merging you can find, and a core that doesn't cringe with huge binaries and repos. We also develop the GUIs, mergetools and everything needed to give you the full version control stack.

If you want to give it a try, download it from here.

We also code SemanticMerge, and the gmaster Git client.

Git merge vs the world

Thursday, November 17, 2011 Pablo Santos , 4 Comments

I’ll be talking about git merge system again, one of the strongest on the planet, and how a good merge system can unlock a new world of possibilities for developers facing complex refactors.

And then, I’ll tell you how to break it. And what can be done.

Refactor and merge

What does refactor have to do with merge? Aren’t merging and refactors on different planets?

Not at all: you’re working on a refactor and then you need to move Class.java to a new package. It happens, doesn’t it?

But while you’re working on your refactor, I’ll be tweaking Class.java.

Ok, now refactor has to do with merging, and if you’re avoiding this situation it only means one thing: you don’t have a proper SCM (we could argue but, ok, tell me you do not need a mouse, a good IDE...).

The good, the bad and the ugly

Now you’ve to merge the previous scenario. What will happen?

  • Git (and of course my beloved Plastic SCM) will do the right thing: you get the rename plus the change. This IS what you expect.
  • SVN and the old fashioned pack (the bad and ugly) will, at best, end up with two files: the “old” Class.java with my changes plus yours, without my changes, on your destination location. Crazy.

Let’s break it

Let’s do something else: you move and modify Class.java. But I do the same… moving it (of course!) to a different location.

Don’t do this at home with SVN: ok, the movie is over from the non-dvcs/non-merging scms, let’s focus on the real mergin machines.

Git it!

How does Git handle it?

$ git commit -a -m "initial"
Created initial commit ced4e21: initial
 1 files changed, 181 insertions(+), 0 deletions(-)
 create mode 100644 foo.cs

$ git branch task001
$ git checkout task001
Switched to branch "task001"
$ vi foo.cs
$ git mv foo.cs bar.cs
$ git commit -a -m "change on task001 + rename"
Created commit d3c6970: change on task001 + rename
 2 files changed, 181 insertions(+), 181 deletions(-)
 create mode 100644 bar.cs
 delete mode 100644 foo.cs

First move and change, let's go to the second.

$ git checkout master
Switched to branch "master"
$ vi foo.cs
$ git mv foo.cs moo.cs
$ git commit -a -m "change on master + rename"
Created commit 4644cb7: change on master + rename
 2 files changed, 182 insertions(+), 181 deletions(-)
 delete mode 100644 foo.cs
 create mode 100644 moo.cs

$ git merge task001
CONFLICT (rename/rename):
Rename "foo.cs"->"moo.cs" in branch "HEAD" 
rename "foo.cs"->"bar.cs" in "task001"
Automatic merge failed; 
fix conflicts and then commit the result.

Ok, git nows about but... how does it handle it?

$ git status
# On branch master
# Changed but not updated:
#       unmerged:   bar.cs
#       unmerged:   foo.cs
#       unmerged:   moo.cs
#       modified:   moo.cs

no changes added to commit

$ ls
bar.cs  moo.cs

Ooooops! The files are not merged and you’ve to solve the conflict yourself!!!

Plastic it!

Is there a better way?

Yes: the dvcs should:

  • ask you: which rename do you prefer? (or any other option)
  • help you solve the rename
  • merge the files

And that’s what Plastic SCM does.

I’m happy to say that we’re launching Plastic SCM 4.0 today at www.plasticscm.com/launch... Join now! Superheroes already did http://plasticscm.com/heroestalk

Pablo Santos
I'm the CTO and Founder at Códice.
I've been leading Plastic SCM since 2005. My passion is helping teams work better through version control.
I had the opportunity to see teams from many different industries at work while I helped them improving their version control practices.
I really enjoy teaching (I've been a University professor for 6+ years) and sharing my experience in talks and articles.
And I love simple code. You can reach me at @psluaces.


  1. "we could argue but, ok, tell me you do not need a mouse, a good IDE…"

    i use vim, your argument is invalid.

  2. Congratulations for the launch!

    Beware, the Launch link is not correct (lacks http://) and also at the launch site: "Check the videos from de launch event hold on Nov 17th"

  3. Git is explicitly not interactive unless you ask it to be. "git merge-tool" will resolve the conflict listed.

  4. I don't think mergetool will solve the directory or files being renamed at all