Skip to content

Commit d775734

Browse files
dschogitster
authored andcommitted
cvsexportcommit: introduce -W for shared working trees (between Git and 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>
1 parent 57e0e3e commit d775734

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

Documentation/git-cvsexportcommit.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ git-cvsexportcommit - Export a single commit to a CVS checkout
88

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

1313

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

70+
-W::
71+
Tell cvsexportcommit that the current working directory is not only
72+
a Git checkout, but also the CVS checkout. Therefore, Git will
73+
reset the working directory to the parent commit before proceeding.
74+
7075
-v::
7176
Verbose.
7277

git-cvsexportcommit.perl

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
use File::Basename qw(basename dirname);
88
use File::Spec;
99

10-
our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w);
10+
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);
1111

12-
getopts('uhPpvcfam:d:w:');
12+
getopts('uhPpvcfam:d:w:W');
1313

1414
$opt_h && usage();
1515

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

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

30+
if ($opt_w) {
2931
if (! -d $opt_w."/CVS" ) {
3032
die "$opt_w is not a CVS checkout";
3133
}
@@ -116,6 +118,15 @@
116118
}
117119
}
118120

121+
my $go_back_to = 0;
122+
123+
if ($opt_W) {
124+
$opt_v && print "Resetting to $parent\n";
125+
$go_back_to = `git symbolic-ref HEAD 2> /dev/null ||
126+
git rev-parse HEAD` || die "Could not determine current branch";
127+
system("git checkout -q $parent^0") && die "Could not check out $parent^0";
128+
}
129+
119130
$opt_v && print "Applying to CVS commit $commit from parent $parent\n";
120131

121132
# grab the commit message
@@ -260,7 +271,11 @@
260271
}
261272

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

265280
print "Patch applied successfully. Adding new files and directories to CVS\n";
266281
my $dirtypatch = 0;
@@ -313,7 +328,9 @@
313328
print "using a patch program. After applying the patch and resolving the\n";
314329
print "problems you may commit using:";
315330
print "\n cd \"$opt_w\"" if $opt_w;
316-
print "\n $cmd\n\n";
331+
print "\n $cmd\n";
332+
print "\n git checkout $go_back_to\n" if $go_back_to;
333+
print "\n";
317334
exit(1);
318335
}
319336

@@ -333,6 +350,14 @@
333350
# clean up
334351
unlink(".cvsexportcommit.diff");
335352

353+
if ($opt_W) {
354+
system("git checkout $go_back_to") && die "cannot move back to $go_back_to";
355+
if (!($go_back_to =~ /^[0-9a-fA-F]{40}$/)) {
356+
system("git symbolic-ref HEAD $go_back_to") &&
357+
die "cannot move back to $go_back_to";
358+
}
359+
}
360+
336361
# CVS version 1.11.x and 1.12.x sleeps the wrong way to ensure the timestamp
337362
# used by CVS and the one set by subsequence file modifications are different.
338363
# If they are not different CVS will not detect changes.

t/t9200-git-cvsexportcommit.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,21 @@ test_expect_success 'commit a file with leading spaces in the name' '
297297
298298
'
299299

300+
test_expect_success 'use the same checkout for Git and CVS' '
301+
302+
(mkdir shared &&
303+
cd shared &&
304+
unset GIT_DIR &&
305+
cvs co . &&
306+
git init &&
307+
git add " space" &&
308+
git commit -m "fake initial commit" &&
309+
echo Hello >> " space" &&
310+
git commit -m "Another change" " space" &&
311+
git cvsexportcommit -W -p -u -c HEAD &&
312+
grep Hello " space" &&
313+
git diff-files)
314+
315+
'
316+
300317
test_done

0 commit comments

Comments
 (0)