From CVS to Git, 9 Things I’ve Learned

From CVS to Git, 9 Things I’ve Learned

As frequent readers of my blog know I’ve been transitioning to git lately. I actually think CVS (with the Eclipse Team Support, local history management and Mylyn) makes a solid source control management solution. However, now that I’ve spent a few weeks with Git, I’m having trouble going back.

I don’t like drinking fine wine, because when I return to my home brew I’m always disappointed. For the same reason, I don’t like git.

I decided to record some of things I learned while moving from CVS (a centralized version control system) to git (a distributed version control system).

1. Commit early, commit often

Unlike centralized version control systems, with Git each developer has their own copy of the repository.  This means you can commit as often as you want without affecting others. Even if your changes are incomplete, breaks API or causes the build to fail — you can commit.  This allows you to structure your commits as logical units of work, as opposed to one monolithic commit that represents the entire new feature.

Once you have your feature completed, you can share your commits with others.

2. May the fork be with you

Services like GitHub are a great way to share projects with others.  The service is free for OpenSource projects, and for a fee it can be used for private repositories. Git makes it easy to fork repositories, evolve them independently, and merge the changes back. You can even ‘cherry-pick’ particular commits.

In the past, forks were often frowned upon because of the fragmentation they caused and the challenges related to merging.  A distributed version control system changes this. Since git store the relationships between commits, merging forks back together is relatively easy.  Encourage forks among you and your team members and don’t worry about the merge step.

3. Check your head

If you end up on the wrong branch, or accidentally reset your head pointer, your source tree may not look as you expect it to. Honestly, take some time to understand how git represents commits. Understanding this was the biggest challenge I faced.  There are some good articles here and here.

Once you understand this, make sure you don’t lose your head.

4. RTFL: Read The Frickin (ref)Log

If you get into trouble, lose commits, or find you’ve broken everything, turn to your reflog. The reflog has saved me many times.  The reflog will show you all your recent repository activity. From here, you can reset your repository to any recent commit.

5. To pull or to fetch, that is the question

In most centralized version control systems, updating your local source tree (to match the repository) cannot be taken lightly.  If you’ve made significant changes, updating from ‘HEAD’ can cause a tremendous headache.  This is because you are essentially ‘fetching the new revision’ and ‘merging it with your source tree’. In git, the concept of ‘fetching’ and ‘merging’ can actually be applied separately.  If you simply want to update your local copy of a remote branch, you do a fetch. You can defer the actual merging to later date. If you want to combine these two operations (fetch and merge) then you can issue a pull request.

6. Shut-up and just branch

Branching and merging in CVS is a pain.  In fact, until the code is properly merged and committed to ‘HEAD’, I don’t consider it complete.  Git on the other hand stores the relationship between commits, which enables much better merge support.  Merging in git is often an effortless operation.  For this reason, I suggest creating a branch whenever you start working on a new feature.  At any point you can ‘merge’ or ‘rebase‘ with the master branch, as well as share your branch with others for easy collaboration.   Separate branches makes it very easy to move effortlessly between tasks.

7. Stash it, don’t trash it

If you need to switch tasks and you’re not able to commit your current work, checkout the git stash.  Git allows you to stash your current changes for easy retrieval at a later date. This means you can stash your current work, reset the branch and work on something else. Then, you can retrieve the stash and continue working right where you left off.

8. Play the blame game

If you need to see when a particular line of code was introduced and who committed it, turn to git blame. Git blame shows the revision and author who last modified each line of a file. It also shows the commit comment for each line.

9. Those who don’t learn from history, are destined to repeat it

The CVS history view is an archaeology tool.  That is, it’s used to unearth historical artifacts about your source code.  It’s used to see who added a particular line of code, or to read the commit messages that accompanies a code change.  While using Git, the history view is a development time tool.  It’s used to see what else is happening in the repository, and to better understand the relationship between commits.  Get used to having this view open. Understanding your history is an important part of working with git.

12 Comments
  • Posted at 2:04 am, June 9, 2011

    I completely agree with #6 and to expand a bit on that point, you should also familiarize yourself with git-reflog which shows you what you have been up to. We hope to add a reflog view in EGit 1.1 so you don’t have to drop to the CLI to use this useful feature.

  • Posted at 3:06 am, June 9, 2011

    Git blame is a great tool as well. Glad to see we’ve converted you over to the Good Side of the Force,

  • Posted at 12:53 pm, June 9, 2011

    Readers might also be interested in my Git Tip of the Week series – I covered stash and reflogs a few weeks back.

    http://alblue.bandlem.com/search/label/gtotw

    Alex (@alblue)

  • Ian Bull
    Reply
    Posted at 4:04 pm, June 9, 2011

    @Alex,

    I actually linked to your gtotw when I talked about stashes 😉

  • Raphas
    Reply
    Posted at 5:04 pm, June 9, 2011

    For number 6, I don’t CVS that much, but for SVN, I can just branch and merge every new functionnality I’m building right ? What would be the advantage of Git and “relationships with commit” ? Can you illustrate how this is creating issues in CVS ? Much thanks !!

    Raphaël.

  • Lee Doolan
    Reply
    Posted at 8:48 pm, June 9, 2011

    I would mention that my usual Modus Operendi is to do all of my work on local branches.

    I do not merge into remote branches until I am almost ready to push. I keep up to date by doing frequent pull’s on remote branches and then rebasing my work forward to the new (remote) branch HEAD.

  • Guy
    Reply
    Posted at 10:43 am, June 10, 2011

    I still have one thing that bothers me about Git.
    Continuous integration – once developers start forking/branching it encourage them to push to the main branch very late in the process which means their new code is not continuously integrated and tested.
    In our team we encourage developers to commit their changes twice a day and make sure the Continuous integration and Automatic tests will give them full feedback in less than a hour.

  • icebrain
    Reply
    Posted at 1:27 pm, June 11, 2011

    @Guy: that’s a problem with your lack of integration between the VCS and the CI system. The CI system should test all the branches, not just the main one. Jenkins/Hudson does this, for example

    Also see https://github.com/blog/471-continuous-integration-spring-cleaning

  • Posted at 2:27 pm, June 11, 2011

    Guy,

    Mulitple branches can still be tested automatically. See my article at InfoQ at http://www.InfoQ.com/articles/Gerrit-jenkins-hudson – in particular, follow the first couple of links to the vimeo screencasts of how you can have automated build and test across multiple branches.

  • Bob
    Reply
    Posted at 6:20 pm, June 11, 2011

    How does a commit get loose?

Post a Comment

Comment
Name
Email
Website