From fe142b3a4577a6692a39e2386ed649664ad8bd20 Mon Sep 17 00:00:00 2001 From: Robin Rosenberg Date: Sun, 12 Nov 2006 16:29:42 +0100 Subject: [PATCH] Rework cvsexportcommit to handle binary files for all cases. Also adds test cases for adding removing and deleting binary and text files plus two tests for the checks on binary files. Signed-off-by: Robin Rosenberg Signed-off-by: Junio C Hamano --- git-cvsexportcommit.perl | 70 +++++++++++----- t/t9200-git-cvsexportcommit.sh | 145 +++++++++++++++++++++++++++++++++ t/test9200a.png | Bin 0 -> 5660 bytes t/test9200b.png | Bin 0 -> 275 bytes 4 files changed, 195 insertions(+), 20 deletions(-) create mode 100755 t/t9200-git-cvsexportcommit.sh create mode 100644 t/test9200a.png create mode 100644 t/test9200b.png diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 5e23851f8..7bac16e94 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -1,10 +1,10 @@ #!/usr/bin/perl -w # Known limitations: -# - 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) +# (not sure this is true anymore, more testing is needed) +# - does not handle whitespace in pathnames at all. use strict; use Getopt::Std; @@ -68,9 +68,9 @@ foreach my $line (@commit) { if ($stage eq 'headers') { if ($line =~ m/^parent (\w{40})$/) { # found a parent push @parents, $1; - } elsif ($line =~ m/^author (.+) \d+ \+\d+$/) { + } elsif ($line =~ m/^author (.+) \d+ [-+]\d+$/) { $author = $1; - } elsif ($line =~ m/^committer (.+) \d+ \+\d+$/) { + } elsif ($line =~ m/^committer (.+) \d+ [-+]\d+$/) { $committer = $1; } } else { @@ -139,6 +139,17 @@ foreach my $f (@files) { push @dfiles, $fields[5]; } } +my (@binfiles, @abfiles, @dbfiles, @bfiles, @mbfiles); +@binfiles = grep m/^Binary files/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit); +map { chomp } @binfiles; +@abfiles = grep s/^Binary files \/dev\/null and b\/(.*) differ$/$1/, @binfiles; +@dbfiles = grep s/^Binary files a\/(.*) and \/dev\/null differ$/$1/, @binfiles; +@mbfiles = grep s/^Binary files a\/(.*) and b\/(.*) differ$/$1/, @binfiles; +push @bfiles, @abfiles; +push @bfiles, @dbfiles; +push @bfiles, @mbfiles; +push @mfiles, @mbfiles; + $opt_v && print "The commit affects:\n "; $opt_v && print join ("\n ", @afiles,@mfiles,@dfiles) . "\n\n"; undef @files; # don't need it anymore @@ -153,6 +164,10 @@ foreach my $d (@dirs) { } foreach my $f (@afiles) { # This should return only one value + if ($f =~ m,(.*)/[^/]*$,) { + my $p = $1; + next if (grep { $_ eq $p } @dirs); + } my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f)); if (@status > 1) { warn 'Strange! cvs status returned more than one line?'}; if (-d dirname $f and $status[0] !~ m/Status: Unknown$/ @@ -162,6 +177,7 @@ foreach my $f (@afiles) { warn "Status was: $status[0]\n"; } } + foreach my $f (@mfiles, @dfiles) { # TODO:we need to handle removed in cvs my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f)); @@ -200,24 +216,31 @@ foreach my $d (@dirs) { print "'Patching' binary files\n"; -my @bfiles = grep(m/^Binary/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit)); -@bfiles = map { chomp } @bfiles; foreach my $f (@bfiles) { # check that the file in cvs matches the "old" file # extract the file to $tmpdir and compare with cmp - my $tree = safe_pipe_capture('git-rev-parse', "$parent^{tree}"); - chomp $tree; - my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`; - chomp $blob; - `git-cat-file blob $blob > $tmpdir/blob`; - if (system('cmp', '-s', $f, "$tmpdir/blob")) { - warn "Binary file $f in CVS does not match parent.\n"; - $dirty = 1; - next; + if (not(grep { $_ eq $f } @afiles)) { + my $tree = safe_pipe_capture('git-rev-parse', "$parent^{tree}"); + chomp $tree; + my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`; + chomp $blob; + `git-cat-file blob $blob > $tmpdir/blob`; + if (system('cmp', '-s', $f, "$tmpdir/blob")) { + warn "Binary file $f in CVS does not match parent.\n"; + if (not $opt_f) { + $dirty = 1; + next; + } + } + } + if (not(grep { $_ eq $f } @dfiles)) { + my $tree = safe_pipe_capture('git-rev-parse', "$commit^{tree}"); + chomp $tree; + my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`; + chomp $blob; + # replace with the new file + `git-cat-file blob $blob > $f`; } - - # replace with the new file - `git-cat-file blob $blob > $f`; # TODO: something smart with file modes @@ -231,7 +254,10 @@ if ($dirty) { 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`; + +if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) != scalar(@bfiles)) { + print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`; +} my $dirtypatch = 0; if (($? >> 8) == 2) { @@ -242,7 +268,11 @@ if (($? >> 8) == 2) { } foreach my $f (@afiles) { - system('cvs', 'add', $f); + if (grep { $_ eq $f } @bfiles) { + system('cvs', 'add','-kb',$f); + } else { + system('cvs', 'add', $f); + } if ($?) { $dirty = 1; warn "Failed to cvs add $f -- you may need to do it manually"; diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh new file mode 100755 index 000000000..6e566d440 --- /dev/null +++ b/t/t9200-git-cvsexportcommit.sh @@ -0,0 +1,145 @@ +#!/bin/bash +# +# Copyright (c) Robin Rosenberg +# +test_description='CVS export comit. ' + +. ./test-lib.sh + +cvs >/dev/null 2>&1 +if test $? -ne 1 +then + test_expect_success 'skipping git-cvsexportcommit tests, cvs not found' : + test_done + exit +fi + +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' \ + 'mkdir A B C D E F && + echo hello1 >A/newfile1.txt && + echo hello2 >B/newfile2.txt && + cp ../test9200a.png C/newfile3.png && + cp ../test9200a.png D/newfile4.png && + git add A/newfile1.txt && + git add B/newfile2.txt && + git add C/newfile3.png && + git add D/newfile4.png && + git commit -a -m "Test: New file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + test "$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))" = "newfile1.txt/1.1/" && + test "$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))" = "newfile2.txt/1.1/" && + test "$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))" = "newfile3.png/1.1/-kb" && + test "$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))" = "newfile4.png/1.1/-kb" && + diff A/newfile1.txt ../A/newfile1.txt && + diff B/newfile2.txt ../B/newfile2.txt && + diff C/newfile3.png ../C/newfile3.png && + diff D/newfile4.png ../D/newfile4.png + )' + +test_expect_success \ + 'Remove two files, add two and update two' \ + 'echo Hello1 >>A/newfile1.txt && + rm -f B/newfile2.txt && + rm -f C/newfile3.png && + echo Hello5 >E/newfile5.txt && + cp ../test9200b.png D/newfile4.png && + cp ../test9200a.png F/newfile6.png && + git add E/newfile5.txt && + git add F/newfile6.png && + git commit -a -m "Test: Remove, add and update" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + test "$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))" = "newfile1.txt/1.2/" && + test "$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))" = "newfile4.png/1.2/-kb" && + test "$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))" = "newfile5.txt/1.1/" && + test "$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))" = "newfile6.png/1.1/-kb" && + diff A/newfile1.txt ../A/newfile1.txt && + diff D/newfile4.png ../D/newfile4.png && + diff E/newfile5.txt ../E/newfile5.txt && + diff F/newfile6.png ../F/newfile6.png + )' + +# Should fail (but only on the git-cvsexportcommit stage) +test_expect_success \ + 'Fail to change binary more than one generation old' \ + 'cat F/newfile6.png >>D/newfile4.png && + git commit -a -m "generatiion 1" && + cat F/newfile6.png >>D/newfile4.png && + git commit -a -m "generation 2" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + ! git cvsexportcommit -c $id + )' + +# Should fail, but only on the git-cvsexportcommit stage +test_expect_success \ + 'Fail to remove binary file more than one generation old' \ + 'git reset --hard HEAD^ && + cat F/newfile6.png >>D/newfile4.png && + git commit -a -m "generation 2 (again)" && + rm -f D/newfile4.png && + git commit -a -m "generation 3" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + ! git cvsexportcommit -c $id + )' + +# We reuse the state from two tests back here + +# This test is here because a patch for only binary files will +# fail with gnu patch, so cvsexportcommit must handle that. +test_expect_success \ + 'Remove only binary files' \ + 'git reset --hard HEAD^^^ && + rm -f D/newfile4.png && + git commit -a -m "test: remove only a binary file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + test "$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))" = "newfile1.txt/1.2/" && + test "$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))" = "newfile5.txt/1.1/" && + test "$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))" = "newfile6.png/1.1/-kb" && + diff A/newfile1.txt ../A/newfile1.txt && + diff E/newfile5.txt ../E/newfile5.txt && + diff F/newfile6.png ../F/newfile6.png + )' + +test_expect_success \ + 'Remove only a text file' \ + 'rm -f A/newfile1.txt && + git commit -a -m "test: remove only a binary file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + test "$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))" = "" && + test "$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))" = "newfile5.txt/1.1/" && + test "$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))" = "newfile6.png/1.1/-kb" && + diff E/newfile5.txt ../E/newfile5.txt && + diff F/newfile6.png ../F/newfile6.png + )' + +test_done diff --git a/t/test9200a.png b/t/test9200a.png new file mode 100644 index 0000000000000000000000000000000000000000..7b181d15cebb4c86a6ad7fed3dbf30ce2223b4c5 GIT binary patch literal 5660 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 literal 0 HcmV?d00001 diff --git a/t/test9200b.png b/t/test9200b.png new file mode 100644 index 0000000000000000000000000000000000000000..ac22ccbd3ee9f03a3b38249ac8efdbe96b5da2cd GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^9zZP3!VDyJZ(h*_aRPioToo7?5)xuJtY5{@z;N#D z@dFGDFJ3(R{{7qk|No7uYm$J<7)yfuf*Bm1-ADs*lDyqr7&=&GL8fsQctjR6FmMZl zFeAgPITAoY_7YEDSN3bH%%X-S`j4JZ016d)x;TbtoKN<6ufXCZA)&>gl@*-uLV<^+ zZOfu-7cOu}w0W9H3$HwJqlx472Q4Ervph31wm>lpQB&rr2^-hlWNOq5Vkv20mdKI;Vst05+voj{pDw literal 0 HcmV?d00001 -- 2.30.2