{"thread":{"id":"43194","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","startedAt":"2006-11-12T15:29:42Z","lastAt":"2006-11-14T06:56:57Z","messageCount":7,"participants":["Robin Rosenberg","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"295399","messageId":"200611121629.43104.robin.rosenberg@dewire.com","threadId":"43194","inReplyTo":null,"subject":"[PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2006-11-12T15:29:42Z","receivedAt":"2006-11-12T15:29:42Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"Now adding, removing and changing binary files works. I added test cases to make sure\nit works and can be verified by others. Som other corner cases were resolved too.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\ndiff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl\nindex 5e23851f8cf866112baf3e76973a8ca649d5c105..78c847ec906af8044e43f55d860a0652eff3e759 100755\n--- a/git-cvsexportcommit.perl\n+++ b/git-cvsexportcommit.perl\n@@ -139,6 +139,17 @@ foreach my $f (@files) {\n \tpush @dfiles, $fields[5];\n     }\n }\n+my (@binfiles, @abfiles, @dbfiles, @bfiles, @mbfiles);\n+@binfiles = grep m/^Binary files/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit);\n+map { chomp } @binfiles;\n+@abfiles = grep s/^Binary files \\/dev\\/null and b\\/(.*) differ$/$1/, @binfiles;\n+@dbfiles = grep s/^Binary files a\\/(.*) and \\/dev\\/null differ$/$1/, @binfiles;\n+@mbfiles = grep s/^Binary files a\\/(.*) and b\\/(.*) differ$/$1/, @binfiles;\n+push @bfiles, @abfiles;\n+push @bfiles, @dbfiles;\n+push @bfiles, @mbfiles;\n+push @mfiles, @mbfiles;\n+\n $opt_v && print \"The commit affects:\\n \";\n $opt_v && print join (\"\\n \", @afiles,@mfiles,@dfiles) . \"\\n\\n\";\n undef @files; # don't need it anymore\n@@ -153,6 +164,10 @@ foreach my $d (@dirs) {\n }\n foreach my $f (@afiles) {\n     # This should return only one value\n+    if ($f =~ m,(.*)/[^/]*$,) {\n+        my $p=\"m,^\".$1.\"\\$,\";\n+\tnext if grep $p,@dirs;\n+    }\n     my @status = grep(m/^File/,  safe_pipe_capture('cvs', '-q', 'status' ,$f));\n     if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};\n     if (-d dirname $f and $status[0] !~ m/Status: Unknown$/\n@@ -162,6 +177,7 @@ foreach my $f (@afiles) {\n \twarn \"Status was: $status[0]\\n\";\n     }\n }\n+\n foreach my $f (@mfiles, @dfiles) {\n     # TODO:we need to handle removed in cvs\n     my @status = grep(m/^File/,  safe_pipe_capture('cvs', '-q', 'status' ,$f));\n@@ -200,24 +216,32 @@ foreach my $d (@dirs) {\n \n print \"'Patching' binary files\\n\";\n \n-my @bfiles = grep(m/^Binary/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit));\n-@bfiles = map { chomp } @bfiles;\n foreach my $f (@bfiles) {\n     # check that the file in cvs matches the \"old\" file\n     # extract the file to $tmpdir and compare with cmp\n-    my $tree = safe_pipe_capture('git-rev-parse', \"$parent^{tree}\");\n-    chomp $tree;\n-    my $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n-    chomp $blob;\n-    `git-cat-file blob $blob > $tmpdir/blob`;\n-    if (system('cmp', '-s', $f, \"$tmpdir/blob\")) {\n-\twarn \"Binary file $f in CVS does not match parent.\\n\";\n-\t$dirty = 1;\n-\tnext;\n+    my $p=\"m/^$f$/\";\n+    if (not(grep $p,@afiles)) {\n+        my $tree = safe_pipe_capture('git-rev-parse', \"$parent^{tree}\");\n+\tchomp $tree;\n+\tmy $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n+\tchomp $blob;\n+        `git-cat-file blob $blob > $tmpdir/blob`;\n+        if (system('cmp', '-s', $f, \"$tmpdir/blob\")) {\n+\t    warn \"Binary file $f in CVS does not match parent.\\n\";\n+\t    if (not $opt_f) {\n+\t        $dirty = 1;\n+\t\tnext;\n+\t    }\n+        }\n+    }\n+    if (not(grep m/^$f$/,@dfiles)) {\n+\tmy $tree = safe_pipe_capture('git-rev-parse', \"$commit^{tree}\");\n+\tchomp $tree;\n+\tmy $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n+\tchomp $blob;\n+\t# replace with the new file\n+\t`git-cat-file blob $blob > $f`;\n     }\n-\n-    # replace with the new file\n-     `git-cat-file blob $blob > $f`;\n \n     # TODO: something smart with file modes\n \n@@ -231,7 +255,10 @@ ## apply non-binary changes\n my $fuzz = $opt_p ? 0 : 2;\n \n print \"Patching non-binary files\\n\";\n-print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;\n+\n+if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) ne scalar(@bfiles)) {\n+    print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;\n+}\n \n my $dirtypatch = 0;\n if (($? >> 8) == 2) {\n@@ -242,7 +269,11 @@ if (($? >> 8) == 2) {\n }\n \n foreach my $f (@afiles) {\n-    system('cvs', 'add', $f);\n+    if (grep /^$f$/,@bfiles) {\n+      system('cvs', 'add','-kb',$f);\n+    } else {\n+      system('cvs', 'add', $f);\n+    }\n     if ($?) {\n \t$dirty = 1;\n \twarn \"Failed to cvs add $f -- you may need to do it manually\";\ndiff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh\nnew file mode 100755\nindex 0000000000000000000000000000000000000000..0ae03f80694a5d4ca3e61b40f6787a89fe8a496e\n--- /dev/null\n+++ b/t/t9200-git-cvsexportcommit.sh\n@@ -0,0 +1,145 @@\n+#!/bin/bash\n+#\n+# Copyright (c) Robin Rosenberg\n+#\n+test_description='CVS export comit. '\n+\n+. ./test-lib.sh\n+\n+cvs >/dev/null 2>&1\n+if test $? -ne 1\n+then\n+    test_expect_success 'skipping git-cvsexportcommit tests, cvs not found' :\n+    test_done\n+    exit\n+fi\n+\n+export CVSROOT=$(pwd)/cvsroot\n+export CVSWORK=$(pwd)/cvswork\n+rm -rf \"$CVSROOT\" \"$CVSWORK\"\n+mkdir \"$CVSROOT\" &&\n+cvs init &&\n+cvs -Q co -d \"$CVSWORK\" . &&\n+export GIT_DIR=$(pwd)/.git &&\n+echo >empty &&\n+git add empty &&\n+git commit -a -m \"Initial\" 2>/dev/null ||\n+exit 1\n+\n+test_expect_success \\\n+    'New file' \\\n+    'mkdir A B C D E F &&\n+     echo hello1 >A/newfile1.txt &&\n+     echo hello2 >B/newfile2.txt &&\n+     cp ../test9200a.png C/newfile3.png &&\n+     cp ../test9200a.png D/newfile4.png &&\n+     git add A/newfile1.txt &&\n+     git add B/newfile2.txt &&\n+     git add C/newfile3.png &&\n+     git add D/newfile4.png &&\n+     git commit -a -m \"Test: New file\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile1.txt/1.1/\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile2.txt/1.1/\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile3.png/1.1/-kb\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile4.png/1.1/-kb\" &&\n+     diff A/newfile1.txt ../A/newfile1.txt &&\n+     diff B/newfile2.txt ../B/newfile2.txt &&\n+     diff C/newfile3.png ../C/newfile3.png &&\n+     diff D/newfile4.png ../D/newfile4.png\n+     )'\n+\n+test_expect_success \\\n+    'Remove two files, add two and update two' \\\n+    'echo Hello1 >>A/newfile1.txt &&\n+     rm -f B/newfile2.txt &&\n+     rm -f C/newfile3.png &&\n+     echo Hello5  >E/newfile5.txt &&\n+     cp ../test9200b.png D/newfile4.png &&\n+     cp ../test9200a.png F/newfile6.png &&\n+     git add E/newfile5.txt &&\n+     git add F/newfile6.png &&\n+     git commit -a -m \"Test: Remove, add and update\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile1.txt/1.2/\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile4.png/1.2/-kb\" &&\n+     test \"$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile5.txt/1.1/\" &&\n+     test \"$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile6.png/1.1/-kb\" &&\n+     diff A/newfile1.txt ../A/newfile1.txt &&\n+     diff D/newfile4.png ../D/newfile4.png &&\n+     diff E/newfile5.txt ../E/newfile5.txt &&\n+     diff F/newfile6.png ../F/newfile6.png\n+     )'\n+\n+# Should fail (but only on the git-cvsexportcommit stage)\n+test_expect_success \\\n+    'Fail to change binary more than one generation old' \\\n+    'cat F/newfile6.png >>D/newfile4.png &&\n+     git commit -a -m \"generatiion 1\" &&\n+     cat F/newfile6.png >>D/newfile4.png &&\n+     git commit -a -m \"generation 2\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     ! git cvsexportcommit -c $id\n+     )'\n+\n+# Should fail, but only on the git-cvsexportcommit stage\n+test_expect_success \\\n+    'Fail to remove binary file more than one generation old' \\\n+    'git reset --hard HEAD^ &&\n+     cat F/newfile6.png >>D/newfile4.png &&\n+     git commit -a -m \"generation 2 (again)\" &&\n+     rm -f D/newfile4.png &&\n+     git commit -a -m \"generation 3\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     ! git cvsexportcommit -c $id\n+     )'\n+\n+# We reuse the state from two tests back here\n+\n+# This test is here because a patch for only binary files will\n+# fail with gnu patch, so cvsexportcommit must handle that.\n+test_expect_success \\\n+    'Remove only binary files' \\\n+    'git reset --hard HEAD^^^ &&\n+     rm -f D/newfile4.png &&\n+     git commit -a -m \"test: remove only a binary file\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile1.txt/1.2/\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile5.txt/1.1/\" &&\n+     test \"$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile6.png/1.1/-kb\" &&\n+     diff A/newfile1.txt ../A/newfile1.txt &&\n+     diff E/newfile5.txt ../E/newfile5.txt &&\n+     diff F/newfile6.png ../F/newfile6.png\n+     )'\n+\n+test_expect_success \\\n+    'Remove only a text file' \\\n+    'rm -f A/newfile1.txt &&\n+     git commit -a -m \"test: remove only a binary file\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile5.txt/1.1/\" &&\n+     test \"$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile6.png/1.1/-kb\" &&\n+     diff E/newfile5.txt ../E/newfile5.txt &&\n+     diff F/newfile6.png ../F/newfile6.png\n+     )' \n+\n+test_done\ndiff --git a/t/test9200a.png b/t/test9200a.png\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..7b181d15cebb4c86a6ad7fed3dbf30ce2223b4c5\nGIT binary patch\nliteral 5660\n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\n\ndiff --git a/t/test9200b.png b/t/test9200b.png\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..ac22ccbd3ee9f03a3b38249ac8efdbe96b5da2cd\nGIT binary patch\nliteral 275\nzc%17D@N?(olHy`uVBq!ia0vp^9zZP3!VDyJZ(h*_aRPioToo7?5)xuJtY5{@z;N#D\nz@dFGDFJ3(R{{7qk|No7uYm$J<7)yfuf*Bm1-ADs*lDyqr7&=&GL8fsQctjR6FmMZl\nzFeAgPITAoY_7YEDSN3bH%%X-S`j4JZ016d)x;TbtoKN<6ufXCZA)&>gl@*-uLV<^+\nzZOfu-7cOu}w0W9H3$HwJqlx472Q4Ervph31wm>lpQB&rr2^-hlWNOq5Vkv20<q=-Z\nz@v30LY2AXTcBx4_L=O5$-0^JfxTAF7fm=Y}A_nHk3XTg7IPfqqTq@aCrp)Sh2xvKj\nMr>mdKI;Vst05+voj{pDw\n\n-- \n1.4.2\n"},{"id":"297027","messageId":"7vmz6wark9.fsf@assigned-by-dhcp.cox.net","threadId":"43194","inReplyTo":"200611121629.43104.robin.rosenberg@dewire.com","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-13T04:39:18Z","receivedAt":"2006-11-13T04:39:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Robin Rosenberg <robin.rosenberg@dewire.com> writes:\n\n> Now adding, removing and changing binary files works. I added\n> test cases to make sure qit works and can be verified by\n> others. Som other corner cases were resolved too.\n>\n> Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n\nThanks.\n\nIt is necessary to clarify what these other corner cases are in\nthe commit log message.  Three months down the road you yourself\nwould not remember what they were.\n\nYou seem to like:\n\n\tmy $p = \"m,^$pathname\\$,\";\n        if (grep $p,@array) { do this... }\n\nbut this is a bad habit.  $pathname can contain regexp\nmetacharacters or a comma.  You should just say:\n\n\tif (grep { $_ eq $pathname } @arrray) { do this... }\n\ninstead.  I'd fix them up with the attached patch.\n\nIt would also be nice to rework this program so that it can work\nwith whitespaces in pathnames.  I do not think it currently\nworks with them at all.\n\nIt appears that this program was never used in western\nhemisphere, by the way ;-).\n\n---\n\ndiff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl\nindex 78c847e..b1cc014 100755\n--- a/git-cvsexportcommit.perl\n+++ b/git-cvsexportcommit.perl\n@@ -1,10 +1,10 @@\n #!/usr/bin/perl -w\n \n # Known limitations:\n-# - cannot add or remove binary files\n # - does not propagate permissions\n # - tells \"ready for commit\" even when things could not be completed\n #   (eg addition of a binary file)\n+# - does not handle whitespace in pathnames at all.\n \n use strict;\n use Getopt::Std;\n@@ -68,9 +68,9 @@ foreach my $line (@commit) {\n     if ($stage eq 'headers') {\n \tif ($line =~ m/^parent (\\w{40})$/) { # found a parent\n \t    push @parents, $1;\n-\t} elsif ($line =~ m/^author (.+) \\d+ \\+\\d+$/) {\n+\t} elsif ($line =~ m/^author (.+) \\d+ [-+]\\d+$/) {\n \t    $author = $1;\n-\t} elsif ($line =~ m/^committer (.+) \\d+ \\+\\d+$/) {\n+\t} elsif ($line =~ m/^committer (.+) \\d+ [-+]\\d+$/) {\n \t    $committer = $1;\n \t}\n     } else {\n@@ -165,8 +165,8 @@ foreach my $d (@dirs) {\n foreach my $f (@afiles) {\n     # This should return only one value\n     if ($f =~ m,(.*)/[^/]*$,) {\n-        my $p=\"m,^\".$1.\"\\$,\";\n-\tnext if grep $p,@dirs;\n+\tmy $p = $1;\n+\tnext if (grep { $_ eq $p } @dirs);\n     }\n     my @status = grep(m/^File/,  safe_pipe_capture('cvs', '-q', 'status' ,$f));\n     if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};\n@@ -219,8 +219,7 @@ print \"'Patching' binary files\\n\";\n foreach my $f (@bfiles) {\n     # check that the file in cvs matches the \"old\" file\n     # extract the file to $tmpdir and compare with cmp\n-    my $p=\"m/^$f$/\";\n-    if (not(grep $p,@afiles)) {\n+    if (not(grep { $_ eq $f } @afiles)) {\n         my $tree = safe_pipe_capture('git-rev-parse', \"$parent^{tree}\");\n \tchomp $tree;\n \tmy $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n@@ -234,7 +233,7 @@ foreach my $f (@bfiles) {\n \t    }\n         }\n     }\n-    if (not(grep m/^$f$/,@dfiles)) {\n+    if (not(grep { $_ eq $f } @dfiles)) {\n \tmy $tree = safe_pipe_capture('git-rev-parse', \"$commit^{tree}\");\n \tchomp $tree;\n \tmy $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n@@ -256,7 +255,7 @@ my $fuzz = $opt_p ? 0 : 2;\n \n print \"Patching non-binary files\\n\";\n \n-if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) ne scalar(@bfiles)) {\n+if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) != scalar(@bfiles)) {\n     print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;\n }\n \n@@ -269,7 +268,7 @@ if (($? >> 8) == 2) {\n }\n \n foreach my $f (@afiles) {\n-    if (grep /^$f$/,@bfiles) {\n+    if (grep { $_ eq $f } @bfiles) {\n       system('cvs', 'add','-kb',$f);\n     } else {\n       system('cvs', 'add', $f);\n\n\n"},{"id":"294178","messageId":"200611132139.25342.robin.rosenberg@dewire.com","threadId":"43194","inReplyTo":"7vmz6wark9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2006-11-13T20:39:25Z","receivedAt":"2006-11-13T20:39:25Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"måndag 13 november 2006 05:39 skrev Junio C Hamano:\n> Robin Rosenberg <robin.rosenberg@dewire.com> writes:\n> > Now adding, removing and changing binary files works. I added\n> > test cases to make sure qit works and can be verified by\n> > others. Som other corner cases were resolved too.\n> >\n> > Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n>\n> Thanks.\n>\n> It is necessary to clarify what these other corner cases are in\n> the commit log message.  Three months down the road you yourself\n> would not remember what they were.\nI hardly remember now. I wrote test cases and modified the code until it \nworked. I'll skip that remark.\n\n>\n> You seem to like:\n>\n> \tmy $p = \"m,^$pathname\\$,\";\n>         if (grep $p,@array) { do this... }\n>\n\nI can't say I'm fond of any perl syntax, really. Perl is a very usable, but \nugly tool.\n\n> but this is a bad habit.  $pathname can contain regexp\n> metacharacters or a comma.  You should just say:\n>\n> \tif (grep { $_ eq $pathname } @arrray) { do this... }\n>\n> instead.  I'd fix them up with the attached patch.\n\nThanks.\n\n> It would also be nice to rework this program so that it can work\n> with whitespaces in pathnames.  I do not think it currently\n> works with them at all.\n\nI sent a patch earlier, which was not applied, due to imperfections that I \ncannot solve fully. One issue was that patch 2.5.9 was required and hacking \nit to handle binary diffs with spaces would require and even worse kludge,\n\nI can, however, send the previous patch adapted onto this one.\n\n> It appears that this program was never used in western\n> hemisphere, by the way ;-).\n\nNow, Sweden is definitely in the northern hemisphere, even during the cold \nwar, though a number of computer games colored it red (or was it only \nFinland) during the cold war.\n\nThe tests work with my locale (swedish ISO-8859-15),  even though they like \nall other tests run in the C \"hemishpere\" by default. AFAIK, git isn't very \nuser friendly with non-ascii filenames as it is today and cvsexportcommit \ndidn't work on such files before, and it doesn't now. No change there. \n\nAnother patch, another day, maybe. \n\n-- robin\n\n\nFrom b591652ab3a65d3e319cbf59bcd161e3588a4696 Mon Sep 17 00:00:00 2001\nFrom: Robin Rosenberg <robin.rosenberg@dewire.com>\nDate: Mon, 13 Nov 2006 21:29:01 +0100\nSubject: [PATCH] Rework cvsexportcommit to handle binary files for all cases.\n\nAlso adds test cases for adding removing and deleting\nbinary and text files plus two tests for the checks on\nbinary files.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n\ndiff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl\nindex 5e23851f8cf866112baf3e76973a8ca649d5c105..facb4667eefe79cbd4d29e542ec5e8111a7a973c 100755\n--- a/git-cvsexportcommit.perl\n+++ b/git-cvsexportcommit.perl\n@@ -1,10 +1,10 @@\n #!/usr/bin/perl -w\n \n # Known limitations:\n-# - cannot add or remove binary files\n # - does not propagate permissions\n # - tells \"ready for commit\" even when things could not be completed\n-#   (eg addition of a binary file)\n+#   (not sure this is true anymore, maybe more testing is needed)\n+# - does not handle whitespace in pathnames at all.\n \n use strict;\n use Getopt::Std;\n@@ -139,6 +139,17 @@ foreach my $f (@files) {\n \tpush @dfiles, $fields[5];\n     }\n }\n+my (@binfiles, @abfiles, @dbfiles, @bfiles, @mbfiles);\n+@binfiles = grep m/^Binary files/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit);\n+map { chomp } @binfiles;\n+@abfiles = grep s/^Binary files \\/dev\\/null and b\\/(.*) differ$/$1/, @binfiles;\n+@dbfiles = grep s/^Binary files a\\/(.*) and \\/dev\\/null differ$/$1/, @binfiles;\n+@mbfiles = grep s/^Binary files a\\/(.*) and b\\/(.*) differ$/$1/, @binfiles;\n+push @bfiles, @abfiles;\n+push @bfiles, @dbfiles;\n+push @bfiles, @mbfiles;\n+push @mfiles, @mbfiles;\n+\n $opt_v && print \"The commit affects:\\n \";\n $opt_v && print join (\"\\n \", @afiles,@mfiles,@dfiles) . \"\\n\\n\";\n undef @files; # don't need it anymore\n@@ -153,6 +164,10 @@ foreach my $d (@dirs) {\n }\n foreach my $f (@afiles) {\n     # This should return only one value\n+    if ($f =~ m,(.*)/[^/]*$,) {\n+\tmy $p = $1;\n+\tnext if (grep { $_ eq $p } @dirs);\n+    }\n     my @status = grep(m/^File/,  safe_pipe_capture('cvs', '-q', 'status' ,$f));\n     if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};\n     if (-d dirname $f and $status[0] !~ m/Status: Unknown$/\n@@ -162,6 +177,7 @@ foreach my $f (@afiles) {\n \twarn \"Status was: $status[0]\\n\";\n     }\n }\n+\n foreach my $f (@mfiles, @dfiles) {\n     # TODO:we need to handle removed in cvs\n     my @status = grep(m/^File/,  safe_pipe_capture('cvs', '-q', 'status' ,$f));\n@@ -200,24 +216,31 @@ foreach my $d (@dirs) {\n \n print \"'Patching' binary files\\n\";\n \n-my @bfiles = grep(m/^Binary/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit));\n-@bfiles = map { chomp } @bfiles;\n foreach my $f (@bfiles) {\n     # check that the file in cvs matches the \"old\" file\n     # extract the file to $tmpdir and compare with cmp\n-    my $tree = safe_pipe_capture('git-rev-parse', \"$parent^{tree}\");\n-    chomp $tree;\n-    my $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n-    chomp $blob;\n-    `git-cat-file blob $blob > $tmpdir/blob`;\n-    if (system('cmp', '-s', $f, \"$tmpdir/blob\")) {\n-\twarn \"Binary file $f in CVS does not match parent.\\n\";\n-\t$dirty = 1;\n-\tnext;\n+    if (not(grep { $_ eq $f } @afiles)) {\n+        my $tree = safe_pipe_capture('git-rev-parse', \"$parent^{tree}\");\n+\tchomp $tree;\n+\tmy $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n+\tchomp $blob;\n+        `git-cat-file blob $blob > $tmpdir/blob`;\n+        if (system('cmp', '-s', $f, \"$tmpdir/blob\")) {\n+\t    warn \"Binary file $f in CVS does not match parent.\\n\";\n+\t    if (not $opt_f) {\n+\t        $dirty = 1;\n+\t\tnext;\n+\t    }\n+        }\n+    }\n+    if (not(grep { $_ eq $f } @dfiles)) {\n+\tmy $tree = safe_pipe_capture('git-rev-parse', \"$commit^{tree}\");\n+\tchomp $tree;\n+\tmy $blob = `git-ls-tree $tree \"$f\" | cut -f 1 | cut -d ' ' -f 3`;\n+\tchomp $blob;\n+\t# replace with the new file\n+\t`git-cat-file blob $blob > $f`;\n     }\n-\n-    # replace with the new file\n-     `git-cat-file blob $blob > $f`;\n \n     # TODO: something smart with file modes\n \n@@ -231,7 +254,10 @@ ## apply non-binary changes\n my $fuzz = $opt_p ? 0 : 2;\n \n print \"Patching non-binary files\\n\";\n-print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;\n+\n+if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) != scalar(@bfiles)) {\n+    print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;\n+}\n \n my $dirtypatch = 0;\n if (($? >> 8) == 2) {\n@@ -242,7 +268,11 @@ if (($? >> 8) == 2) {\n }\n \n foreach my $f (@afiles) {\n-    system('cvs', 'add', $f);\n+    if (grep { $_ eq $f } @bfiles) {\n+      system('cvs', 'add','-kb',$f);\n+    } else {\n+      system('cvs', 'add', $f);\n+    }\n     if ($?) {\n \t$dirty = 1;\n \twarn \"Failed to cvs add $f -- you may need to do it manually\";\ndiff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh\nnew file mode 100755\nindex 0000000000000000000000000000000000000000..0ae03f80694a5d4ca3e61b40f6787a89fe8a496e\n--- /dev/null\n+++ b/t/t9200-git-cvsexportcommit.sh\n@@ -0,0 +1,145 @@\n+#!/bin/bash\n+#\n+# Copyright (c) Robin Rosenberg\n+#\n+test_description='CVS export comit. '\n+\n+. ./test-lib.sh\n+\n+cvs >/dev/null 2>&1\n+if test $? -ne 1\n+then\n+    test_expect_success 'skipping git-cvsexportcommit tests, cvs not found' :\n+    test_done\n+    exit\n+fi\n+\n+export CVSROOT=$(pwd)/cvsroot\n+export CVSWORK=$(pwd)/cvswork\n+rm -rf \"$CVSROOT\" \"$CVSWORK\"\n+mkdir \"$CVSROOT\" &&\n+cvs init &&\n+cvs -Q co -d \"$CVSWORK\" . &&\n+export GIT_DIR=$(pwd)/.git &&\n+echo >empty &&\n+git add empty &&\n+git commit -a -m \"Initial\" 2>/dev/null ||\n+exit 1\n+\n+test_expect_success \\\n+    'New file' \\\n+    'mkdir A B C D E F &&\n+     echo hello1 >A/newfile1.txt &&\n+     echo hello2 >B/newfile2.txt &&\n+     cp ../test9200a.png C/newfile3.png &&\n+     cp ../test9200a.png D/newfile4.png &&\n+     git add A/newfile1.txt &&\n+     git add B/newfile2.txt &&\n+     git add C/newfile3.png &&\n+     git add D/newfile4.png &&\n+     git commit -a -m \"Test: New file\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile1.txt/1.1/\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile2.txt/1.1/\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile3.png/1.1/-kb\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile4.png/1.1/-kb\" &&\n+     diff A/newfile1.txt ../A/newfile1.txt &&\n+     diff B/newfile2.txt ../B/newfile2.txt &&\n+     diff C/newfile3.png ../C/newfile3.png &&\n+     diff D/newfile4.png ../D/newfile4.png\n+     )'\n+\n+test_expect_success \\\n+    'Remove two files, add two and update two' \\\n+    'echo Hello1 >>A/newfile1.txt &&\n+     rm -f B/newfile2.txt &&\n+     rm -f C/newfile3.png &&\n+     echo Hello5  >E/newfile5.txt &&\n+     cp ../test9200b.png D/newfile4.png &&\n+     cp ../test9200a.png F/newfile6.png &&\n+     git add E/newfile5.txt &&\n+     git add F/newfile6.png &&\n+     git commit -a -m \"Test: Remove, add and update\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile1.txt/1.2/\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile4.png/1.2/-kb\" &&\n+     test \"$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile5.txt/1.1/\" &&\n+     test \"$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile6.png/1.1/-kb\" &&\n+     diff A/newfile1.txt ../A/newfile1.txt &&\n+     diff D/newfile4.png ../D/newfile4.png &&\n+     diff E/newfile5.txt ../E/newfile5.txt &&\n+     diff F/newfile6.png ../F/newfile6.png\n+     )'\n+\n+# Should fail (but only on the git-cvsexportcommit stage)\n+test_expect_success \\\n+    'Fail to change binary more than one generation old' \\\n+    'cat F/newfile6.png >>D/newfile4.png &&\n+     git commit -a -m \"generatiion 1\" &&\n+     cat F/newfile6.png >>D/newfile4.png &&\n+     git commit -a -m \"generation 2\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     ! git cvsexportcommit -c $id\n+     )'\n+\n+# Should fail, but only on the git-cvsexportcommit stage\n+test_expect_success \\\n+    'Fail to remove binary file more than one generation old' \\\n+    'git reset --hard HEAD^ &&\n+     cat F/newfile6.png >>D/newfile4.png &&\n+     git commit -a -m \"generation 2 (again)\" &&\n+     rm -f D/newfile4.png &&\n+     git commit -a -m \"generation 3\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     ! git cvsexportcommit -c $id\n+     )'\n+\n+# We reuse the state from two tests back here\n+\n+# This test is here because a patch for only binary files will\n+# fail with gnu patch, so cvsexportcommit must handle that.\n+test_expect_success \\\n+    'Remove only binary files' \\\n+    'git reset --hard HEAD^^^ &&\n+     rm -f D/newfile4.png &&\n+     git commit -a -m \"test: remove only a binary file\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile1.txt/1.2/\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile5.txt/1.1/\" &&\n+     test \"$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile6.png/1.1/-kb\" &&\n+     diff A/newfile1.txt ../A/newfile1.txt &&\n+     diff E/newfile5.txt ../E/newfile5.txt &&\n+     diff F/newfile6.png ../F/newfile6.png\n+     )'\n+\n+test_expect_success \\\n+    'Remove only a text file' \\\n+    'rm -f A/newfile1.txt &&\n+     git commit -a -m \"test: remove only a binary file\" &&\n+     id=$(git rev-list --max-count=1 HEAD) &&\n+     (cd \"$CVSWORK\" &&\n+     git cvsexportcommit -c $id &&\n+     test \"$(echo $(sort A/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort B/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort C/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort D/CVS/Entries|cut -d/ -f2,3,5))\" = \"\" &&\n+     test \"$(echo $(sort E/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile5.txt/1.1/\" &&\n+     test \"$(echo $(sort F/CVS/Entries|cut -d/ -f2,3,5))\" = \"newfile6.png/1.1/-kb\" &&\n+     diff E/newfile5.txt ../E/newfile5.txt &&\n+     diff F/newfile6.png ../F/newfile6.png\n+     )' \n+\n+test_done\ndiff --git a/t/test9200a.png b/t/test9200a.png\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..7b181d15cebb4c86a6ad7fed3dbf30ce2223b4c5\nGIT binary patch\nliteral 5660\n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\n\ndiff --git a/t/test9200b.png b/t/test9200b.png\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..ac22ccbd3ee9f03a3b38249ac8efdbe96b5da2cd\nGIT binary patch\nliteral 275\nzc%17D@N?(olHy`uVBq!ia0vp^9zZP3!VDyJZ(h*_aRPioToo7?5)xuJtY5{@z;N#D\nz@dFGDFJ3(R{{7qk|No7uYm$J<7)yfuf*Bm1-ADs*lDyqr7&=&GL8fsQctjR6FmMZl\nzFeAgPITAoY_7YEDSN3bH%%X-S`j4JZ016d)x;TbtoKN<6ufXCZA)&>gl@*-uLV<^+\nzZOfu-7cOu}w0W9H3$HwJqlx472Q4Ervph31wm>lpQB&rr2^-hlWNOq5Vkv20<q=-Z\nz@v30LY2AXTcBx4_L=O5$-0^JfxTAF7fm=Y}A_nHk3XTg7IPfqqTq@aCrp)Sh2xvKj\nMr>mdKI;Vst05+voj{pDw\n\n-- \n1.4.2\n\n"},{"id":"294014","messageId":"200611132140.01578.robin.rosenberg@dewire.com","threadId":"43194","inReplyTo":"7vmz6wark9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2006-11-13T20:40:01Z","receivedAt":"2006-11-13T20:40:01Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"And the updated fix for spaces in file names\n\n-- robin\n\n\nFrom bf4030e88bfd5b5f1a84b19a1be36f8178f2b24a Mon Sep 17 00:00:00 2001\nFrom: Robin Rosenberg <robin.rosenberg@dewire.com>\nDate: Mon, 13 Nov 2006 21:29:06 +0100\nSubject: [PATCH] Make cvsexportcommit work with filenames containing spaces.\n\nBinary files are except to this so far.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n\ndiff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl\nindex facb4667eefe79cbd4d29e542ec5e8111a7a973c..017648c8c252e60151320f09a428f0bff6ae46de 100755\n--- a/git-cvsexportcommit.perl\n+++ b/git-cvsexportcommit.perl\n@@ -4,7 +4,7 @@ # Known limitations:\n # - does not propagate permissions\n # - tells \"ready for commit\" even when things could not be completed\n #   (not sure this is true anymore, maybe more testing is needed)\n-# - does not handle whitespace in pathnames at all.\n+# - Fedora/RHEL uses patch 2.5.4 which doesn't handles spaces in file names\n \n use strict;\n use Getopt::Std;\n@@ -121,7 +121,14 @@ #print @files;\n $? && die \"Error in git-diff-tree\";\n foreach my $f (@files) {\n     chomp $f;\n-    my @fields = split(m!\\s+!, $f);\n+    $f =~ m/^(\\S+) (\\S+) (\\S+) (\\S+) (\\S+)\t(.*)/;\n+    my @fields = ();\n+    $fields[++$#fields] = $1;\n+    $fields[++$#fields] = $2;\n+    $fields[++$#fields] = $3;\n+    $fields[++$#fields] = $4;\n+    $fields[++$#fields] = $5;\n+    $fields[++$#fields] = $6;\n     if ($fields[4] eq 'A') {\n         my $path = $fields[5];\n \tpush @afiles, $path;\n@@ -256,7 +263,19 @@ my $fuzz = $opt_p ? 0 : 2;\n print \"Patching non-binary files\\n\";\n \n if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) != scalar(@bfiles)) {\n-    print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;\n+    my $saveslash = $/;\n+    undef $/;\n+\n+    open DIFF, \"git-diff-tree -p $parent -p $commit|\" || die \"Cannot diff\";\n+    open PATCH, \"|tee \\$\\$.diff|patch -p1 -F $fuzz\" || die \"Cannot patch\";\n+    my $delta = <DIFF>;\n+    close DIFF || die \"Could not diff\";\n+    unless (defined $ENV{'GIT_CVSEXPORTCOMMIT_NO_SPACES'}) {\n+        $delta =~ s/\\n(index [^\\n]*)\\n(--- [^\\n]*)\\n(\\+\\+\\+ [^\\n]*)\\n(@@[^\\n]*@@)\\n/$1\\n$2\\t\\n$3\\t\\n$4\\n/sg\n+    }\n+    print PATCH $delta;\n+    close PATCH || die \"Could not patch\";\n+    $/ = $saveslash;\n }\n \n my $dirtypatch = 0;\ndiff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh\nindex 0ae03f80694a5d4ca3e61b40f6787a89fe8a496e..bf40d12f27ddde562da8f8526349df1784a48ae8 100755\n--- a/t/t9200-git-cvsexportcommit.sh\n+++ b/t/t9200-git-cvsexportcommit.sh\n@@ -142,4 +142,28 @@ test_expect_success \\\n      diff F/newfile6.png ../F/newfile6.png\n      )' \n \n+test_expect_success \\\n+     'New file with spaces in file name' \\\n+     'mkdir G &&\n+      echo ok then >\"G/with spaces.txt\" &&\n+      git add \"G/with spaces.txt\" && \\\n+      git commit -a -m \"With spaces\" &&\n+      id=$(git rev-list --max-count=1 HEAD) &&\n+      (cd \"$CVSWORK\" &&\n+      git-cvsexportcommit -c $id &&\n+      test $(cat G/CVS/Entries|wc -l) = 1\n+      )'\n+\n+test_expect_success \\\n+     'Update file with spaces in file name' \\\n+     'echo Ok then >>\"G/with spaces.txt\" &&\n+      git add \"G/with spaces.txt\" &&\n+      git commit -a -m \"Update with spaces\" &&\n+      id=$(git rev-list --max-count=1 HEAD) &&\n+      (cd \"$CVSWORK\" &&\n+      git-cvsexportcommit -c $id &&\n+      test $(cat G/CVS/Entries|wc -l) = 1\n+      )'\n+     \n+\n test_done\n-- \n1.4.2\n\n"},{"id":"295202","messageId":"7vveli4zxc.fsf@assigned-by-dhcp.cox.net","threadId":"43194","inReplyTo":"200611132139.25342.robin.rosenberg@dewire.com","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-14T00:47:27Z","receivedAt":"2006-11-14T00:47:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Robin Rosenberg <robin.rosenberg@dewire.com> writes:\n\n>> It would also be nice to rework this program so that it can work\n>> with whitespaces in pathnames.  I do not think it currently\n>> works with them at all.\n>\n> I sent a patch earlier, which was not applied, due to imperfections that I \n> cannot solve fully. One issue was that patch 2.5.9 was required and hacking \n> it to handle binary diffs with spaces would require and even worse kludge,\n\nI suspect that we should not be using patch, but instead be\nusing git-apply perhaps with -C option if people want fuzz.\n\n>> It appears that this program was never used in western\n>> hemisphere, by the way ;-).\n>\n> Now, Sweden is definitely in the northern hemisphere, even during the cold \n> war, though a number of computer games colored it red (or was it only \n> Finland) during the cold war.\n\nI know this script originally came from southern hemisphere, but\nI was talking about _western_ hemisphere.  The comment refers to\nthe part of the code the attached patch fixes, which I will\napply along with your updated patch.\n\n> The tests work with my locale (swedish ISO-8859-15),  even though they like \n> all other tests run in the C \"hemishpere\" by default. AFAIK, git isn't very \n> user friendly with non-ascii filenames as it is today and cvsexportcommit \n> didn't work on such files before, and it doesn't now. No change there. \n\nThat is a separate issue.  I think scripts that work with git\nplumbing should read from -z output when they need to and are\ncapable of, as we have done for git-cvsserver recently, and\nthings written in Perl certainly are capable of doing so.\n\ndiff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl\nindex facb466..b1cc014 100755\n--- a/git-cvsexportcommit.perl\n+++ b/git-cvsexportcommit.perl\n@@ -68,9 +68,9 @@ foreach my $line (@commit) {\n     if ($stage eq 'headers') {\n \tif ($line =~ m/^parent (\\w{40})$/) { # found a parent\n \t    push @parents, $1;\n-\t} elsif ($line =~ m/^author (.+) \\d+ \\+\\d+$/) {\n+\t} elsif ($line =~ m/^author (.+) \\d+ [-+]\\d+$/) {\n \t    $author = $1;\n-\t} elsif ($line =~ m/^committer (.+) \\d+ \\+\\d+$/) {\n+\t} elsif ($line =~ m/^committer (.+) \\d+ [-+]\\d+$/) {\n \t    $committer = $1;\n \t}\n     } else {\n"},{"id":"297287","messageId":"200611140749.05023.robin.rosenberg@dewire.com","threadId":"43194","inReplyTo":"7vveli4zxc.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg@dewire.com","sentAt":"2006-11-14T06:49:04Z","receivedAt":"2006-11-14T06:49:04Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"tisdag 14 november 2006 01:47 skrev Junio C Hamano:\n>Robin Rosenberg wrote:\n>> I sent a patch earlier, which was not applied, due to imperfections that I \n>> cannot solve fully. One issue was that patch 2.5.9 was required and hacking \n>> it to handle binary diffs with spaces would require and even worse kludge,\n>\n>I suspect that we should not be using patch, but instead be\n>using git-apply perhaps with -C option if people want fuzz.\n\nDoes git-apply work without a git repo? We're applying patches onto a CVS \nrepo.\n\n>[...]\n> I know this script originally came from southern hemisphere, but\n> I was talking about _western_ hemisphere.  The comment refers to\n> the part of the code the attached patch fixes, which I will\n> apply along with your updated patch.\nWestern/nothern, both apply to where I live.\n\n>[...]\n>I think scripts that work with git\n> plumbing should read from -z output when they need to and are\n> capable of, as we have done for git-cvsserver recently, and\n> things written in Perl certainly are capable of doing so.\nI'll investgate that.\n\n"},{"id":"295319","messageId":"7vmz6u3492.fsf@assigned-by-dhcp.cox.net","threadId":"43194","inReplyTo":"200611140749.05023.robin.rosenberg@dewire.com","subject":"Re: [PATCH] Rework cvsexportcommit to handle binary files for all cases.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-14T06:56:57Z","receivedAt":"2006-11-14T06:56:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Robin Rosenberg <robin.rosenberg@dewire.com> writes:\n\n> tisdag 14 november 2006 01:47 skrev Junio C Hamano:\n>>Robin Rosenberg wrote:\n>>> I sent a patch earlier, which was not applied, due to imperfections that I \n>>> cannot solve fully. One issue was that patch 2.5.9 was required and hacking \n>>> it to handle binary diffs with spaces would require and even worse kludge,\n>>\n>>I suspect that we should not be using patch, but instead be\n>>using git-apply perhaps with -C option if people want fuzz.\n>\n> Does git-apply work without a git repo? We're applying patches onto a CVS \n> repo.\n\nI do it during my day job so I know it works.  I have a git\nrepository that is updated via cvsimport from the central CVS,\nwith patches of mine managed by StGIT and git.  I export what's\napplicable with format-patch, go to a CVS working tree next door\nand run git-apply there, and then manually commit the result\ninto CVS.  In other words, I am doing what cvsexportcommit ought\nto be doing by hand.\n\n>> I know this script originally came from southern hemisphere, but\n>> I was talking about _western_ hemisphere.  The comment refers to\n>> the part of the code the attached patch fixes, which I will\n>> apply along with your updated patch.\n> Western/nothern, both apply to where I live.\n\nYes, I noticed that you are east of Greenwich, and NZ is too.\n\n"}]}