HOW-TO import and export to and from Git and CVS

From PKP Wiki
Jump to: navigation, search

While we are still using both CVS and Git, we will be importing from CVS and exporting out to CVS. Fortunately, Git has commands built in for this purpose and with a little finesse, we can use this process cleanly. A longer description of each of these commands and a few extra tips can be found at this StackOverflow answer.

Importing from CVS into Git

Fortunately, we can all share one CVS import. The following commands are set up to run on a server (currently, and are being pushed to the "official" PKP Github account. This means that on your local machine, you only need to follow this how-to: HOW-TO check out PKP applications from git and do:

$ git pull official master

To setup a new Git repository imported from CVS, make sure you have a $CVSROOT parameter initialized in your session, and run the following command:

$ git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k cvs_module_to_checkout

Note: cvsimport uses the cvs command. If you do not have cvs installed, the import will not be successful.

When you encounter problems with the initial import

The initial import of all the applications except for OJS worked just fine following the instructions below. However, if cvsps gives an error, it is not very clear what should be done. Separating the cvsps command and the git cvsimport seems to do the trick.

cvsps -x --norc -u -A ojs2 > ~/cvsps.out
mkdir ojs
cd ojs
# the ojs2 at the end is the CVS module name
git-cvsimport -o HEAD -v -k -P ~/cvsps.out ojs2

To simplify subsequent commands

You can configure the following:

$ git config cvsimport.module cvs_module_to_checkout
$ git config cvsimport.r cvs
$ git config cvsimport.d $CVSROOT

Once you run those config commands, keeping the master branch up to date can simply be done by:

$ git cvsimport -k

note: The use of -k is current in question, as this might conflict with the instructions in HOW-TO use git and CVS in parallel.


The nice thing about our setup is that it allows everyone to share one cvsimport instance (the one that updates the official GitHub account), but we can do our own CVS export commits. We could export all of the micro-commits in GitHub to CVS, but I think it will be easier if we just merge a topic branch into the master and export only the merge commit. This way we only run the cvsexportcommit command on the one merge commit.

Assuming you have a topic branch with the name "experiment" that you want to commit to CVS, you can do the following

$ git checkout master
# on master
$ git pull official master
# makes sure the master matches the latest CVS to avoid conflicts
# this is the equivalent of doing cvs update before you do a commit
$ git merge --no-ff --log -m "#bugumber# commit message" experiment
$ git cvsexportcommit -w /path/to/cvs/checkout -u -p -k -c ORIG_HEAD HEAD

Note: cvsexportcommit does not work on fast-forward commits, so the --no-ff is important
Note 2: that you need a working CVS checkout somewhere in your file system at /path/to/cvs/checkout above.
Note 3: Unless you have SSH keys set up, the above command might ask you for your CVS password several times.

If you're making a change in one of the application repositories and there are corresponding changes in the pkp library, you will receive a conflict because CVS doesn't know anything about the lib/pkp folder and its not a regular file that can be added with cvs add. To avoid this problem, we have to make sure that the commits that go you push with cvsexportcommit DO NOT have a change to lib/pkp.

more coming on how to avoid this

Once you do this, you can wait a while until the change propages across. The cvsimport command is set to run on the hour, every hour. So a few minutes after the hour, your change in CVS should exist in the official PKP github repository. However, if you commit within 10 minutes of the hour, your change will only make it across an hour later because cvsimport ignores commits within the last 10 minutes by default to avoid importing a half-finished commit.

After the change comes across, you can simply do:

# on Master branch
$ git pull official master

This creates yet another commit in your Git history. The history becomes a little messy for the person doing the commit, because you have a merge commit, the cvs import commit, the cvs import merge, and the update from the official commit. You can, if you really want, reset your master to before you merged in your experiment branch with a git reset --hard and then pull from the official. However, this is purely for esthetics and makes no functional difference.