Jounio. Thanks for the feedback. It is your fedora patch 2.5.4 that doesn't work. It doesn't seem to handle spaces in filenames in any way. Not much I can do about that. Btw, 2.5.4 is nine years old, but strangely that's the one that's around everywhere on source mirrors, but most (=the few ones I checked) Linux distros have 2.5.9 (except RH). -- robin
Make cvsexportcommit work with filenames containing spaces. From: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> Binary files are except to this so far. Signed-off-by: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> --- git-cvsexportcommit.perl | 27 +++++++++++++++++--- t/t9200-git-cvsexportcommit.sh | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 99b3dc3..ecded35 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -5,6 +5,7 @@ # - cannot add or remove binary files # - does not propagate permissions # - tells "ready for commit" even when things could not be completed # (eg addition of a binary file) +# - Fedora/RHEL uses patch 2.5.4 which doesn't handles spaces in file names use strict; use Getopt::Std; @@ -121,7 +122,14 @@ #print @files; $? && die "Error in git-diff-tree"; foreach my $f (@files) { chomp $f; - my @fields = split(m!\s+!, $f); + $f =~ m/^(\S+) (\S+) (\S+) (\S+) (\S+) (.*)/; + my @fields = (); + $fields[++$#fields] = $1; + $fields[++$#fields] = $2; + $fields[++$#fields] = $3; + $fields[++$#fields] = $4; + $fields[++$#fields] = $5; + $fields[++$#fields] = $6; if ($fields[4] eq 'A') { my $path = $fields[5]; push @afiles, $path; @@ -217,7 +225,7 @@ foreach my $f (@bfiles) { } # replace with the new file - `git-cat-file blob $blob > $f`; + `git-cat-file blob $blob > "$f"`; # TODO: something smart with file modes @@ -231,7 +239,20 @@ ## apply non-binary changes my $fuzz = $opt_p ? 0 : 2; print "Patching non-binary files\n"; -print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`; + +my $saveslash = $/; +undef $/; + +open DIFF, "git-diff-tree -p $parent -p $commit|" || die "Cannot diff"; +open PATCH, "|patch -p1 -F $fuzz" || die "Cannot patch"; +my $delta = <DIFF>; +close DIFF || die "Could not diff"; +unless (defined $ENV{'GIT_CVSEXPORTCOMMIT_NO_SPACES'}) { + $delta =~ s/\n(index [^\n]*)\n(--- [^\n]*)\n(\+\+\+ [^\n]*)\n(@@[^\n]*@@)\n/$1\n$2\t\n$3\t\n$4\n/sg +} +print PATCH $delta; +close PATCH || die "Could not patch"; +$/ = $saveslash; my $dirtypatch = 0; if (($? >> 8) == 2) { diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh new file mode 100755 index 0000000..548e329 --- /dev/null +++ b/t/t9200-git-cvsexportcommit.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +test_description='CVS export comit. + +These tests are ad-hoc ones made to test +some changes, not a complete test.' + +. ./test-lib.sh + +export CVSROOT=$(pwd)/cvsroot +export CVSWORK=$(pwd)/cvswork +rm -rf "$CVSROOT" "$CVSWORK" +mkdir "$CVSROOT" && +cvs init && +cvs -Q co -d "$CVSWORK" . && +export GIT_DIR=$(pwd)/.git && +echo >empty && +git add empty && +git commit -a -m "Initial" 2>/dev/null || +exit 1 + +test_expect_success \ + 'New file' \ + 'echo hello >newfile.txt && + git add newfile.txt && + git commit -a -m "Hello" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + test $(cat CVS/Entries|wc -l) = 2 + )' + +test_expect_success \ + 'New file with spaces in file name' \ + 'echo ok then >"with spaces.txt" && + git add "with spaces.txt" && \ + git commit -a -m "With spaces" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git-cvsexportcommit -c $id && + test $(cat CVS/Entries|wc -l) = 3 + )' + +test_expect_success \ + 'Update file with spaces in file name' \ + 'echo Ok then >>"with spaces.txt" && + git add "with spaces.txt" && + git commit -a -m "Update with spaces" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git-cvsexportcommit -c $id && + test $(cat CVS/Entries|wc -l) = 3 + )' + +test_done
Make cvsexportcommit remove files. From: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> Signed-off-by: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> --- git-cvsexportcommit.perl | 2 +- t/t9200-git-cvsexportcommit.sh | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletions(-) diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index ecded35..4fb55a6 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -143,7 +143,7 @@ foreach my $f (@files) { if ($fields[4] eq 'M') { push @mfiles, $fields[5]; } - if ($fields[4] eq 'R') { + if ($fields[4] eq 'D') { push @dfiles, $fields[5]; } } diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 548e329..6f28da6 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -52,4 +52,16 @@ test_expect_success \ test $(cat CVS/Entries|wc -l) = 3 )' +test_expect_success \ + 'Remove file with spaces in file name' \ + 'echo Ok then >"with spaces.txt" && + rm -v "with spaces.txt" && \ + git rm "with spaces.txt" && \ + git commit -a -m "Remove file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git-cvsexportcommit -v -c $id && + test $(cat CVS/Entries|wc -l) = 2 + )' + test_done