Discussions of git and an experiment

The company I work for (youDevise) hosted the Stackoverflow meetup the other week. I got to meet a few people, eat, some pizza, and play a game on a Kinect. The evening ended with a discussion about the branching and merging capabilities of git versus those of subversion. Rather than us simply talking about the differences and probably getting many of them wrong, one of the guys challenged me to try out the scenarios we had been discussing and write up a post about it. This is the result.

Setup

I’ve written up a little Perl script to play out various scenarios of using a version control system. You can find the code for the script and the 3 scenarios in my github repository. The script provides a simple DSL for creating files, changing files, renaming files, creating branches, and merging between branches. I was looking for how subversion and git handle merging together changes between two branches that consist of these operations.

Scenario 1: Same change

Script

on master => perform {
    add file => "this is the one file";
    commit "the file"
};

branch master => other;

on other => perform {
    change file => "this is the file";
    commit "not the only one"
};

on master => perform {
    change file => "this is the file";
    commit "not alone"
};

merge other => master;

Result

Both svn and git ended up doing the same thing in this scenario: merge without conflict.

Scenario 2: Different change

Script

on master => perform {
    add file => "this is the one file";
    commit "the file"
};

branch master => other;

on other => perform {
    change file => "this is the file";
    commit "not the only one"
};

on master => perform {
    change file => "this is one file";
    commit "not *the* only file"
};

merge other => master;

Result

In this case both git and svn once again produced the same outcome: a conflict. Nothing too surprising here.

Scenario 3: File change against a rename

Script

on master => perform {
    add file => "this is the one file";
    commit "the file"
};

branch master => other;

on other => perform {
    move file => new_file_name;
    commit "changed name"
};

on master => perform {
    change file => "this is one file";
    commit "not *the* only file"
};

merge other => master;

Result

The result of this was a bit surprising to me, but completely understandable. Svn considered this to be a conflict: the file hand been changed, but it had also been moved while holding the original contents. Git on the other hand considered this to be OK and went ahead without a conflict. Git renamed the file, but with the new contents.

I can see logic on both of these outcomes. Git’s result may be nicer quite often, but svn is more conservative and may be less likely to end up causing unintended errors without it having at least warned you.

Conclusion

This was a fun little experiment, and I went a little overboard doing it by creating a little internal DSL for perl to execute the scenarios on the two VCS systems. The experiments showed me that git and svn will end up doing different things, but these simple little cases are of course in no way comprehensive. It would be great if others would contribute scenarios that they thought are interesting. If anyone wants to they can also hack away at adding other systems (maybe Mercurial or even CVS for nostalgia).

On the topic of which one is better, I did have a bit of time to reflect while creating these scripts. Each system has strengths and weaknesses, each one promotes different styles of working. Which of any of the many VCS technologies out there is best for any particular group is hard to say. Each group or individual needs to examine the way they work, want to work, and can work and then evaluate what out there best fits their needs.

Advertisements
This entry was posted in Software and tagged , , , . Bookmark the permalink.

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