Skip to content

Commit

Permalink
implement gitcvs.usecrlfattr
Browse files Browse the repository at this point in the history
If gitcvs.usecrlfattr is set to true, git-cvsserver will consult
the "crlf" for each file to determine if it should mark the file
as binary (-kb).

Signed-off-by: Matthew Ogilvie <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
Matthew Ogilvie authored and gitster committed May 16, 2008
1 parent 044182e commit 8a06a63
Show file tree
Hide file tree
Showing 4 changed files with 276 additions and 22 deletions.
23 changes: 17 additions & 6 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -660,11 +660,21 @@ gitcvs.logfile::
Path to a log file where the CVS server interface well... logs
various stuff. See linkgit:git-cvsserver[1].

gitcvs.usecrlfattr
If true, the server will look up the `crlf` attribute for
files to determine the '-k' modes to use. If `crlf` is set,
the '-k' mode will be left blank, so cvs clients will
treat it as text. If `crlf` is explicitly unset, the file
will be set with '-kb' mode, which supresses any newline munging
the client might otherwise do. If `crlf` is not specified,
then 'gitcvs.allbinary' is used. See linkgit:gitattribute[5].

gitcvs.allbinary::
If true, all files are sent to the client in mode '-kb'. This
causes the client to treat all files as binary files which suppresses
any newline munging it otherwise might do. A work-around for the
fact that there is no way yet to set single files to mode '-kb'.
If true, all files not otherwise specified using
'gitcvs.usecrlfattr' and an explicitly set or unset `crlf`
attribute are sent to the client in mode '-kb'. This
causes the client to treat them as binary files which
suppresses any newline munging it otherwise might do.

gitcvs.dbname::
Database used by git-cvsserver to cache revision information
Expand Down Expand Up @@ -695,8 +705,9 @@ gitcvs.dbTableNamePrefix::
linkgit:git-cvsserver[1] for details). Any non-alphabetic
characters will be replaced with underscores.

All gitcvs variables except for 'gitcvs.allbinary' can also be
specified as 'gitcvs.<access_method>.<varname>' (where 'access_method'
All gitcvs variables except for 'gitcvs.usecrlfattr' and
'gitcvs.allbinary' can also be specified as
'gitcvs.<access_method>.<varname>' (where 'access_method'
is one of "ext" and "pserver") to make them apply only for the given
access method.

Expand Down
26 changes: 21 additions & 5 deletions Documentation/git-cvsserver.txt
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,27 @@ checkout, diff, status, update, log, add, remove, commit.
Legacy monitoring operations are not supported (edit, watch and related).
Exports and tagging (tags and branches) are not supported at this stage.

The server should set the '-k' mode to binary when relevant, however,
this is not really implemented yet. For now, you can force the server
to set '-kb' for all files by setting the `gitcvs.allbinary` config
variable. In proper GIT tradition, the contents of the files are
always respected. No keyword expansion or newline munging is supported.
CRLF Line Ending Conversions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default the server leaves the '-k' mode blank for all files,
which causes the cvs client to treat them as a text files, subject
to crlf conversion on some platforms.

You can make the server use `crlf` attributes to set the '-k' modes
for files by setting the `gitcvs.usecrlfattr` config variable.
In this case, if `crlf` is explicitly unset ('-crlf'), then the
will set '-kb' mode, for binary files. If it `crlf` is set,
then the '-k' mode will explicitly be left blank. See
also linkgit:gitattributes[5] for more information about the `crlf`
attribute.

Alternatively, if `gitcvs.usecrlfattr` config is not enabled
or if the `crlf` attribute is unspecified for a filename, then
the server uses the `gitcvs.allbinary` for the default setting.
If `gitcvs.allbinary` is set, then the files not otherwise
specified will default to '-kb' mode. Otherwise the '-k' mode
is left blank.

Dependencies
------------
Expand Down
71 changes: 60 additions & 11 deletions git-cvsserver.perl
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ sub req_add
print $state->{CVSROOT} . "/$state->{module}/$filename\n";

# this is an "entries" line
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path($filename);
$log->debug("/$filepart/1.$meta->{revision}//$kopts/");
print "/$filepart/1.$meta->{revision}//$kopts/\n";
# permissions
Expand Down Expand Up @@ -533,9 +533,25 @@ sub req_add

print "Checked-in $dirpart\n";
print "$filename\n";
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path($filename);
print "/$filepart/0//$kopts/\n";

my $requestedKopts = $state->{opt}{k};
if(defined($requestedKopts))
{
$requestedKopts = "-k$requestedKopts";
}
else
{
$requestedKopts = "";
}
if( $kopts ne $requestedKopts )
{
$log->warn("Ignoring requested -k='$requestedKopts'"
. " for '$filename'; detected -k='$kopts' instead");
#TODO: Also have option to send warning to user?
}

$addcount++;
}

