Skip to content

Commit

Permalink
cvsserver: nested directory creation fixups for Eclipse clients
Browse files Browse the repository at this point in the history
To create nested directories without (or before) sending file entries
is rather tricky. Most clients just work. Eclipse, however, expects
a very specific sequence of events. With this patch, cvsserver meets
those expectations.

Note: we may want to reuse prepdir() in req_update -- should move it
outside of req_co. Right now prepdir() is tied to how req_co() works.

Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Martin Langhoff authored and Junio C Hamano committed Mar 4, 2006
1 parent be97292 commit 6be32d4
Showing 1 changed file with 56 additions and 17 deletions.
73 changes: 56 additions & 17 deletions git-cvsserver.perl
Original file line number Diff line number Diff line change
Expand Up @@ -579,20 +579,73 @@ sub req_co
print $state->{CVSROOT} . "/$module/\n";
print "Clear-static-directory $checkout_path/\n";
print $state->{CVSROOT} . "/$module/\n";
print "Clear-sticky $checkout_path/\n"; # yes, twice
print $state->{CVSROOT} . "/$module/\n";
print "Template $checkout_path/\n";
print $state->{CVSROOT} . "/$module/\n";
print "0\n";

# instruct the client that we're checking out to $checkout_path
print "E cvs checkout: Updating $checkout_path\n";

my %seendirs = ();
my $lastdir ='';

# recursive
sub prepdir {
my ($dir, $repodir, $remotedir, $seendirs) = @_;
my $parent = dirname($dir);
$dir =~ s|/+$||;
$repodir =~ s|/+$||;
$remotedir =~ s|/+$||;
$parent =~ s|/+$||;
$log->debug("announcedir $dir, $repodir, $remotedir" );

if ($parent eq '.' || $parent eq './') {
$parent = '';
}
# recurse to announce unseen parents first
if (length($parent) && !exists($seendirs->{$parent})) {
prepdir($parent, $repodir, $remotedir, $seendirs);
}
# Announce that we are going to modify at the parent level
if ($parent) {
print "E cvs checkout: Updating $remotedir/$parent\n";
} else {
print "E cvs checkout: Updating $remotedir\n";
}
print "Clear-sticky $remotedir/$parent/\n";
print "$repodir/$parent/\n";

print "Clear-static-directory $remotedir/$dir/\n";
print "$repodir/$dir/\n";
print "Clear-sticky $remotedir/$parent/\n"; # yes, twice
print "$repodir/$parent/\n";
print "Template $remotedir/$dir/\n";
print "$repodir/$dir/\n";
print "0\n";

$seendirs->{$dir} = 1;
}

foreach my $git ( @{$updater->gethead} )
{
# Don't want to check out deleted files
next if ( $git->{filehash} eq "deleted" );

( $git->{name}, $git->{dir} ) = filenamesplit($git->{name});

if (length($git->{dir}) && $git->{dir} ne './'
&& $git->{dir} ne $lastdir ) {
unless (exists($seendirs{$git->{dir}})) {
prepdir($git->{dir}, $state->{CVSROOT} . "/$module/",
$checkout_path, \%seendirs);
$lastdir = $git->{dir};
$seendirs{$git->{dir}} = 1;
}
print "E cvs checkout: Updating /$checkout_path/$git->{dir}\n";
}

# modification time of this file
print "Mod-time $git->{modified}\n";

Expand All @@ -604,24 +657,10 @@ sub req_co
print "M U $checkout_path/$git->{name}\n";
}

if (length($git->{dir}) && $git->{dir} ne './'
&& $git->{dir} ne $lastdir && !exists($seendirs{$git->{dir}})) {

# Eclipse seems to need the Clear-sticky command
# to prepare the 'Entries' file for the new directory.
print "Clear-sticky $checkout_path/$git->{dir}\n";
print $state->{CVSROOT} . "/$module/$git->{dir}\n";
print "Clear-static-directory $checkout_path/$git->{dir}\n";
print $state->{CVSROOT} . "/$module/$git->{dir}\n";
print "E cvs checkout: Updating /$checkout_path/$git->{dir}\n";
$lastdir = $git->{dir};
$seendirs{$git->{dir}} = 1;
}

# instruct client we're sending a file to put in this path
print "Created $checkout_path/" . ( defined ( $git->{dir} ) and $git->{dir} ne "./" ? $git->{dir} . "/" : "" ) . "\n";
# instruct client we're sending a file to put in this path
print "Created $checkout_path/" . ( defined ( $git->{dir} ) and $git->{dir} ne "./" ? $git->{dir} . "/" : "" ) . "\n";

print $state->{CVSROOT} . "/$module/" . ( defined ( $git->{dir} ) and $git->{dir} ne "./" ? $git->{dir} . "/" : "" ) . "$git->{name}\n";
print $state->{CVSROOT} . "/$module/" . ( defined ( $git->{dir} ) and $git->{dir} ne "./" ? $git->{dir} . "/" : "" ) . "$git->{name}\n";

# this is an "entries" line
print "/$git->{name}/1.$git->{revision}///\n";
Expand Down

0 comments on commit 6be32d4

Please sign in to comment.