{"thread":{"id":"12850","subject":"[PATCH 0/7] Enhance TkCVS interoperability","startedAt":"2008-03-24T22:48:39Z","lastAt":"2008-03-28T07:52:10Z","messageCount":22,"participants":["Damien Diederen","Junio C Hamano","Frank Lichtenheld","Rafael Garcia-Suarez"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"72967","messageId":"cover.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":null,"subject":"[PATCH 0/7] Enhance TkCVS interoperability","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:48:39Z","receivedAt":"2008-03-24T22:48:39Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nThis series was developed to improve interoperability between\ngit-cvsserver and TkCVS, a CVS client that is fairly popular at least\nin some corporate environments.\n\nPatches 1-6 are \"obvious\" improvements, implementing missing features\nor fixing incorrect behaviour.  7 is more questionable, but likely to\nresult in more intelligible log output in a majority of cases.\n\nBear in mind that my perl-fu is not very high when reviewing this\nseries; suggestions are more than welcome!\n\n        Damien\n\nDamien Diederen (7):\n  cvsserver: Respond to the 'editors' command.\n  cvsserver: Only print the file part of filename in status header.\n  cvsserver: Do not include status output for subdirectories if -l is\n    passed.\n  cvsserver: Add a few tests for 'status' command.\n  cvsserver: Implemented update -p (print to stdout)\n  cvsserver: Added test for update -p\n  cvsserver: Use the user part of the email in log and annotate results\n\n git-cvsserver.perl              |   67 ++++++++++++++++++++++++++++++--------\n t/t9400-git-cvsserver-server.sh |   50 +++++++++++++++++++++++++++++\n 2 files changed, 103 insertions(+), 14 deletions(-)\n"},{"id":"72968","messageId":"8cb3f0ef415bdfe8a25f89fdac3d14d3b8360dcf.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 1/7] cvsserver: Respond to the 'editors' command","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:48:52Z","receivedAt":"2008-03-24T22:48:52Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\n\"Cvs editors\" lists the users currently working on watched (locked)\nfiles.  This trivial implementation always returns an empty response,\nsince git-cvsserver does not implement file locking.\n\nWithout this, TkCVS hangs at startup, waiting forever for a response.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |    7 ++++++-\n 1 files changed, 6 insertions(+), 1 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 7f632af..33d30c5 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -74,7 +74,7 @@ my $methods = {\n     'admin'           => \\&req_CATCHALL,\n     'history'         => \\&req_CATCHALL,\n     'watchers'        => \\&req_CATCHALL,\n-    'editors'         => \\&req_CATCHALL,\n+    'editors'         => \\&req_editors,\n     'annotate'        => \\&req_annotate,\n     'Global_option'   => \\&req_Globaloption,\n     #'annotate'        => \\&req_CATCHALL,\n@@ -1489,6 +1489,11 @@ sub req_status\n     print \"ok\\n\";\n }\n \n+sub req_editors\n+{\n+    print \"ok\\n\";\n+}\n+\n sub req_diff\n {\n     my ( $cmd, $data ) = @_;\n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72969","messageId":"42e48b57a0e94ca07e9dea28da2fa1f8d8a074c2.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 2/7] cvsserver: Only print the file part of the filename in status header","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:49:07Z","receivedAt":"2008-03-24T22:49:07Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nThe \"File:\" header of CVS status output only includes the basename of\nthe file, even when generating a recursive listing; do the same.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |    4 +++-\n 1 files changed, 3 insertions(+), 1 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 33d30c5..9101eef 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -1466,8 +1466,10 @@ sub req_status\n \n         $status ||= \"Unknown\";\n \n+        my ($filepart) = filenamesplit($filename);\n+\n         print \"M ===================================================================\\n\";\n-        print \"M File: $filename\\tStatus: $status\\n\";\n+        print \"M File: $filepart\\tStatus: $status\\n\";\n         if ( defined($state->{entries}{$filename}{revision}) )\n         {\n             print \"M Working revision:\\t\" . $state->{entries}{$filename}{revision} . \"\\n\";\n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72970","messageId":"acabbce71725396ac8641b59197525fdfd8e8ae9.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 3/7] cvsserver: Do not include status output for subdirectories if -l is passed","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:49:22Z","receivedAt":"2008-03-24T22:49:22Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nThis effectively implements the -l switch by pruning the entries whose\nfilenames contain a path separator.  It was previously ignored.\n\nWithout this, TkCVS includes strange \"ghost\" entries in its directory\nlistings.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 9101eef..073a426 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -1423,6 +1423,8 @@ sub req_status\n     {\n         $filename = filecleanup($filename);\n \n+        next if exists($state->{opt}{l}) && index($filename, '/', length($state->{prependdir})) >= 0;\n+\n         my $meta = $updater->getmeta($filename);\n         my $oldmeta = $meta;\n \n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72971","messageId":"96f67c3e4ad8f5fe0c179b97b9f1ae1a7943b106.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 4/7] cvsserver: Add a few tests for 'status' command","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:50:05Z","receivedAt":"2008-03-24T22:50:05Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n t/t9400-git-cvsserver-server.sh |   32 ++++++++++++++++++++++++++++++++\n 1 files changed, 32 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh\nindex b91b151..6168324 100755\n--- a/t/t9400-git-cvsserver-server.sh\n+++ b/t/t9400-git-cvsserver-server.sh\n@@ -420,4 +420,36 @@ test_expect_success 'cvs update (merge no-op)' \\\n     GIT_CONFIG=\"$git_config\" cvs -Q update &&\n     diff -q merge ../merge'\n \n+#------------\n+# CVS STATUS\n+#------------\n+\n+cd \"$WORKDIR\"\n+test_expect_success 'cvs status' '\n+    mkdir status.dir &&\n+    echo Line > status.dir/status.file &&\n+    echo Line > status.file &&\n+    git add status.dir status.file &&\n+    git commit -q -m \"Status test\" &&\n+    git push gitcvs.git >/dev/null &&\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs update &&\n+    GIT_CONFIG=\"$git_config\" cvs status | grep \"^File: status.file\" >../out &&\n+    test $(wc -l <../out) = 2\n+'\n+\n+cd \"$WORKDIR\"\n+test_expect_success 'cvs status (nonrecursive)' '\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs status -l | grep \"^File: status.file\" >../out &&\n+    test $(wc -l <../out) = 1\n+'\n+\n+cd \"$WORKDIR\"\n+test_expect_success 'cvs status (no subdirs in header)' '\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs status | grep ^File: >../out &&\n+    ! grep / <../out\n+'\n+\n test_done\n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72972","messageId":"4ba0ce96c3dcd304ca598379dc448ca50d994133.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 5/7] cvsserver: Implemented update -p (print to stdout)","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:50:32Z","receivedAt":"2008-03-24T22:50:32Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nCvs update -p -r <rev> <path> is the documented way to retrieve a\nspecific revision of a file (similar to git show <rev>:<path>).\nWithout this patch, the -p flag is ignored and status output is\nproduced, causing clients to interpret it as the contents of the file.\n\nTkCVS uses update -p as a basis for implementing its various \"View\"\nand \"Diff\" commands.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |   36 ++++++++++++++++++++++++++++--------\n 1 files changed, 28 insertions(+), 8 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 073a426..3c97226 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -958,6 +958,17 @@ sub req_update\n             $meta = $updater->getmeta($filename);\n         }\n \n+        # If -p was given, \"print\" the contents of the requested revision.\n+        if ( exists ( $state->{opt}{p} ) ) {\n+            if ( defined ( $meta->{revision} ) ) {\n+                $log->info(\"Printing '$filename' revision \" . $meta->{revision});\n+\n+                transmitfile($meta->{filehash}, { print => 1 });\n+            }\n+\n+            next;\n+        }\n+\n \tif ( ! defined $meta )\n \t{\n \t    $meta = {\n@@ -1091,9 +1102,9 @@ sub req_update\n             my $file_local = $filepart . \".mine\";\n             system(\"ln\",\"-s\",$state->{entries}{$filename}{modified_filename}, $file_local);\n             my $file_old = $filepart . \".\" . $oldmeta->{revision};\n-            transmitfile($oldmeta->{filehash}, $file_old);\n+            transmitfile($oldmeta->{filehash}, { targetfile => $file_old });\n             my $file_new = $filepart . \".\" . $meta->{revision};\n-            transmitfile($meta->{filehash}, $file_new);\n+            transmitfile($meta->{filehash}, { targetfile => $file_new });\n \n             # we need to merge with the local changes ( M=successful merge, C=conflict merge )\n             $log->info(\"Merging $file_local, $file_old, $file_new\");\n@@ -1550,14 +1561,14 @@ sub req_diff\n                 print \"E File $filename at revision 1.$revision1 doesn't exist\\n\";\n                 next;\n             }\n-            transmitfile($meta1->{filehash}, $file1);\n+            transmitfile($meta1->{filehash}, { targetfile => $file1 });\n         }\n         # otherwise we just use the working copy revision\n         else\n         {\n             ( undef, $file1 ) = tempfile( DIR => $TEMP_DIR, OPEN => 0 );\n             $meta1 = $updater->getmeta($filename, $wrev);\n-            transmitfile($meta1->{filehash}, $file1);\n+            transmitfile($meta1->{filehash}, { targetfile => $file1 });\n         }\n \n         # if we have a second -r switch, use it too\n@@ -1572,7 +1583,7 @@ sub req_diff\n                 next;\n             }\n \n-            transmitfile($meta2->{filehash}, $file2);\n+            transmitfile($meta2->{filehash}, { targetfile => $file2 });\n         }\n         # otherwise we just use the working copy\n         else\n@@ -1585,7 +1596,7 @@ sub req_diff\n         {\n             ( undef, $file2 ) = tempfile( DIR => $TEMP_DIR, OPEN => 0 );\n             $meta2 = $updater->getmeta($filename, $wrev);\n-            transmitfile($meta2->{filehash}, $file2);\n+            transmitfile($meta2->{filehash}, { targetfile => $file2 });\n         }\n \n         # We need to have retrieved something useful\n@@ -2021,7 +2032,7 @@ sub revparse\n sub transmitfile\n {\n     my $filehash = shift;\n-    my $targetfile = shift;\n+    my $options = shift;\n \n     if ( defined ( $filehash ) and $filehash eq \"deleted\" )\n     {\n@@ -2043,11 +2054,20 @@ sub transmitfile\n \n     if ( open my $fh, '-|', \"git-cat-file\", \"blob\", $filehash )\n     {\n-        if ( defined ( $targetfile ) )\n+        if ( defined ( $options->{targetfile} ) )\n         {\n+            my $targetfile = $options->{targetfile};\n             open NEWFILE, \">\", $targetfile or die(\"Couldn't open '$targetfile' for writing : $!\");\n             print NEWFILE $_ while ( <$fh> );\n             close NEWFILE or die(\"Failed to write '$targetfile': $!\");\n+        } elsif ( defined ( $options->{print} ) && $options->{print} ) {\n+            while ( <$fh> ) {\n+                if( /\\n\\z/ ) {\n+                    print 'M ', $_;\n+                } else {\n+                    print 'MT text ', $_, \"\\n\";\n+                }\n+            }\n         } else {\n             print \"$size\\n\";\n             print while ( <$fh> );\n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72973","messageId":"d183368d7796cc28e600a6984954a836dc78d8be.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 6/7] cvsserver: Added test for update -p","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:50:44Z","receivedAt":"2008-03-24T22:50:44Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n t/t9400-git-cvsserver-server.sh |   18 ++++++++++++++++++\n 1 files changed, 18 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh\nindex 6168324..166b43f 100755\n--- a/t/t9400-git-cvsserver-server.sh\n+++ b/t/t9400-git-cvsserver-server.sh\n@@ -420,6 +420,24 @@ test_expect_success 'cvs update (merge no-op)' \\\n     GIT_CONFIG=\"$git_config\" cvs -Q update &&\n     diff -q merge ../merge'\n \n+cd \"$WORKDIR\"\n+test_expect_success 'cvs update (-p)' '\n+    touch really-empty &&\n+    echo Line 1 > no-lf &&\n+    echo -n Line 2 >> no-lf &&\n+    git add really-empty no-lf &&\n+    git commit -q -m \"Update -p test\" &&\n+    git push gitcvs.git >/dev/null &&\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs update &&\n+    rm -f failures &&\n+    for i in merge no-lf empty really-empty; do\n+        GIT_CONFIG=\"$git_config\" cvs update -p \"$i\" >$i.out\n+        diff $i.out ../$i >>failures 2>&1\n+    done &&\n+    test -z \"$(cat failures)\"\n+'\n+\n #------------\n # CVS STATUS\n #------------\n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72975","messageId":"01e5947cde524f4eb97a86785d0e1f28e2d040e0.1206393086.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH 7/7] cvsserver: Use the user part of the email in log and annotate results","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-24T22:50:55Z","receivedAt":"2008-03-24T22:50:55Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"Generate the CVS author names by taking the first eight characters of\nthe user part of the email address.  The resulting names are more\nlikely to make sense (or at least reduce ambiguities) in \"corporate\"\nenvironments.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |   18 ++++++++++++++----\n 1 files changed, 14 insertions(+), 4 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 3c97226..9d845c8 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -1728,8 +1728,7 @@ sub req_log\n             print \"M revision 1.$revision->{revision}\\n\";\n             # reformat the date for log output\n             $revision->{modified} = sprintf('%04d/%02d/%02d %s', $3, $DATE_LIST->{$2}, $1, $4 ) if ( $revision->{modified} =~ /(\\d+)\\s+(\\w+)\\s+(\\d+)\\s+(\\S+)/ and defined($DATE_LIST->{$2}) );\n-            $revision->{author} =~ s/\\s+.*//;\n-            $revision->{author} =~ s/^(.{8}).*/$1/;\n+            $revision->{author} = cvs_author($revision->{author});\n             print \"M date: $revision->{modified};  author: $revision->{author};  state: \" . ( $revision->{filehash} eq \"deleted\" ? \"dead\" : \"Exp\" ) . \";  lines: +2 -3\\n\";\n             my $commitmessage = $updater->commitmessage($revision->{commithash});\n             $commitmessage =~ s/^/M /mg;\n@@ -1844,8 +1843,7 @@ sub req_annotate\n                 unless ( defined ( $metadata->{$commithash} ) )\n                 {\n                     $metadata->{$commithash} = $updater->getmeta($filename, $commithash);\n-                    $metadata->{$commithash}{author} =~ s/\\s+.*//;\n-                    $metadata->{$commithash}{author} =~ s/^(.{8}).*/$1/;\n+                    $metadata->{$commithash}{author} = cvs_author($metadata->{$commithash}{author});\n                     $metadata->{$commithash}{modified} = sprintf(\"%02d-%s-%02d\", $1, $2, $3) if ( $metadata->{$commithash}{modified} =~ /^(\\d+)\\s(\\w+)\\s\\d\\d(\\d\\d)/ );\n                 }\n                 printf(\"M 1.%-5d      (%-8s %10s): %s\\n\",\n@@ -2136,6 +2134,18 @@ sub kopts_from_path\n     }\n }\n \n+# Generate a CVS author name from Git author information, by taking\n+# the first eight characters of the user part of the email address.\n+sub cvs_author\n+{\n+    my $author = shift;\n+\n+    $author =~ s/.*<([^>]+)\\@[^>]+>$/$1/;\n+    $author =~ s/^(.{8}).*/$1/;\n+\n+    $author;\n+}\n+\n package GITCVS::log;\n \n ####\n-- \n1.5.5.rc1.6.gd183\n"},{"id":"72991","messageId":"7vd4pjr4o1.fsf@gitster.siamese.dyndns.org","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"Re: [PATCH 0/7] Enhance TkCVS interoperability","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-25T01:08:46Z","receivedAt":"2008-03-25T01:08:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Damien Diederen <dash@foobox.net> writes:\n\n> This series was developed to improve interoperability between\n> git-cvsserver and TkCVS, a CVS client that is fairly popular at least\n> in some corporate environments.\n>\n> Patches 1-6 are \"obvious\" improvements, implementing missing features\n> or fixing incorrect behaviour.  7 is more questionable, but likely to\n> result in more intelligible log output in a majority of cases.\n\nIf anything, I think 7/7 is an improvement that consolidates a few\nduplicated code that massage authorship information in the commit object\ninto CVS form.  I cannot readily tell what is going on from this old code\nsequence:\n\n-    $metadata->{$commithash}{author} =~ s/\\s+.*//;\n-    $metadata->{$commithash}{author} =~ s/^(.{8}).*/$1/;\n\nbut I can tell what is going on in the latter even without the help from\nthe leading comment.\n\n+# Generate a CVS author name from Git author information, by taking\n+# the first eight characters of the user part of the email address.\n+sub cvs_author\n+{\n+    my $author = shift;\n+\n+    $author =~ s/.*<([^>]+)\\@[^>]+>$/$1/;\n+    $author =~ s/^(.{8}).*/$1/;\n+\n+    $author;\n+}\n\nAnd 1/7-6/7 looked all good, but this is just from _looking_.  I do not\nrun cvsserver myself, so people should take this with a moderate amount of\nsalt.\n\nMartin, Frank?\n"},{"id":"73015","messageId":"20080325090306.GM25732@mail-vs.djpig.de","threadId":"12850","inReplyTo":"8cb3f0ef415bdfe8a25f89fdac3d14d3b8360dcf.1206393086.git.dash@foobox.net","subject":"Re: [PATCH 1/7] cvsserver: Respond to the 'editors' command","fromName":"Frank Lichtenheld","fromEmail":"frank@lichtenheld.de","sentAt":"2008-03-25T09:03:07Z","receivedAt":"2008-03-25T09:03:07Z","isPatch":true,"sender":{"key":"frank@lichtenheld.de","avatar":"https://gravatar.com/avatar/b9f1d4b120e138f157c9e480d0818197c474628923786adb98f30017cdb99c3c?d=mp&s=160"},"body":"On Mon, Mar 24, 2008 at 11:48:52PM +0100, Damien Diederen wrote:\n> \"Cvs editors\" lists the users currently working on watched (locked)\n> files.  This trivial implementation always returns an empty response,\n> since git-cvsserver does not implement file locking.\n\nIt might be nicer to name the function something like req_dummy_response\nand use it for (at least) editors and watchers commands.\n\nGruesse,\n-- \nFrank Lichtenheld <frank@lichtenheld.de>\nwww: http://www.djpig.de/\n"},{"id":"73016","messageId":"20080325092621.GN25732@mail-vs.djpig.de","threadId":"12850","inReplyTo":"01e5947cde524f4eb97a86785d0e1f28e2d040e0.1206393086.git.dash@foobox.net","subject":"Re: [PATCH 7/7] cvsserver: Use the user part of the email in log and annotate results","fromName":"Frank Lichtenheld","fromEmail":"frank@lichtenheld.de","sentAt":"2008-03-25T09:26:21Z","receivedAt":"2008-03-25T09:26:21Z","isPatch":true,"sender":{"key":"frank@lichtenheld.de","avatar":"https://gravatar.com/avatar/b9f1d4b120e138f157c9e480d0818197c474628923786adb98f30017cdb99c3c?d=mp&s=160"},"body":"On Mon, Mar 24, 2008 at 11:50:55PM +0100, Damien Diederen wrote:\n> +# Generate a CVS author name from Git author information, by taking\n> +# the first eight characters of the user part of the email address.\n> +sub cvs_author\n> +{\n> +    my $author = shift;\n> +\n> +    $author =~ s/.*<([^>]+)\\@[^>]+>$/$1/;\n> +    $author =~ s/^(.{8}).*/$1/;\n\nIMHO substr($author, 0, 8) would be easier to read here. (It is also\nmuch faster according to some quick benchmarks I just ran)\n\nGruesse,\n-- \nFrank Lichtenheld <frank@lichtenheld.de>\nwww: http://www.djpig.de/\n"},{"id":"73017","messageId":"b77c1dce0803250239o249a9059sbaafccf9ddea5e22@mail.gmail.com","threadId":"12850","inReplyTo":"20080325092621.GN25732@mail-vs.djpig.de","subject":"Re: [PATCH 7/7] cvsserver: Use the user part of the email in log and annotate results","fromName":"Rafael Garcia-Suarez","fromEmail":"rgarciasuarez@gmail.com","sentAt":"2008-03-25T09:39:08Z","receivedAt":"2008-03-25T09:39:08Z","isPatch":true,"sender":{"key":"rgarciasuarez@gmail.com","avatar":null},"body":"On 25/03/2008, Frank Lichtenheld <frank@lichtenheld.de> wrote:\n> On Mon, Mar 24, 2008 at 11:50:55PM +0100, Damien Diederen wrote:\n>  > +# Generate a CVS author name from Git author information, by taking\n>  > +# the first eight characters of the user part of the email address.\n>  > +sub cvs_author\n>  > +{\n>  > +    my $author = shift;\n>  > +\n>  > +    $author =~ s/.*<([^>]+)\\@[^>]+>$/$1/;\n>  > +    $author =~ s/^(.{8}).*/$1/;\n>\n>\n> IMHO substr($author, 0, 8) would be easier to read here. (It is also\n>  much faster according to some quick benchmarks I just ran)\n\nWhile we're at nitpicking:\nFaster, shorter, and probably more robust if no @ appears in the email address:\n\nmy $author_line = shift;\n(my $author) = $author_line =~ /<([^>@]{1,8})/;\n"},{"id":"73041","messageId":"87myomykg1.fsf@keem.bcc","threadId":"12850","inReplyTo":"b77c1dce0803250239o249a9059sbaafccf9ddea5e22@mail.gmail.com","subject":"Re: [PATCH 7/7] cvsserver: Use the user part of the email in log and annotate results","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-25T13:58:22Z","receivedAt":"2008-03-25T13:58:22Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"\nHi All,\n\n\"Rafael Garcia-Suarez\" <rgarciasuarez@gmail.com> writes:\n> On 25/03/2008, Frank Lichtenheld <frank@lichtenheld.de> wrote:\n>> On Mon, Mar 24, 2008 at 11:50:55PM +0100, Damien Diederen wrote:\n>>  > +# Generate a CVS author name from Git author information, by taking\n>>  > +# the first eight characters of the user part of the email address.\n>>  > +sub cvs_author\n>>  > +{\n>>  > +    my $author = shift;\n>>  > +\n>>  > +    $author =~ s/.*<([^>]+)\\@[^>]+>$/$1/;\n>>  > +    $author =~ s/^(.{8}).*/$1/;\n>>\n>> IMHO substr($author, 0, 8) would be easier to read here. (It is also\n>>  much faster according to some quick benchmarks I just ran)\n>\n> While we're at nitpicking:\n> Faster, shorter, and probably more robust if no @ appears in the email address:\n>\n> my $author_line = shift;\n> (my $author) = $author_line =~ /<([^>@]{1,8})/;\n\nKeep 'em coming :)\n\nI agree with all suggestions so far; I will prepare a new series\naddressing them (and including a minor documentation update) once the\nthread has settled down a bit.\n\n        Damien\n\n-- \nhttp://foobox.net/~dash/\n"},{"id":"73222","messageId":"cover.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 0/7] Enhance TkCVS interoperability","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:17:03Z","receivedAt":"2008-03-27T22:17:03Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"This series was developed to improve interoperability between\ngit-cvsserver and TkCVS, a CVS client that is fairly popular at least\nin some corporate environments.\n\nThis revised version incorporates suggestions from Frank Lichtenheld\nand Rafael Garcia-Suarez, plus a small internal documentation update.\nI have no outstanding changes planned for the near future.  Junio,\nthis can go in as far as I am concerned.\n\n        Damien\n\nDamien Diederen (7):\n  cvsserver: Respond to the 'editors' and 'watchers' commands\n  cvsserver: Only print the file part of the filename in status header\n  cvsserver: Do not include status output for subdirectories if -l is\n    passed\n  cvsserver: Add a few tests for 'status' command\n  cvsserver: Implement update -p (print to stdout)\n  cvsserver: Add test for update -p\n  cvsserver: Use the user part of the email in log and annotate results\n\n git-cvsserver.perl              |   78 +++++++++++++++++++++++++++++---------\n t/t9400-git-cvsserver-server.sh |   50 +++++++++++++++++++++++++\n 2 files changed, 109 insertions(+), 19 deletions(-)\n"},{"id":"73223","messageId":"ade0303c6104ad25bc4d846af2417a994cf9cf46.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 1/7] cvsserver: Respond to the 'editors' and 'watchers' commands","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:17:26Z","receivedAt":"2008-03-27T22:17:26Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"These commands list users editing and watching locked files.  This trivial\nimplementation always returns an empty response, since git-cvsserver does not\nimplement file locking.\n\nWithout this, TkCVS hangs at startup, waiting forever for a response.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |    9 +++++++--\n 1 files changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 7f632af..2fe0a8a 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -73,8 +73,8 @@ my $methods = {\n     'status'          => \\&req_status,\n     'admin'           => \\&req_CATCHALL,\n     'history'         => \\&req_CATCHALL,\n-    'watchers'        => \\&req_CATCHALL,\n-    'editors'         => \\&req_CATCHALL,\n+    'watchers'        => \\&req_EMPTY,\n+    'editors'         => \\&req_EMPTY,\n     'annotate'        => \\&req_annotate,\n     'Global_option'   => \\&req_Globaloption,\n     #'annotate'        => \\&req_CATCHALL,\n@@ -199,6 +199,11 @@ sub req_CATCHALL\n     $log->warn(\"Unhandled command : req_$cmd : $data\");\n }\n \n+# This method invariably succeeds with an empty response.\n+sub req_EMPTY\n+{\n+    print \"ok\\n\";\n+}\n \n # Root pathname \\n\n #     Response expected: no. Tell the server which CVSROOT to use. Note that\n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73224","messageId":"333a7cfa26e71fe42a9b10cd4d7c1a6a5085aacd.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 2/7] cvsserver: Only print the file part of the filename in status header","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:17:42Z","receivedAt":"2008-03-27T22:17:42Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"The \"File:\" header of CVS status output only includes the basename of\nthe file, even when generating a recursive listing; do the same.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |    4 +++-\n 1 files changed, 3 insertions(+), 1 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 2fe0a8a..444ec0d 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -1471,8 +1471,10 @@ sub req_status\n \n         $status ||= \"Unknown\";\n \n+        my ($filepart) = filenamesplit($filename);\n+\n         print \"M ===================================================================\\n\";\n-        print \"M File: $filename\\tStatus: $status\\n\";\n+        print \"M File: $filepart\\tStatus: $status\\n\";\n         if ( defined($state->{entries}{$filename}{revision}) )\n         {\n             print \"M Working revision:\\t\" . $state->{entries}{$filename}{revision} . \"\\n\";\n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73225","messageId":"e9090852dc2f6e0f9aae5f7418b18be24374a4d9.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 3/7] cvsserver: Do not include status output for subdirectories if -l is passed","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:17:53Z","receivedAt":"2008-03-27T22:17:53Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"This effectively implements the -l switch by pruning the entries whose\nfilenames contain a path separator.  It was previously ignored.\n\nWithout this, TkCVS includes strange \"ghost\" entries in its directory\nlistings.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 444ec0d..89a4dac 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -1428,6 +1428,8 @@ sub req_status\n     {\n         $filename = filecleanup($filename);\n \n+        next if exists($state->{opt}{l}) && index($filename, '/', length($state->{prependdir})) >= 0;\n+\n         my $meta = $updater->getmeta($filename);\n         my $oldmeta = $meta;\n \n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73226","messageId":"3bc8d6b298f7111d5ddcc5bfbaf8bab557eaec61.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 4/7] cvsserver: Add a few tests for 'status' command","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:18:02Z","receivedAt":"2008-03-27T22:18:02Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"Signed-off-by: Damien Diederen <dash@foobox.net>\n---\n t/t9400-git-cvsserver-server.sh |   32 ++++++++++++++++++++++++++++++++\n 1 files changed, 32 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh\nindex b91b151..6168324 100755\n--- a/t/t9400-git-cvsserver-server.sh\n+++ b/t/t9400-git-cvsserver-server.sh\n@@ -420,4 +420,36 @@ test_expect_success 'cvs update (merge no-op)' \\\n     GIT_CONFIG=\"$git_config\" cvs -Q update &&\n     diff -q merge ../merge'\n \n+#------------\n+# CVS STATUS\n+#------------\n+\n+cd \"$WORKDIR\"\n+test_expect_success 'cvs status' '\n+    mkdir status.dir &&\n+    echo Line > status.dir/status.file &&\n+    echo Line > status.file &&\n+    git add status.dir status.file &&\n+    git commit -q -m \"Status test\" &&\n+    git push gitcvs.git >/dev/null &&\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs update &&\n+    GIT_CONFIG=\"$git_config\" cvs status | grep \"^File: status.file\" >../out &&\n+    test $(wc -l <../out) = 2\n+'\n+\n+cd \"$WORKDIR\"\n+test_expect_success 'cvs status (nonrecursive)' '\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs status -l | grep \"^File: status.file\" >../out &&\n+    test $(wc -l <../out) = 1\n+'\n+\n+cd \"$WORKDIR\"\n+test_expect_success 'cvs status (no subdirs in header)' '\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs status | grep ^File: >../out &&\n+    ! grep / <../out\n+'\n+\n test_done\n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73227","messageId":"e95fde851fdc6ef39f32054cba6cde0ae975b8fd.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 5/7] cvsserver: Implement update -p (print to stdout)","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:18:12Z","receivedAt":"2008-03-27T22:18:12Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"Cvs update -p -r <rev> <path> is the documented way to retrieve a\nspecific revision of a file (similar to git show <rev>:<path>).\nWithout this patch, the -p flag is ignored and status output is\nproduced, causing clients to interpret it as the contents of the file.\n\nTkCVS uses update -p as a basis for implementing its various \"View\"\nand \"Diff\" commands.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |   47 +++++++++++++++++++++++++++++++++++------------\n 1 files changed, 35 insertions(+), 12 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 89a4dac..49c0ba2 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -963,6 +963,17 @@ sub req_update\n             $meta = $updater->getmeta($filename);\n         }\n \n+        # If -p was given, \"print\" the contents of the requested revision.\n+        if ( exists ( $state->{opt}{p} ) ) {\n+            if ( defined ( $meta->{revision} ) ) {\n+                $log->info(\"Printing '$filename' revision \" . $meta->{revision});\n+\n+                transmitfile($meta->{filehash}, { print => 1 });\n+            }\n+\n+            next;\n+        }\n+\n \tif ( ! defined $meta )\n \t{\n \t    $meta = {\n@@ -1096,9 +1107,9 @@ sub req_update\n             my $file_local = $filepart . \".mine\";\n             system(\"ln\",\"-s\",$state->{entries}{$filename}{modified_filename}, $file_local);\n             my $file_old = $filepart . \".\" . $oldmeta->{revision};\n-            transmitfile($oldmeta->{filehash}, $file_old);\n+            transmitfile($oldmeta->{filehash}, { targetfile => $file_old });\n             my $file_new = $filepart . \".\" . $meta->{revision};\n-            transmitfile($meta->{filehash}, $file_new);\n+            transmitfile($meta->{filehash}, { targetfile => $file_new });\n \n             # we need to merge with the local changes ( M=successful merge, C=conflict merge )\n             $log->info(\"Merging $file_local, $file_old, $file_new\");\n@@ -1550,14 +1561,14 @@ sub req_diff\n                 print \"E File $filename at revision 1.$revision1 doesn't exist\\n\";\n                 next;\n             }\n-            transmitfile($meta1->{filehash}, $file1);\n+            transmitfile($meta1->{filehash}, { targetfile => $file1 });\n         }\n         # otherwise we just use the working copy revision\n         else\n         {\n             ( undef, $file1 ) = tempfile( DIR => $TEMP_DIR, OPEN => 0 );\n             $meta1 = $updater->getmeta($filename, $wrev);\n-            transmitfile($meta1->{filehash}, $file1);\n+            transmitfile($meta1->{filehash}, { targetfile => $file1 });\n         }\n \n         # if we have a second -r switch, use it too\n@@ -1572,7 +1583,7 @@ sub req_diff\n                 next;\n             }\n \n-            transmitfile($meta2->{filehash}, $file2);\n+            transmitfile($meta2->{filehash}, { targetfile => $file2 });\n         }\n         # otherwise we just use the working copy\n         else\n@@ -1585,7 +1596,7 @@ sub req_diff\n         {\n             ( undef, $file2 ) = tempfile( DIR => $TEMP_DIR, OPEN => 0 );\n             $meta2 = $updater->getmeta($filename, $wrev);\n-            transmitfile($meta2->{filehash}, $file2);\n+            transmitfile($meta2->{filehash}, { targetfile => $file2 });\n         }\n \n         # We need to have retrieved something useful\n@@ -2014,14 +2025,17 @@ sub revparse\n     return undef;\n }\n \n-# This method takes a file hash and does a CVS \"file transfer\" which transmits the\n-# size of the file, and then the file contents.\n-# If a second argument $targetfile is given, the file is instead written out to\n-# a file by the name of $targetfile\n+# This method takes a file hash and does a CVS \"file transfer\".  Its\n+# exact behaviour depends on a second, optional hash table argument:\n+# - If $options->{targetfile}, dump the contents to that file;\n+# - If $options->{print}, use M/MT to transmit the contents one line\n+#   at a time;\n+# - Otherwise, transmit the size of the file, followed by the file\n+#   contents.\n sub transmitfile\n {\n     my $filehash = shift;\n-    my $targetfile = shift;\n+    my $options = shift;\n \n     if ( defined ( $filehash ) and $filehash eq \"deleted\" )\n     {\n@@ -2043,11 +2057,20 @@ sub transmitfile\n \n     if ( open my $fh, '-|', \"git-cat-file\", \"blob\", $filehash )\n     {\n-        if ( defined ( $targetfile ) )\n+        if ( defined ( $options->{targetfile} ) )\n         {\n+            my $targetfile = $options->{targetfile};\n             open NEWFILE, \">\", $targetfile or die(\"Couldn't open '$targetfile' for writing : $!\");\n             print NEWFILE $_ while ( <$fh> );\n             close NEWFILE or die(\"Failed to write '$targetfile': $!\");\n+        } elsif ( defined ( $options->{print} ) && $options->{print} ) {\n+            while ( <$fh> ) {\n+                if( /\\n\\z/ ) {\n+                    print 'M ', $_;\n+                } else {\n+                    print 'MT text ', $_, \"\\n\";\n+                }\n+            }\n         } else {\n             print \"$size\\n\";\n             print while ( <$fh> );\n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73228","messageId":"c1b10ec91d678b58e0c5e65b3fbc77a4ed19453a.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 6/7] cvsserver: Add test for update -p","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:18:23Z","receivedAt":"2008-03-27T22:18:23Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"Signed-off-by: Damien Diederen <dash@foobox.net>\n---\n t/t9400-git-cvsserver-server.sh |   18 ++++++++++++++++++\n 1 files changed, 18 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh\nindex 6168324..166b43f 100755\n--- a/t/t9400-git-cvsserver-server.sh\n+++ b/t/t9400-git-cvsserver-server.sh\n@@ -420,6 +420,24 @@ test_expect_success 'cvs update (merge no-op)' \\\n     GIT_CONFIG=\"$git_config\" cvs -Q update &&\n     diff -q merge ../merge'\n \n+cd \"$WORKDIR\"\n+test_expect_success 'cvs update (-p)' '\n+    touch really-empty &&\n+    echo Line 1 > no-lf &&\n+    echo -n Line 2 >> no-lf &&\n+    git add really-empty no-lf &&\n+    git commit -q -m \"Update -p test\" &&\n+    git push gitcvs.git >/dev/null &&\n+    cd cvswork &&\n+    GIT_CONFIG=\"$git_config\" cvs update &&\n+    rm -f failures &&\n+    for i in merge no-lf empty really-empty; do\n+        GIT_CONFIG=\"$git_config\" cvs update -p \"$i\" >$i.out\n+        diff $i.out ../$i >>failures 2>&1\n+    done &&\n+    test -z \"$(cat failures)\"\n+'\n+\n #------------\n # CVS STATUS\n #------------\n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73229","messageId":"f7869cd4f5ed963cbc298ee64b77a43ebd778b0f.1206654905.git.dash@foobox.net","threadId":"12850","inReplyTo":"cover.1206393086.git.dash@foobox.net","subject":"[PATCH v2 7/7] cvsserver: Use the user part of the email in log and annotate results","fromName":"Damien Diederen","fromEmail":"dash@foobox.net","sentAt":"2008-03-27T22:18:35Z","receivedAt":"2008-03-27T22:18:35Z","isPatch":true,"sender":{"key":"dash@foobox.net","avatar":"https://gravatar.com/avatar/43e8b73fd01fd0587aa487caac6bc481a663a09b9d5e884f86c5c5e03530d0e8?d=mp&s=160"},"body":"Generate the CVS author names by taking the first eight characters of\nthe user part of the email address.  The resulting names are more\nlikely to make sense (or at least reduce ambiguities) in \"corporate\"\nenvironments.\n\nSigned-off-by: Damien Diederen <dash@foobox.net>\n---\n git-cvsserver.perl |   16 ++++++++++++----\n 1 files changed, 12 insertions(+), 4 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 49c0ba2..dcca4e7 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -1728,8 +1728,7 @@ sub req_log\n             print \"M revision 1.$revision->{revision}\\n\";\n             # reformat the date for log output\n             $revision->{modified} = sprintf('%04d/%02d/%02d %s', $3, $DATE_LIST->{$2}, $1, $4 ) if ( $revision->{modified} =~ /(\\d+)\\s+(\\w+)\\s+(\\d+)\\s+(\\S+)/ and defined($DATE_LIST->{$2}) );\n-            $revision->{author} =~ s/\\s+.*//;\n-            $revision->{author} =~ s/^(.{8}).*/$1/;\n+            $revision->{author} = cvs_author($revision->{author});\n             print \"M date: $revision->{modified};  author: $revision->{author};  state: \" . ( $revision->{filehash} eq \"deleted\" ? \"dead\" : \"Exp\" ) . \";  lines: +2 -3\\n\";\n             my $commitmessage = $updater->commitmessage($revision->{commithash});\n             $commitmessage =~ s/^/M /mg;\n@@ -1844,8 +1843,7 @@ sub req_annotate\n                 unless ( defined ( $metadata->{$commithash} ) )\n                 {\n                     $metadata->{$commithash} = $updater->getmeta($filename, $commithash);\n-                    $metadata->{$commithash}{author} =~ s/\\s+.*//;\n-                    $metadata->{$commithash}{author} =~ s/^(.{8}).*/$1/;\n+                    $metadata->{$commithash}{author} = cvs_author($metadata->{$commithash}{author});\n                     $metadata->{$commithash}{modified} = sprintf(\"%02d-%s-%02d\", $1, $2, $3) if ( $metadata->{$commithash}{modified} =~ /^(\\d+)\\s(\\w+)\\s\\d\\d(\\d\\d)/ );\n                 }\n                 printf(\"M 1.%-5d      (%-8s %10s): %s\\n\",\n@@ -2139,6 +2137,16 @@ sub kopts_from_path\n     }\n }\n \n+# Generate a CVS author name from Git author information, by taking\n+# the first eight characters of the user part of the email address.\n+sub cvs_author\n+{\n+    my $author_line = shift;\n+    (my $author) = $author_line =~ /<([^>@]{1,8})/;\n+\n+    $author;\n+}\n+\n package GITCVS::log;\n \n ####\n-- \n1.5.5.rc1.19.gfe7681\n"},{"id":"73244","messageId":"7vabkj2slx.fsf@gitster.siamese.dyndns.org","threadId":"12850","inReplyTo":"cover.1206654905.git.dash@foobox.net","subject":"Re: [PATCH v2 0/7] Enhance TkCVS interoperability","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-28T07:52:10Z","receivedAt":"2008-03-28T07:52:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The diff from the v1 patch all makes sense to me.  Thanks.\nI'll queue it for post 1.5.5\n"}]}