summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgit-cvsserver.perl221
1 files changed, 139 insertions, 82 deletions
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 2e9b673..f3149bb 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -214,8 +214,7 @@ sub req_Globaloption
{
my ( $cmd, $data ) = @_;
$log->debug("req_Globaloption : $data");
-
- # TODO : is this data useful ???
+ $state->{globaloptions}{$data} = 1;
}
# Valid-responses request-list \n
@@ -267,11 +266,32 @@ sub req_Directory
$state->{localdir} = $data;
$state->{repository} = $repository;
- $state->{directory} = $repository;
- $state->{directory} =~ s/^$state->{CVSROOT}\///;
- $state->{module} = $1 if ($state->{directory} =~ s/^(.*?)(\/|$)//);
+ $state->{path} = $repository;
+ $state->{path} =~ s/^$state->{CVSROOT}\///;
+ $state->{module} = $1 if ($state->{path} =~ s/^(.*?)(\/|$)//);
+ $state->{path} .= "/" if ( $state->{path} =~ /\S/ );
+
+ $state->{directory} = $state->{localdir};
+ $state->{directory} = "" if ( $state->{directory} eq "." );
$state->{directory} .= "/" if ( $state->{directory} =~ /\S/ );
+ if ( not defined($state->{prependdir}) and $state->{localdir} eq "." and $state->{path} =~ /\S/ )
+ {
+ $log->info("Setting prepend to '$state->{path}'");
+ $state->{prependdir} = $state->{path};
+ foreach my $entry ( keys %{$state->{entries}} )
+ {
+ $state->{entries}{$state->{prependdir} . $entry} = $state->{entries}{$entry};
+ delete $state->{entries}{$entry};
+ }
+ }
+
+ if ( defined ( $state->{prependdir} ) )
+ {
+ $log->debug("Prepending '$state->{prependdir}' to state|directory");
+ $state->{directory} = $state->{prependdir} . $state->{directory}
+ }
+
$log->debug("req_Directory : localdir=$data repository=$repository directory=$state->{directory} module=$state->{module}");
}
@@ -290,7 +310,7 @@ sub req_Entry
{
my ( $cmd, $data ) = @_;
- $log->debug("req_Entry : $data");
+ #$log->debug("req_Entry : $data");
my @data = split(/\//, $data);
@@ -300,6 +320,22 @@ sub req_Entry
options => $data[4],
tag_or_date => $data[5],
};
+
+ $log->info("Received entry line '$data' => '" . $state->{directory} . $data[1] . "'");
+}
+
+# Questionable filename \n
+# Response expected: no. Additional data: no. Tell the server to check
+# whether filename should be ignored, and if not, next time the server
+# sends responses, send (in a M response) `?' followed by the directory and
+# filename. filename must not contain `/'; it needs to be a file in the
+# directory named by the most recent Directory request.
+sub req_Questionable
+{
+ my ( $cmd, $data ) = @_;
+
+ $log->debug("req_Questionable : $data");
+ $state->{entries}{$state->{directory}.$data}{questionable} = 1;
}
# add \n
@@ -332,8 +368,7 @@ sub req_add
next;
}
-
- my ( $filepart, $dirpart ) = filenamesplit($filename);
+ my ( $filepart, $dirpart ) = filenamesplit($filename, 1);
print "E cvs add: scheduling file `$filename' for addition\n";
@@ -414,7 +449,7 @@ sub req_remove
}
- my ( $filepart, $dirpart ) = filenamesplit($filename);
+ my ( $filepart, $dirpart ) = filenamesplit($filename, 1);
print "E cvs remove: scheduling `$filename' for removal\n";
@@ -502,22 +537,6 @@ sub req_Unchanged
#$log->debug("req_Unchanged : $data");
}
-# Questionable filename \n
-# Response expected: no. Additional data: no.
-# Tell the server to check whether filename should be ignored,
-# and if not, next time the server sends responses, send (in
-# a M response) `?' followed by the directory and filename.
-# filename must not contain `/'; it needs to be a file in the
-# directory named by the most recent Directory request.
-sub req_Questionable
-{
- my ( $cmd, $data ) = @_;
-
- $state->{entries}{$state->{directory}.$data}{questionable} = 1;
-
- #$log->debug("req_Questionable : $data");
-}
-
# Argument text \n
# Response expected: no. Save argument for use in a subsequent command.
# Arguments accumulate until an argument-using command is given, at which
@@ -757,8 +776,7 @@ sub req_update
$updater->update();
- # if no files were specified, we need to work out what files we should be providing status on ...
- argsfromdir($updater) if ( scalar ( @{$state->{args}} ) == 0 );
+ argsfromdir($updater);
#$log->debug("update state : " . Dumper($state));
@@ -767,6 +785,8 @@ sub req_update
{
$filename = filecleanup($filename);
+ $log->debug("Processing file $filename");
+
# if we have a -C we should pretend we never saw modified stuff
if ( exists ( $state->{opt}{C} ) )
{
@@ -821,13 +841,16 @@ sub req_update
if ( $meta->{filehash} eq "deleted" )
{
- my ( $filepart, $dirpart ) = filenamesplit($filename);
+ my ( $filepart, $dirpart ) = filenamesplit($filename,1);
$log->info("Removing '$filename' from working copy (no longer in the repo)");
print "E cvs update: `$filename' is no longer in the repository\n";
- print "Removed $dirpart\n";
- print "$filepart\n";
+ # Don't want to actually _DO_ the update if -n specified
+ unless ( $state->{globaloptions}{-n} ) {
+ print "Removed $dirpart\n";
+ print "$filepart\n";
+ }
}
elsif ( not defined ( $state->{entries}{$filename}{modified_hash} )
or $state->{entries}{$filename}{modified_hash} eq $oldmeta->{filehash} )
@@ -840,34 +863,42 @@ sub req_update
print "MT newline\n";
print "MT -updated\n";
- my ( $filepart, $dirpart ) = filenamesplit($filename);
- $dirpart =~ s/^$state->{directory}//;
-
- if ( defined ( $wrev ) )
- {
- # instruct client we're sending a file to put in this path as a replacement
- print "Update-existing $dirpart\n";
- $log->debug("Updating existing file 'Update-existing $dirpart'");
- } else {
- # instruct client we're sending a file to put in this path as a new file
- print "Created $dirpart\n";
- $log->debug("Creating new file 'Created $dirpart'");
- }
- print $state->{CVSROOT} . "/$state->{module}/$filename\n";
-
- # this is an "entries" line
- $log->debug("/$filepart/1.$meta->{revision}///");
- print "/$filepart/1.$meta->{revision}///\n";
-
- # permissions
- $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}");
- print "u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}\n";
-
- # transmit file
- transmitfile($meta->{filehash});
+ my ( $filepart, $dirpart ) = filenamesplit($filename,1);
+
+ # Don't want to actually _DO_ the update if -n specified
+ unless ( $state->{globaloptions}{-n} )
+ {
+ if ( defined ( $wrev ) )
+ {
+ # instruct client we're sending a file to put in this path as a replacement
+ print "Update-existing $dirpart\n";
+ $log->debug("Updating existing file 'Update-existing $dirpart'");
+ } else {
+ # instruct client we're sending a file to put in this path as a new file
+ print "Clear-static-directory $dirpart\n";
+ print $state->{CVSROOT} . "/$state->{module}/$dirpart\n";
+ print "Clear-sticky $dirpart\n";
+ print $state->{CVSROOT} . "/$state->{module}/$dirpart\n";
+
+ $log->debug("Creating new file 'Created $dirpart'");
+ print "Created $dirpart\n";
+ }
+ print $state->{CVSROOT} . "/$state->{module}/$filename\n";
+
+ # this is an "entries" line
+ $log->debug("/$filepart/1.$meta->{revision}///");
+ print "/$filepart/1.$meta->{revision}///\n";
+
+ # permissions
+ $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}");
+ print "u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}\n";
+
+ # transmit file
+ transmitfile($meta->{filehash});
+ }
} else {
$log->info("Updating '$filename'");
- my ( $filepart, $dirpart ) = filenamesplit($meta->{name});
+ my ( $filepart, $dirpart ) = filenamesplit($meta->{name},1);
my $dir = tempdir( DIR => $TEMP_DIR, CLEANUP => 1 ) . "/";
@@ -892,19 +923,29 @@ sub req_update
$log->info("Merged successfully");
print "M M $filename\n";
$log->debug("Update-existing $dirpart");
- print "Update-existing $dirpart\n";
- $log->debug($state->{CVSROOT} . "/$state->{module}/$filename");
- print $state->{CVSROOT} . "/$state->{module}/$filename\n";
- $log->debug("/$filepart/1.$meta->{revision}///");
- print "/$filepart/1.$meta->{revision}///\n";
+
+ # Don't want to actually _DO_ the update if -n specified
+ unless ( $state->{globaloptions}{-n} )
+ {
+ print "Update-existing $dirpart\n";
+ $log->debug($state->{CVSROOT} . "/$state->{module}/$filename");
+ print $state->{CVSROOT} . "/$state->{module}/$filename\n";
+ $log->debug("/$filepart/1.$meta->{revision}///");
+ print "/$filepart/1.$meta->{revision}///\n";
+ }
}
elsif ( $return == 1 )
{
$log->info("Merged with conflicts");
print "M C $filename\n";
- print "Update-existing $dirpart\n";
- print $state->{CVSROOT} . "/$state->{module}/$filename\n";
- print "/$filepart/1.$meta->{revision}/+//\n";
+
+ # Don't want to actually _DO_ the update if -n specified
+ unless ( $state->{globaloptions}{-n} )
+ {
+ print "Update-existing $dirpart\n";
+ print $state->{CVSROOT} . "/$state->{module}/$filename\n";
+ print "/$filepart/1.$meta->{revision}/+//\n";
+ }
}
else
{
@@ -912,17 +953,21 @@ sub req_update
next;
}
- # permissions
- $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}");
- print "u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}\n";
-
- # transmit file, format is single integer on a line by itself (file
- # size) followed by the file contents
- # TODO : we should copy files in blocks
- my $data = `cat $file_local`;
- $log->debug("File size : " . length($data));
- print length($data) . "\n";
- print $data;
+ # Don't want to actually _DO_ the update if -n specified
+ unless ( $state->{globaloptions}{-n} )
+ {
+ # permissions
+ $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}");
+ print "u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}\n";
+
+ # transmit file, format is single integer on a line by itself (file
+ # size) followed by the file contents
+ # TODO : we should copy files in blocks
+ my $data = `cat $file_local`;
+ $log->debug("File size : " . length($data));
+ print length($data) . "\n";
+ print $data;
+ }
chdir "/";
}
@@ -990,6 +1035,7 @@ sub req_ci
# foreach file specified on the commandline ...
foreach my $filename ( @{$state->{args}} )
{
+ my $committedfile = $filename;
$filename = filecleanup($filename);
next unless ( exists $state->{entries}{$filename}{modified_filename} or not $state->{entries}{$filename}{unchanged} );
@@ -1024,7 +1070,7 @@ sub req_ci
exit;
}
- push @committedfiles, $filename;
+ push @committedfiles, $committedfile;
$log->info("Committing $filename");
system("mkdir","-p",$dirpart) unless ( -d $dirpart );
@@ -1107,7 +1153,7 @@ sub req_ci
my $meta = $updater->getmeta($filename);
- my ( $filepart, $dirpart ) = filenamesplit($filename);
+ my ( $filepart, $dirpart ) = filenamesplit($filename, 1);
$log->debug("Checked-in $dirpart : $filename");
@@ -1143,7 +1189,7 @@ sub req_status
$updater->update();
# if no files were specified, we need to work out what files we should be providing status on ...
- argsfromdir($updater) if ( scalar ( @{$state->{args}} ) == 0 );
+ argsfromdir($updater);
# foreach file specified on the commandline ...
foreach my $filename ( @{$state->{args}} )
@@ -1244,7 +1290,7 @@ sub req_diff
$updater->update();
# if no files were specified, we need to work out what files we should be providing status on ...
- argsfromdir($updater) if ( scalar ( @{$state->{args}} ) == 0 );
+ argsfromdir($updater);
# foreach file specified on the commandline ...
foreach my $filename ( @{$state->{args}} )
@@ -1386,7 +1432,7 @@ sub req_log
$updater->update();
# if no files were specified, we need to work out what files we should be providing status on ...
- argsfromdir($updater) if ( scalar ( @{$state->{args}} ) == 0 );
+ argsfromdir($updater);
# foreach file specified on the commandline ...
foreach my $filename ( @{$state->{args}} )
@@ -1462,7 +1508,7 @@ sub req_annotate
$updater->update();
# if no files were specified, we need to work out what files we should be providing annotate on ...
- argsfromdir($updater) if ( scalar ( @{$state->{args}} ) == 0 );
+ argsfromdir($updater);
# we'll need a temporary checkout dir
my $tmpdir = tempdir ( DIR => $TEMP_DIR );
@@ -1657,6 +1703,12 @@ sub argsfromdir
{
my $updater = shift;
+ $state->{args} = [] if ( scalar(@{$state->{args}}) == 1 and $state->{args}[0] eq "." );
+
+ return if ( scalar ( @{$state->{args}} ) > 0 );
+
+ $log->info("No args specified, populating file list automatically");
+
$state->{args} = [];
foreach my $file ( @{$updater->gethead} )
@@ -1738,11 +1790,17 @@ sub transmitfile
sub filenamesplit
{
my $filename = shift;
+ my $fixforlocaldir = shift;
my ( $filepart, $dirpart ) = ( $filename, "." );
( $filepart, $dirpart ) = ( $2, $1 ) if ( $filename =~ /(.*)\/(.*)/ );
$dirpart .= "/";
+ if ( $fixforlocaldir )
+ {
+ $dirpart =~ s/^$state->{prependdir}//;
+ }
+
return ( $filepart, $dirpart );
}
@@ -1759,7 +1817,6 @@ sub filecleanup
$filename =~ s/^\.\///g;
$filename = $state->{directory} . $filename;
-
return $filename;
}