Expand Down Expand Up @@ -615,7 +631,7 @@ sub req_remove

print "Checked-in $dirpart\n";
print "$filename\n";
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path($filename);
print "/$filepart/-1.$wrev//$kopts/\n";

$rmcount++;
Expand Down Expand Up @@ -785,6 +801,7 @@ sub req_co
argsplit("co");

my $module = $state->{args}[0];
$state->{module} = $module;
my $checkout_path = $module;

# use the user specified directory if we're given it
Expand Down Expand Up @@ -862,6 +879,7 @@ sub req_co
# Don't want to check out deleted files
next if ( $git->{filehash} eq "deleted" );

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

if (length($git->{dir}) && $git->{dir} ne './'
Expand Down Expand Up @@ -892,7 +910,7 @@ sub req_co
print $state->{CVSROOT} . "/$module/" . ( defined ( $git->{dir} ) and $git->{dir} ne "./" ? $git->{dir} . "/" : "" ) . "$git->{name}\n";

# this is an "entries" line
my $kopts = kopts_from_path($git->{name});
my $kopts = kopts_from_path($fullName);
print "/$git->{name}/1.$git->{revision}//$kopts/\n";
# permissions
print "u=$git->{mode},g=$git->{mode},o=$git->{mode}\n";
Expand Down Expand Up @@ -1101,7 +1119,7 @@ sub req_update
print $state->{CVSROOT} . "/$state->{module}/$filename\n";

# this is an "entries" line
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path($filename);
$log->debug("/$filepart/1.$meta->{revision}//$kopts/");
print "/$filepart/1.$meta->{revision}//$kopts/\n";

Expand Down Expand Up @@ -1149,7 +1167,7 @@ sub req_update
print "Merged $dirpart\n";
$log->debug($state->{CVSROOT} . "/$state->{module}/$filename");
print $state->{CVSROOT} . "/$state->{module}/$filename\n";
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path("$dirpart/$filepart");
$log->debug("/$filepart/1.$meta->{revision}//$kopts/");
print "/$filepart/1.$meta->{revision}//$kopts/\n";
}
Expand All @@ -1165,7 +1183,7 @@ sub req_update
{
print "Merged $dirpart\n";
print $state->{CVSROOT} . "/$state->{module}/$filename\n";
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path("$dirpart/$filepart");
print "/$filepart/1.$meta->{revision}/+/$kopts/\n";
}
}
Expand Down Expand Up @@ -1416,7 +1434,7 @@ sub req_ci
}
print "Checked-in $dirpart\n";
print "$filename\n";
my $kopts = kopts_from_path($filepart);
my $kopts = kopts_from_path($filename);
print "/$filepart/1.$meta->{revision}//$kopts/\n";
}
}
Expand Down Expand Up @@ -2296,10 +2314,24 @@ sub kopts_from_path
{
my ($path) = @_;

# Once it exists, the git attributes system should be used to look up
# what attributes apply to this path.
if ( defined ( $cfg->{gitcvs}{usecrlfattr} ) and
$cfg->{gitcvs}{usecrlfattr} =~ /\s*(1|true|yes)\s*$/i )
{
my ($val) = check_attr( "crlf", $path );
if ( $val eq "set" )
{
return "";
}
elsif ( $val eq "unset" )
{
return "-kb"
}
else
{
$log->info("Unrecognized check_attr crlf $path : $val");
}
}

# Until then, take the setting from the config file
unless ( defined ( $cfg->{gitcvs}{allbinary} ) and $cfg->{gitcvs}{allbinary} =~ /^\s*(1|true|yes)\s*$/i )
{
# Return "" to give no special treatment to any path
Expand All @@ -2311,6 +2343,23 @@ sub kopts_from_path
}
}

sub check_attr
{
my ($attr,$path) = @_;
ensureWorkTree();
if ( open my $fh, '-|', "git", "check-attr", $attr, "--", $path )
{
my $val = <$fh>;
close $fh;
$val =~ s/.*: ([^:\r\n]*)\s*$/$1/;
return $val;
}
else
{
return undef;
}
}

# Generate a CVS author name from Git author information, by taking
# the first eight characters of the user part of the email address.
sub cvs_author
Expand Down
Loading

0 comments on commit 8a06a63

Please sign in to comment.