Published on

Using Git with CVS


Git has become my favorite DVCS and I use it anytime I can. That said, at work we use CVS and it's likely not going to change for a while. Even an upgrade to Subversion is probably out of the question. After a year of using Git elsewhere I've finally figured out how to incorporate Git into my CVS workflow.

I created a git repo inside of my CVS working copy and perform operations according to a defined workflow, interacting separately with git and CVS.

Workflow Rules

I think the major benefits of DVCS is that it gives you the freedom to adapt a different workflow and interesting enough that can also be one of it drawbacks. Therefore it is a good idea to lay down some ground rules for yourself that you can refer back to during a conflict.

  • Only master receives updates from CVS and rebased to branches
  • All work is done on a local feature branch and from there committed to CVS

Initialize Git repo on CVS working copy

$ cd cvs_working_copy
$ git init
$ git add .
$ git commit -m 'initial import'

I have the following in .gitignore since my Git repo will remain oblivious to CVS:


CVS to Git Workflow (and vice versa)

  • Once master receives an update from CVS (upstream) it is committed with a message of 'sync CVS'
    [master]$ cvs update
    M index.html
    M css/style.css

    [master]$ git status
    # On branch master
    # Changed but not updated:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #       modified:   index.html
    #       modified:   css/style.css
    # no changes added to commit (use "git add" and/or "git commit -a")

    [master]$ git commit -a -m 'sync CVS'
    [master 50a26ad] sync CVS
     2 files changed, 135 insertions(+), 19 deletions(-)
  • Switch to a feature branch and run git rebase master to pull in upstream changes, then reapply the commits on the branch.
    [master]$ git checkout feature_1
    [feature_1]$ git rebase master
  • When a portion of the feature is ready to be sent upstream, it is committed to the git feature branch, and from the feature branch committed to CVS
  • From that point it is merged from the feature branch back to master (pulling directly from CVS (upstream) would cause a conflict): git co master; git merge feature_branch
    [feature_1]$ git checkout master
    [master]$ git merge feature_1
    Updating a24ae94..50a26ad
    Fast forward
     index.html       |  135 +++++-
     css/style.css    |   19 +-
     2 files changed, 135 insertions(+), 19 deletions(-)