Skip to content

Commit

Permalink
cvsexportcommit: introduce -W for shared working trees (between Git a…
Browse files Browse the repository at this point in the history
…nd CVS)

If you have a CVS checkout, it is easy to import the CVS history by
calling "git cvsimport".  However, interacting with the CVS repository
using "git cvsexportcommit" was cumbersome, since that script assumes
separate working directories for Git and CVS.

Now, you can call cvsexportcommit with the -W option.  This will
automatically discover the GIT_DIR, and it will check out the parent
commit before exporting the commit.

The intended workflow is this:

$ CVSROOT=$URL cvs co module
$ cd module
$ git cvsimport
hack, hack, hack, making two commits, cleaning them up using rebase -i.
$ git cvsexportcommit -W -c -p -u HEAD^
$ git cvsexportcommit -W -c -p -u HEAD

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed May 15, 2008
1 parent 57e0e3e commit d775734
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
7 changes: 6 additions & 1 deletion Documentation/git-cvsexportcommit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ git-cvsexportcommit - Export a single commit to a CVS checkout

SYNOPSIS
--------
'git-cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-w cvsworkdir] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
'git-cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-w cvsworkdir] [-W] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID


DESCRIPTION
Expand Down Expand Up @@ -67,6 +67,11 @@ OPTIONS
option does not require GIT_DIR to be set before execution if the
current directory is within a git repository.

-W::
Tell cvsexportcommit that the current working directory is not only
a Git checkout, but also the CVS checkout. Therefore, Git will
reset the working directory to the parent commit before proceeding.

-v::
Verbose.

Expand Down
35 changes: 30 additions & 5 deletions git-cvsexportcommit.perl
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
use File::Basename qw(basename dirname);
use File::Spec;

our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w);
our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w, $opt_W);

getopts('uhPpvcfam:d:w:');
getopts('uhPpvcfam:d:w:W');

$opt_h && usage();

die "Need at least one commit identifier!" unless @ARGV;

if ($opt_w) {
if ($opt_w || $opt_W) {
# Remember where GIT_DIR is before changing to CVS checkout
unless ($ENV{GIT_DIR}) {
# No GIT_DIR set. Figure it out for ourselves
Expand All @@ -25,7 +25,9 @@
}
# Make sure GIT_DIR is absolute
$ENV{GIT_DIR} = File::Spec->rel2abs($ENV{GIT_DIR});
}

if ($opt_w) {
if (! -d $opt_w."/CVS" ) {
die "$opt_w is not a CVS checkout";
}
Expand Down Expand Up @@ -116,6 +118,15 @@
}
}

my $go_back_to = 0;

if ($opt_W) {
$opt_v && print "Resetting to $parent\n";
$go_back_to = `git symbolic-ref HEAD 2> /dev/null ||
git rev-parse HEAD` || die "Could not determine current branch";
system("git checkout -q $parent^0") && die "Could not check out $parent^0";
}

$opt_v && print "Applying to CVS commit $commit from parent $parent\n";

# grab the commit message
Expand Down Expand Up @@ -260,7 +271,11 @@
}

print "Applying\n";
`GIT_DIR= git-apply $context --summary --numstat --apply <.cvsexportcommit.diff` || die "cannot patch";
if ($opt_W) {
system("git checkout -q $commit^0") && die "cannot patch";
} else {
`GIT_DIR= git-apply $context --summary --numstat --apply <.cvsexportcommit.diff` || die "cannot patch";
}

print "Patch applied successfully. Adding new files and directories to CVS\n";
my $dirtypatch = 0;
Expand Down Expand Up @@ -313,7 +328,9 @@
print "using a patch program. After applying the patch and resolving the\n";
print "problems you may commit using:";
print "\n cd \"$opt_w\"" if $opt_w;
print "\n $cmd\n\n";
print "\n $cmd\n";
print "\n git checkout $go_back_to\n" if $go_back_to;
print "\n";
exit(1);
}

Expand All @@ -333,6 +350,14 @@
# clean up
unlink(".cvsexportcommit.diff");

if ($opt_W) {
system("git checkout $go_back_to") && die "cannot move back to $go_back_to";
if (!($go_back_to =~ /^[0-9a-fA-F]{40}$/)) {
system("git symbolic-ref HEAD $go_back_to") &&
die "cannot move back to $go_back_to";
}
}

# CVS version 1.11.x and 1.12.x sleeps the wrong way to ensure the timestamp
# used by CVS and the one set by subsequence file modifications are different.
# If they are not different CVS will not detect changes.
Expand Down
17 changes: 17 additions & 0 deletions t/t9200-git-cvsexportcommit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,21 @@ test_expect_success 'commit a file with leading spaces in the name' '
'

test_expect_success 'use the same checkout for Git and CVS' '
(mkdir shared &&
cd shared &&
unset GIT_DIR &&
cvs co . &&
git init &&
git add " space" &&
git commit -m "fake initial commit" &&
echo Hello >> " space" &&
git commit -m "Another change" " space" &&
git cvsexportcommit -W -p -u -c HEAD &&
grep Hello " space" &&
git diff-files)
'

test_done

0 comments on commit d775734

Please sign in to comment.