Skip to content

Commit 49c7e46

Browse files
committed
Merge branch 'nw/maint-cvsexportcommit'
* nw/maint-cvsexportcommit: git-cvsexportcommit can't commit files which have been removed from CVS
2 parents 1bbc820 + 54d5cc0 commit 49c7e46

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

git-cvsexportcommit.perl

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,39 +225,60 @@
225225
foreach my $name (keys %todo) {
226226
my $basename = basename($name);
227227

228-
$basename = "no file " . $basename if (exists($added{$basename}));
228+
# CVS reports files that don't exist in the current revision as
229+
# "no file $basename" in its "status" output, so we should
230+
# anticipate that. Totally unknown files will have a status
231+
# "Unknown". However, if they exist in the Attic, their status
232+
# will be "Up-to-date" (this means they were added once but have
233+
# been removed).
234+
$basename = "no file $basename" if $added{$basename};
235+
229236
$basename =~ s/^\s+//;
230237
$basename =~ s/\s+$//;
231238

232239
if (!exists($fullname{$basename})) {
233240
$fullname{$basename} = $name;
234241
push (@canstatusfiles2, $name);
235242
delete($todo{$name});
236-
}
243+
}
237244
}
238245
my @cvsoutput;
239246
@cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles2);
240247
foreach my $l (@cvsoutput) {
241-
chomp $l;
242-
if ($l =~ /^File:\s+(.*\S)\s+Status: (.*)$/) {
243-
if (!exists($fullname{$1})) {
244-
print STDERR "Huh? Status reported for unexpected file '$1'\n";
245-
} else {
246-
$cvsstat{$fullname{$1}} = $2;
247-
}
248-
}
248+
chomp $l;
249+
next unless
250+
my ($file, $status) = $l =~ /^File:\s+(.*\S)\s+Status: (.*)$/;
251+
252+
my $fullname = $fullname{$file};
253+
print STDERR "Huh? Status '$status' reported for unexpected file '$file'\n"
254+
unless defined $fullname;
255+
256+
# This response means the file does not exist except in
257+
# CVS's attic, so set the status accordingly
258+
$status = "In-attic"
259+
if $file =~ /^no file /
260+
&& $status eq 'Up-to-date';
261+
262+
$cvsstat{$fullname{$file}} = $status;
249263
}
250264
}
251265
}
252266

253-
# ... validate new files,
267+
# ... Validate that new files have the correct status
254268
foreach my $f (@afiles) {
255-
if (defined ($cvsstat{$f}) and $cvsstat{$f} ne "Unknown") {
256-
$dirty = 1;
269+
next unless defined(my $stat = $cvsstat{$f});
270+
271+
# This means the file has never been seen before
272+
next if $stat eq 'Unknown';
273+
274+
# This means the file has been seen before but was removed
275+
next if $stat eq 'In-attic';
276+
277+
$dirty = 1;
257278
warn "File $f is already known in your CVS checkout -- perhaps it has been added by another user. Or this may indicate that it exists on a different branch. If this is the case, use -f to force the merge.\n";
258279
warn "Status was: $cvsstat{$f}\n";
259-
}
260280
}
281+
261282
# ... validate known files.
262283
foreach my $f (@files) {
263284
next if grep { $_ eq $f } @afiles;

t/t9200-git-cvsexportcommit.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,22 @@ test_expect_success 'use the same checkout for Git and CVS' '
317317
318318
'
319319

320+
test_expect_success 're-commit a removed filename which remains in CVS attic' '
321+
322+
(cd "$CVSWORK" &&
323+
echo >attic_gremlin &&
324+
cvs -Q add attic_gremlin &&
325+
cvs -Q ci -m "added attic_gremlin" &&
326+
rm attic_gremlin &&
327+
cvs -Q rm attic_gremlin &&
328+
cvs -Q ci -m "removed attic_gremlin") &&
329+
330+
echo > attic_gremlin &&
331+
git add attic_gremlin &&
332+
git commit -m "Added attic_gremlin" &&
333+
git cvsexportcommit -w "$CVSWORK" -c HEAD &&
334+
(cd "$CVSWORK"; cvs -Q update -d) &&
335+
test -f "$CVSWORK/attic_gremlin"
336+
'
337+
320338
test_done

0 commit comments

Comments
 (0)