#!/usr/bin/perl # This script allows you to push commits out of a local git repository into an # associated cvs repository. Commits are not pulled from cvs in any way, so it # is assumed that someone is taking the cvs commits and turning them into git # updates somewhere else, and that this mirrored git repository is what you've # cloned for your local git copy. In order for the git-cvs-push script to # work, there must be a directory named .git/cvs in your repo, and it must have # a writable cvs checkout in it. After a commit, do a "git checkout --rebase" # to grab the mirrored version of your cvs commit. use strict; use warnings; my $git_dir = shift; die "Usage: cvs-push-git GIT_DIR [FILES]" unless defined $git_dir && -d "$git_dir/.git"; my $cvs_repo = "$git_dir/.git/cvs"; die "No cvs dir found in $git_dir/.git" unless -d $cvs_repo; my $commit_symlink = "$cvs_repo/.commit"; my $origin_commit; $_ = `git log -1 origin`; if (/^commit (\S+)/) { $origin_commit = $1; } else { die "Unable to parse origin commit from git log output.\n"; } unless (@ARGV) { my $prev_commit = readlink $commit_symlink; $prev_commit = '' unless defined $prev_commit; chomp(my $user = `git config user.name`); die "Git user is not set.\n" unless $user =~ /\S/; my $commit; open PIPE, '-|', qw( git log -30 ) or die $!; while () { if (/^commit (\S+)/) { $commit = $1; last if $commit eq $prev_commit || $commit eq $origin_commit; } elsif (/^Author:/) { last unless /\Q$user\E/o; unshift @ARGV, $commit; } } close PIPE; } die "Nothing to push.\n" unless @ARGV; foreach (@ARGV) { unlink $commit_symlink; symlink $_, $commit_symlink; print '=' x 20, " $_ ", '=' x 20, "\n"; system qw( git cvsexportcommit -c -u -p -w ), $cvs_repo, $_ and exit 1; }