{"thread":{"id":"3546","subject":"[PATCH] cvsserver: nested directory creation fixups for Eclipse clients","startedAt":"2006-03-04T04:47:29Z","lastAt":"2006-03-04T04:47:29Z","messageCount":1,"participants":["Martin Langhoff"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"17134","messageId":"1141447649849-git-send-email-martin@catalyst.net.nz","threadId":"3546","inReplyTo":null,"subject":"[PATCH] cvsserver: nested directory creation fixups for Eclipse clients","fromName":"Martin Langhoff","fromEmail":"martin@catalyst.net.nz","sentAt":"2006-03-04T04:47:29Z","receivedAt":"2006-03-04T04:47:29Z","isPatch":true,"sender":{"key":"martin@laptop.org","avatar":null},"body":"To create nested directories without (or before) sending file entries\nis rather tricky. Most clients just work. Eclipse, however, expects\na very specific sequence of events. With this patch, cvsserver meets\nthose expectations.\n\nNote: we may want to reuse prepdir() in req_update -- should move it\noutside of req_co. Right now prepdir() is tied to how req_co() works.\n\n---\n\n git-cvsserver.perl |   73 ++++++++++++++++++++++++++++++++++++++++------------\n 1 files changed, 56 insertions(+), 17 deletions(-)\n\n701168bf1ddad1dbc3788e58181589dc082ce536\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex ab32d3e..b450792 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -592,6 +592,11 @@ sub req_co\n     print $state->{CVSROOT} . \"/$module/\\n\";\n     print \"Clear-static-directory $checkout_path/\\n\";\n     print $state->{CVSROOT} . \"/$module/\\n\";\n+    print \"Clear-sticky $checkout_path/\\n\"; # yes, twice\n+    print $state->{CVSROOT} . \"/$module/\\n\";\n+    print \"Template $checkout_path/\\n\";\n+    print $state->{CVSROOT} . \"/$module/\\n\";\n+    print \"0\\n\";\n \n     # instruct the client that we're checking out to $checkout_path\n     print \"E cvs checkout: Updating $checkout_path\\n\";\n@@ -599,6 +604,43 @@ sub req_co\n     my %seendirs = ();\n     my $lastdir ='';\n \n+    # recursive\n+    sub prepdir {\n+       my ($dir, $repodir, $remotedir, $seendirs) = @_;\n+       my $parent = dirname($dir);\n+       $dir       =~ s|/+$||;\n+       $repodir   =~ s|/+$||;\n+       $remotedir =~ s|/+$||;\n+       $parent    =~ s|/+$||;\n+       $log->debug(\"announcedir $dir, $repodir, $remotedir\" );\n+\n+       if ($parent eq '.' || $parent eq './') {\n+           $parent = '';\n+       }\n+       # recurse to announce unseen parents first\n+       if (length($parent) && !exists($seendirs->{$parent})) {\n+           prepdir($parent, $repodir, $remotedir, $seendirs);\n+       }\n+       # Announce that we are going to modify at the parent level\n+       if ($parent) {\n+           print \"E cvs checkout: Updating $remotedir/$parent\\n\";\n+       } else {\n+           print \"E cvs checkout: Updating $remotedir\\n\";\n+       }\n+       print \"Clear-sticky $remotedir/$parent/\\n\";\n+       print \"$repodir/$parent/\\n\";\n+\n+       print \"Clear-static-directory $remotedir/$dir/\\n\";\n+       print \"$repodir/$dir/\\n\";\n+       print \"Clear-sticky $remotedir/$parent/\\n\"; # yes, twice\n+       print \"$repodir/$parent/\\n\";\n+       print \"Template $remotedir/$dir/\\n\";\n+       print \"$repodir/$dir/\\n\";\n+       print \"0\\n\";\n+\n+       $seendirs->{$dir} = 1;\n+    }\n+\n     foreach my $git ( @{$updater->gethead} )\n     {\n         # Don't want to check out deleted files\n@@ -606,6 +648,17 @@ sub req_co\n \n         ( $git->{name}, $git->{dir} ) = filenamesplit($git->{name});\n \n+       if (length($git->{dir}) && $git->{dir} ne './'\n+           && $git->{dir} ne $lastdir ) {\n+           unless (exists($seendirs{$git->{dir}})) {\n+               prepdir($git->{dir}, $state->{CVSROOT} . \"/$module/\",\n+                       $checkout_path, \\%seendirs);\n+               $lastdir = $git->{dir};\n+               $seendirs{$git->{dir}} = 1;\n+           }\n+           print \"E cvs checkout: Updating /$checkout_path/$git->{dir}\\n\";\n+       }\n+\n         # modification time of this file\n         print \"Mod-time $git->{modified}\\n\";\n \n@@ -617,24 +670,10 @@ sub req_co\n             print \"M U $checkout_path/$git->{name}\\n\";\n         }\n \n-\tif (length($git->{dir}) && $git->{dir} ne './' \n-\t    && $git->{dir} ne $lastdir && !exists($seendirs{$git->{dir}})) {\n-\n-\t    # Eclipse seems to need the Clear-sticky command\n-\t    # to prepare the 'Entries' file for the new directory.\n-\t    print \"Clear-sticky $checkout_path/$git->{dir}\\n\";\n-\t    print $state->{CVSROOT} . \"/$module/$git->{dir}\\n\";\n-\t    print \"Clear-static-directory $checkout_path/$git->{dir}\\n\";\n-\t    print $state->{CVSROOT} . \"/$module/$git->{dir}\\n\";\n-\t    print \"E cvs checkout: Updating /$checkout_path/$git->{dir}\\n\";\n-\t    $lastdir = $git->{dir};\n-\t    $seendirs{$git->{dir}} = 1;\n-\t}\n-\n-        # instruct client we're sending a file to put in this path\n-        print \"Created $checkout_path/\" . ( defined ( $git->{dir} ) and $git->{dir} ne \"./\" ? $git->{dir} . \"/\" : \"\" ) . \"\\n\";\n+       # instruct client we're sending a file to put in this path\n+       print \"Created $checkout_path/\" . ( defined ( $git->{dir} ) and $git->{dir} ne \"./\" ? $git->{dir} . \"/\" : \"\" ) . \"\\n\";\n \n-        print $state->{CVSROOT} . \"/$module/\" . ( defined ( $git->{dir} ) and $git->{dir} ne \"./\" ? $git->{dir} . \"/\" : \"\" ) . \"$git->{name}\\n\";\n+       print $state->{CVSROOT} . \"/$module/\" . ( defined ( $git->{dir} ) and $git->{dir} ne \"./\" ? $git->{dir} . \"/\" : \"\" ) . \"$git->{name}\\n\";\n \n         # this is an \"entries\" line\n         print \"/$git->{name}/1.$git->{revision}///\\n\";\n-- \n1.2.4.g09a27-dirty\n"}]}