@matheusbsbs / matheus-bagliano / commits / 54d5cc0e12
Fork 0

git-cvsexportcommit can't commit files which have been removed from CVS

If a file X is removed from CVS, it goes into the Attic directory, and CVS reports it as 'no file X' but with status 'Up-to-date'. cvsexportcommit misinterprets this as an existing file and tries to commit a file with the same name. Correctly identify these files, so that new files with the same name can be committed. Add a test to t9200-git-cvsexportcommit.sh, which tests that we can re-commit a removed filename which remains in CVS's attic. This adds a file 'attic_gremlin' in CVS, then "removes" it, then tries to commit a file with the same name from git. Signed-off-by: Nick Woolley <git.wu-lee@noodlefactory.co.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nick Woolley committed May 29, 2009 at 00:23 UTC 54d5cc0e126ed4b6cc4b186efd9faf7b93df570f
2 files changed +53 -14
git-cvsexportcommit.perl
+35 -14
@@ -225,7 +225,14 @@ if (@canstatusfiles) {
225 foreach my $name (keys %todo) {
226 my $basename = basename($name);
227
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 +
236 $basename =~ s/^\s+//;
237 $basename =~ s/\s+$//;
238
@@ -233,31 +240,45 @@ if (@canstatusfiles) {
240 $fullname{$basename} = $name;
241 push (@canstatusfiles2, $name);
242 delete($todo{$name});
236 - }
243 + }
244 }
245 my @cvsoutput;
246 @cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles2);
247 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;
263 }
264 }
265 }
266
253 -# ... validate new files,
267 +# ... Validate that new files have the correct status
268 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;
278 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";
279 warn "Status was: $cvsstat{$f}\n";
259 - }
280 }
281 +
282 # ... validate known files.
283 foreach my $f (@files) {
284 next if grep { $_ eq $f } @afiles;
t/t9200-git-cvsexportcommit.sh
+18
@@ -317,4 +317,22 @@ test_expect_success 'use the same checkout for Git and CVS' '
317
318 '
319
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 +
338 test_done