@matheusbsbs / matheus-bagliano / commits / d775734c40
Fork 0

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>

Johannes Schindelin committed May 14, 2008 at 15:29 UTC d775734c40afed216160437c59a45c93bdf28689
3 files changed +53 -6
Documentation/git-cvsexportcommit.txt
+6 -1
@@ -8,7 +8,7 @@ git-cvsexportcommit - Export a single commit to a CVS checkout
8
9 SYNOPSIS
10 --------
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
12
13
14 DESCRIPTION
@@ -67,6 +67,11 @@ OPTIONS
67 option does not require GIT_DIR to be set before execution if the
68 current directory is within a git repository.
69
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 +
75 -v::
76 Verbose.
77
git-cvsexportcommit.perl
+30 -5
@@ -7,15 +7,15 @@ use Data::Dumper;
7 use File::Basename qw(basename dirname);
8 use File::Spec;
9
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);
11
12 -getopts('uhPpvcfam:d:w:');
12 +getopts('uhPpvcfam:d:w:W');
13
14 $opt_h && usage();
15
16 die "Need at least one commit identifier!" unless @ARGV;
17
18 -if ($opt_w) {
18 +if ($opt_w || $opt_W) {
19 # Remember where GIT_DIR is before changing to CVS checkout
20 unless ($ENV{GIT_DIR}) {
21 # No GIT_DIR set. Figure it out for ourselves
@@ -25,7 +25,9 @@ if ($opt_w) {
25 }
26 # Make sure GIT_DIR is absolute
27 $ENV{GIT_DIR} = File::Spec->rel2abs($ENV{GIT_DIR});
28 +}
29
30 +if ($opt_w) {
31 if (! -d $opt_w."/CVS" ) {
32 die "$opt_w is not a CVS checkout";
33 }
@@ -116,6 +118,15 @@ if ($parent) {
118 }
119 }
120
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 +
130 $opt_v && print "Applying to CVS commit $commit from parent $parent\n";
131
132 # grab the commit message
@@ -260,7 +271,11 @@ if ($dirty) {
271 }
272
273 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 +}
279
280 print "Patch applied successfully. Adding new files and directories to CVS\n";
281 my $dirtypatch = 0;
@@ -313,7 +328,9 @@ if ($dirtypatch) {
328 print "using a patch program. After applying the patch and resolving the\n";
329 print "problems you may commit using:";
330 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";
334 exit(1);
335 }
336
@@ -333,6 +350,14 @@ if ($opt_c) {
350 # clean up
351 unlink(".cvsexportcommit.diff");
352
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 +
361 # CVS version 1.11.x and 1.12.x sleeps the wrong way to ensure the timestamp
362 # used by CVS and the one set by subsequence file modifications are different.
363 # If they are not different CVS will not detect changes.
t/t9200-git-cvsexportcommit.sh
+17
@@ -297,4 +297,21 @@ test_expect_success 'commit a file with leading spaces in the name' '
297
298 '
299
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 +
317 test_done