Differences between revisions 2 and 3
Revision 2 as of 2015-07-04 06:32:55
Size: 5210
Editor: OsamuAoki
Comment:
Revision 3 as of 2015-07-04 14:20:21
Size: 5210
Editor: OsamuAoki
Comment:
Deletions are marked like this. Additions are marked like this.
Line 49: Line 49:
  $ git reset --hard cvs && git -dfxi clean   $ git reset --hard cvs && git clean -dfxi

Work with the CVS repository using Git

This is a short memo on how to work with the CVS repository using Git.

Requirements

Basic understanding of followings are prerequisites:

Work with the CVS repository using git

You may wish to use the convenience of your local git repository when you update an upstream source tree maintained in the CVS system.

Of course, you can set up the full repository history of CVS in the local repository and track the CVS HEAD in your local git repository as the remote branch, e.g., as cvs/master. In short, this is slow and cumbersome. I will explain this later in "Approach 2".

For simplicity, I use following variables.

CVSROOT=${USER}@${HOST}:${PATH_TO_CVSREPO}
CWD=`pwd`

TIP: You may set up command alias to ease typing :-)

Approach 1: only future changes

Let's worry only future changes. This can be realized as:

make simple CVS checkout and make it a git repository (1st run only)

  $ cvs -d ${CVSROOT} checkout -P -kk $MODULE
  $ cd $MODULE
  $ git init; git add .; git commit -m "initial import"
  $ git branch cvs

update the git cvs branch to the latest CVS (non-1st run only)

  $ git checkout cvs
  $ git reset --hard cvs && git clean -dfxi
  $ cvs update -PdA -kk
  $ git add . ; git commit -m "new cvs HEAD"
  $ git checkout master
  $ git reset --hard master && git clean -dfxi

start hacking the source on master

  $ vim foo.txt
  $ git commit -a -m "commit for foo"
  $ vim bar.txt
  $ git commit -a -m "commit for bar"
  ... (test code etc.)
  $ vim baz.txt
  $ git commit -a -m "commit for baz"

update to the latest CVS (to be sure)

  $ git checkout cvs
  $ git reset --hard cvs && git clean -dfxi
  $ cvs update -PdA -kk
  $ git add . ; git commit -m "new cvs HEAD"
  $ git checkout master
  $ git reset --hard master && git clean -dfxi 

rebase to the latest CVS and organize commit candidates

  $ git rebase -i cvs
  ...

commit as a series of commits

  $ git cherry cvs master | sed -n 's/^+ //p' | xargs -l1 \
    git cvsexportcommit -ckpvW

NOTE: The local git repository contains CVS/ directories in it.

Approach 2: synchronized full history of changes

This approach requires to set up 3 directories to be efficient with the CVS data transaction. Let's arrange them as follows under ${CWD}/:

  • ${CWD}/gitdir/
    • a local git repository managed by git-cvsimport without CVS/ directories
  • ${CWD}/cvsdir/
    • a local checkout from the CVS repository with CVS/ directories
  • ${CWD}/rsyncdir/
    • a full local copy of the CVS repository

Overview of the workflow is the following.

           1)            2)                           3)
Remote CVS -> Local CVS -+-> git-cvsimport (cvsps) -> hack ... +
        ^                |                                     |
        |                +-> cvs checkout -------------------> +
        |                                                      |
        +<------------------ git-cvsexportcommit <-------------+
                             4)

1) Create a local copy of the CVS repository

 $ rsync -avS --delete --delay-updates --rsh=ssh ${CVSROOT}/. rsyncdir

You should see files under the following directories:

  • ${CWD}/rsyncdir/CVSROOT
  • ${CWD}/rsyncdir/${MODULE}

2) Create a local git repository and a local checkout from the CVS repository

 $ git cvsimport -akmRv -d ${CWD}/rsyncdir -C gitdir -r cvs $MODULE
 $ cvs -d ${CWD}/rsyncdir checkout -P -kk -d cvsdir $MODULE

The git-cvsimport command imports the full history of changes to the local git repository and allows to synchronize it continuously with the upstream CVS. The upstream CVS repository data without CVS/ directories is tracked on the remote branch called cvs/master if "-r cvs" option is used.

3) Hack code while using git

 $ cd ${CWD}/gitdir
  ... hack on master branch starting at remote branch cvs/master
 $ cd ${CWD}
 $ rsync -avS --delete --delay-updates --rsh=ssh ${CVSROOT}/. rsyncdir
 $ cd cvsdir
 $ cvs -d ${CWD}/rsyncdir update -PdA -kk $MODULE
 $ cd ${CWD}/gitdir
 $ git rebase -i cvs/master
  ... resolve conflicts and clean up history

4) Merge pending patches into CVS automatically

 $ git cherry cvs/master master | sed -n 's/^+ //p' | xargs -l1 \
   git cvsexportcommit -ckpuv -d $CVSROOT -w ${CWD}/cvsdir/
 $ rm -rf ${CWD}/cvsdir

The "-d $CVSROOT" is required since CVS is used in an asymmetric fashion.

See also: