Skip to content

Instantly share code, notes, and snippets.

@apk
Last active December 20, 2015 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apk/6044942 to your computer and use it in GitHub Desktop.
Save apk/6044942 to your computer and use it in GitHub Desktop.
Transfer commits from git into cvs, for use in what is a CVS checkout and a git repo at the same time.

git-to-cvs.sh is part of the workflow for syncing a CVS branch with a git branch (and it's the only part of this that is actually tested, the rest has just been written down quickly). You do check out your CVS tree (with -kk), go into its root directory, and run git-init.sh (untested as of yet). The local git repo has the branch cvs checked out, and that is the one we keep in sync with CVS (and the branch we checked out there).

Update from cvs is

cvs -q update -dP
git add --all .
git commit -m 'update from cvs'

(It does not try to recreate the individual commits of the CVS side into git; we're just interested in bringing over the current tree state in this direction.)

In the other direction you need to push into the local master branch the commits you want to put into CVS. They must be rebased onto the current state of cvs (so that cvs..master is a fast-forward); then you just run git-to-cvs.sh until it claims no more work to be done. (If the repo isn't clean afterwards, then the cvs update has washed ashore some updates from CVS, and you first need to put them into git, and rebase master again.)

The rebasing of master should be done in a clone where you also presumably do your work; this git repo plus CVS sandbox better stays clean. (Note that when you clone from this transfer repo, unfortunately cvs will be the checked-out branch; you'd need to change to master.)

The script also has a protection ('not for cvs') against putting commits into CVS that are marked such.

It will break if git brings in new directories.

#!/bin/sh
# (UNTESTED)
if test -d .git -o ! -d CVS; then
echo "WAT!"
exit 1
fi
git init
echo CVS >.git/info/exclude
git add .
git commit -m initial
git checkout -b cvs
# Commit diffs from cvs..master into cvs, one at a time.
# No file additions/removals.
set -x
git log --format=oneline cvs..master | tail -1 | (read commit comment
if test X"$commit" != X; then
echo "[commit:'$comment']"
oldcomm="`git log --format=oneline -n1 | awk '{print $1}'`"
if expr X"$comment" : '.*not *for *cvs.*'; then
set +x
echo "Hold the phone: [$comment]"
echo "You don't want to commit this to CVS."
exit
fi
: '********************'
git merge $commit || exit
: '********************' "$comment"
git diff --name-only --diff-filter=D $oldcomm..$commit | while read fn; do cvs rm $fn; done
git diff --name-only --diff-filter=A $oldcomm..$commit | while read fn; do cvs add $fn; done
cvs -q commit -m "$comment" || exit
cvs -q update -kk
git update-index -q --refresh
git status; else echo all done; fi)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment