Maintain git and CVS synchronized
The idea of using .git and CVS in parallel is that both version control systems use files in sub-directories to keep track of versioning state. And both have a mechanism to ignore directories that should not be tracked. So we simply use both tools in the same folder letting each of them ignore the other.
We also benefit from the fact that git doesn't mind where a certain file comes from historically (i.e. checked out from CVS or from git). As long as it has the correct SHA1 hash git will recognize it as "equal" to the objects in its object database. This makes it possible to make a change, check it into CVS, wait until the change gets pushed into the git repository, fetch it from there and not get a merge conflict when the file comes in through the back door into git. As soon as git receives a change sent out by CVS the updated files will simply no longer be marked 'changed' in the workspace.
That way we can use git for development and communication between developers and for local day-to-day version control. Developers can also maintain several development topics they work on in parallel in distinct branches and switch from one to the other whenever they like. In short: all the nice things that git enables.
We'll not check anything into CVS during this stage. Only when we have put together a stable change set we'll check out the corresponding branch in git, run a CVS update so that CVS can identify the changes, create a patch to be saved to the corresponding bug-entry in Bugzilla and commit the changes as a single well-defined change set into CVS to make it available to outside users or community developers.
This way we get the best out of both worlds:
- We get full git flexibility at development time removing the overhead of sending around large patch sets and allowing granular control and transparency of development advances throughout the team even when it takes weeks or months until a stable change-set is ready for publication on CVS.
- CVS OTOH will remain there as a well-known, well-established, tool-rich source repository, accessible to less tech-savvy outside users that only want to track stable changes.
Prerequisites and Assumptions
- I assume that you already have a PKP-application (say OMP) checked out from CVS in a folder. I'll reference to this directory by '/omp'. Replace 'omp' with the application you want to check out wherever it occurs.
- git knows nothing about keyword expansion. Please make sure that you update your whole source tree from CVS with the -kk option to avoid differences between git and CVS checkouts. The -kk option is sticky so this has only to be done once for every source tree.
- I also assume that you've checked out the pkp library in the folder 'lib/pkp' and that you have it under CVS version control.
- You should have read the git sub-module tutorial. I assume that you've understood git and git submodule basics.
- You should have forked the official PKP repositories on github as described in HOW-TO check out PKP applications from git. Just do the remote forking, do nothing locally. What we describe here is an alternative approach.
- Please replace 'youruser' with your github user wherever it occurs.
- I am using vim as an editor. Please feel free to use whatever editor you like instead.
Initialize the git repository
We create an empty git repository within the existing application folder that is already under CVS control:
cd /omp git init
Now configure git to ignore CVS directories. Edit '.git/info/exclude' and add the following lines:
# exclude CVS files CVS/
Fetching git objects
Now we have to retrieve git objects from the remote repository to make them available locally. Execute the following commands to establish the connection to your personal git repository, create a remote tracking branch and fetch git objects:
git remote add origin email@example.com:youruser/omp.git git fetch origin
Next we do the same for the official master project:
git remote add cvs git://github.com/pkp/omp.git git fetch cvs
Checking out the master branch
I assume that you don't have personal branches in your remote repository yet. But if you have you can check out any other remote branch of course. It doesn't have to be 'origin/master':
git checkout origin/master git checkout -b master
Creating and updating the pkp-lib submodule
Next we'll have to create the lib/pkp submodule and fetch it's contents. Please do *not* issue 'git submodule update' as this will make your beloved CVS folders disappear. We'll have to create the submodule repository manually:
git submodule init vim .git/config # change your submodules url to point to your personal pkp-lib remote repository # If you don't know what I mean then you should go back to the submodule tutorial cd lib/pkp git init
We'll ignore CVS directories in the submodule as well:
vim .git/info/exclude # add the same CVS/ line you added before
As we're creating the submodule manually we'll now have to add remote repositories and check out the initial branch as we did for the application repository:
git remote add origin firstname.lastname@example.org:youruser/pkp-lib.git git fetch origin git remote add cvs git://github.com/pkp/pkp-lib.git git fetch cvs git checkout origin/master git checkout -b master
Now you can check whether everything worked out:
git status cd ../.. git status
This should produce the following output for both the submodule and the main repository (if you had no local changes in your CVS which is perfectly possible and allowed but will produce different output of course):
# On branch master nothing to commit (working directory clean)
Configuring CVS to ignore git
The last step we have to take is to add '.git' to the '.cvsignore' files in the main application directory as well as in the pkp directory. As you are a longtime CVS user I assume that you know how to do that.
Now you can use git and CVS in parallel as described in the section "Background" above. Have fun.