1983
1984
# get HEAD ref of given project as hash
1985
sub git_get_head_hash {
1986
- my $project = shift;
1986
+ return git_get_full_hash(shift, 'HEAD');
1987
+}
1988
+
1989
+sub git_get_full_hash {
1990
+ return git_get_hash(@_);
1991
+}
1992
+
1993
+sub git_get_short_hash {
1994
+ return git_get_hash(@_, '--short=7');
1995
+}
1996
+
1997
+sub git_get_hash {
1998
+ my ($project, $hash, @options) = @_;
1999
my $o_git_dir = $git_dir;
2000
my $retval = undef;
2001
$git_dir = "$projectroot/$project";
1990
- if (open my $fd, "-|", git_cmd(), "rev-parse", "--verify", "HEAD") {
1991
- my $head = <$fd>;
2002
+ if (open my $fd, '-|', git_cmd(), 'rev-parse',
2003
+ '--verify', '-q', @options, $hash) {
2004
+ $retval = <$fd>;
2005
+ chomp $retval if defined $retval;
2006
close $fd;
1993
- if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) {
1994
- $retval = $1;
1995
- }
2007
}
2008
if (defined $o_git_dir) {
2009
$git_dir = $o_git_dir;
5190
git_footer_html();
5191
}
5192
5193
+sub snapshot_name {
5194
+ my ($project, $hash) = @_;
5195
+
5196
+ # path/to/project.git -> project
5197
+ # path/to/project/.git -> project
5198
+ my $name = to_utf8($project);
5199
+ $name =~ s,([^/])/*\.git$,$1,;
5200
+ $name = basename($name);
5201
+ # sanitize name
5202
+ $name =~ s/[[:cntrl:]]/?/g;
5203
+
5204
+ my $ver = $hash;
5205
+ if ($hash =~ /^[0-9a-fA-F]+$/) {
5206
+ # shorten SHA-1 hash
5207
+ my $full_hash = git_get_full_hash($project, $hash);
5208
+ if ($full_hash =~ /^$hash/ && length($hash) > 7) {
5209
+ $ver = git_get_short_hash($project, $hash);
5210
+ }
5211
+ } elsif ($hash =~ m!^refs/tags/(.*)$!) {
5212
+ # tags don't need shortened SHA-1 hash
5213
+ $ver = $1;
5214
+ } else {
5215
+ # branches and other need shortened SHA-1 hash
5216
+ if ($hash =~ m!^refs/(?:heads|remotes)/(.*)$!) {
5217
+ $ver = $1;
5218
+ }
5219
+ $ver .= '-' . git_get_short_hash($project, $hash);
5220
+ }
5221
+ # in case of hierarchical branch names
5222
+ $ver =~ s!/!.!g;
5223
+
5224
+ # name = project-version_string
5225
+ $name = "$name-$ver";
5226
+
5227
+ return wantarray ? ($name, $name) : $name;
5228
+}
5229
+
5230
sub git_snapshot {
5231
my $format = $input_params{'snapshot_format'};
5232
if (!@snapshot_fmts) {
5251
die_error(400, 'Object is not a tree-ish');
5252
}
5253
5206
- my $name = $project;
5207
- $name =~ s,([^/])/*\.git$,$1,;
5208
- $name = basename($name);
5209
- my $filename = to_utf8($name);
5210
- $name =~ s/\047/\047\\\047\047/g;
5211
- my $cmd;
5212
- $filename .= "-$hash$known_snapshot_formats{$format}{'suffix'}";
5213
- $cmd = quote_command(
5254
+ my ($name, $prefix) = snapshot_name($project, $hash);
5255
+ my $filename = "$name$known_snapshot_formats{$format}{'suffix'}";
5256
+ my $cmd = quote_command(
5257
git_cmd(), 'archive',
5258
"--format=$known_snapshot_formats{$format}{'format'}",
5216
- "--prefix=$name/", $hash);
5259
+ "--prefix=$prefix/", $hash);
5260
if (exists $known_snapshot_formats{$format}{'compressor'}) {
5261
$cmd .= ' | ' . quote_command(@{$known_snapshot_formats{$format}{'compressor'}});
5262
}
5263
5264
+ $filename =~ s/(["\\])/\\$1/g;
5265
print $cgi->header(
5266
-type => $known_snapshot_formats{$format}{'type'},
5223
- -content_disposition => 'inline; filename="' . "$filename" . '"',
5267
+ -content_disposition => 'inline; filename="' . $filename . '"',
5268
-status => '200 OK');
5269
5270
open my $fd, "-|", $cmd