子目录的gitweb快照

时间:2013-01-21 18:01:50

标签: git archive snapshot subdirectory gitweb

调用网址http://<gitweburl>/gitweb.cgi?p=<repo>;a=tree;f=<subdir>;hb=HEAD会显示从<repo>开始的<subdir>树。

调用网址http://<gitweburl>/gitweb.cgi?p=<repo>;a=snapshot;f=<subdir>;hb=HEAD将生成404。

调用网址http://<gitweburl>/gitweb.cgi?p=<repo>.git;a=snapshot;h=HEAD将在HEAD修订版中提供<repo>的快照。

我无法找到正确的语法使Gitweb从子目录开始提供快照。我的意思是导致:$ git archive --format=tar --remote=<gituser>@<gitserver>:<repo> HEAD:<subdir>

我天真地尝试调用URL http://<gitweburl>/gitweb.cgi?p=<repo>;a=snapshot;h=HEAD;f=<subdir>,但导致包含整个存储库的快照存档

在Gitweb网页界面中点击后,我发现,更改为“树”视图并移至<subdir>然后点击“快照”会使用与此类似的网址:

http://<gitweburl>?p=<repo>;a=snapshot;h=42a6503da6aaedc92bb3543e0b0de9b2de0aaae9;sf=tgz

哪个正是我想要的,但我不知道这个哈希参数h=...是什么。它没有提交ID - 我已经检查过了。它必须以某种方式识别<subdir>。但即使它确实如此 - 这仍然无法帮助我,因为只想要从/只包含<subdir>开始的快照通常不知道这个哈希值。

有关如何通过Gitweb获取子目录快照的任何想法? 提前谢谢!


增加:

刚刚发现:h=42a6503da6aaedc92bb3543e0b0de9b2de0aaae9是与<subdir>相关联的哈希值,例如$ git ls-tree -r -t HEAD

所以这两个命令:

$ git archive --format=tar --remote=<gituser>@<gitserver>:<repo> HEAD:<subdir>

$ git archive --format=tar --remote=<gituser>@<gitserver>:<repo> 42a6503da6aaedc92bb3543e0b0de9b2de0aaae9

做同样的事情,让我认为 HEAD:<subdir>42a6503da6aaedc92bb3543e0b0de9b2de0aaae9是等价的。我仍然不能用http://<gitweburl>?p=<repo>;a=snapshot;h=42a6503da6aaedc92bb3543e0b0de9b2de0aaae9;sf=tgz替换HEAD:<subdir>中的哈希值。调用此URL会导致“400 - 无效的哈希参数”......所以这里没有真正的进展。


根据poke的建议,使用URL http://<gitweburl>/gitweb.cgi?p=<repo>;a=snapshot;h=HEAD;f=<subdir>

快速肮脏的黑客攻击
$ diff -Naur gitweb.cgi.original gitweb.cgi.new 
--- gitweb.cgi.original 2012-09-28 00:50:47.000000000 +0200
+++ gitweb.cgi.new  2013-01-22 11:04:29.870532502 +0100
@@ -7029,6 +7029,9 @@

    my ($name, $prefix) = snapshot_name($project, $hash);
    my $filename = "$name$known_snapshot_formats{$format}{'suffix'}";
+   if ($file_name) {
+       $hash="$hash:$file_name"
+   }
    my $cmd = quote_command(
        git_cmd(), 'archive',
        "--format=$known_snapshot_formats{$format}{'format'}",

2 个答案:

答案 0 :(得分:2)

有问题的h值是您当前正在查看的树对象的ID。提交具有单个根树对象,您可以在Gitweb的提交页面上看到该对象。每个树都是一个指向blob(如果是文件)或其他树对象的目录条目列表。

因此,当您在树中更深入地导航时,h始终表示树ID。另一方面,hb值是提交ID。

不幸的是,Gitweb没有更好的方法来获取子目录的快照,即不知道树形哈希而只知道路径。但是可能会添加一些功能,将f参数考虑在内并自动为您获取树形哈希。

我刚刚检查了这个来源,你可能在修改this part时很幸运。我不太了解perl,告诉你究竟要做什么,但你基本上可以检查是否设置了$file_name变量,如果是这种情况,只需获取$hash:$file_name的哈希值。然后你将它设置为新的哈希,一切都可以工作。

答案 1 :(得分:0)

我最近遇到了类似的任务 - 让gitweb生成一个带有列出的对象名称的存档(只允许一个f = URL参数,但是我们可以传递%20个空格字符来列出几个对象)。这是我对gitweb.cgi的整体补丁,如OpenSuse 13.2&#34; git-web-2.1.4-13.1.x86_64&#34;版本

随意使用和享受:

--- gitweb.cgi.orig     2015-03-13 13:42:29.000000000 +0100
+++ gitweb.cgi.snapshot-filenames-withoutDebug  2015-07-02 14:50:46.196000000 +0200
@@ -20,6 +20,11 @@
 use Time::HiRes qw(gettimeofday tv_interval);
 binmode STDOUT, ':utf8';

+# http://www.spinics.net/lists/git/msg241958.html
+if (!defined($CGI::VERSION) || $CGI::VERSION < 4.08) {
+       eval 'sub CGI::multi_param { CGI::param(@_) }'
+}
+
 our $t0 = [ gettimeofday() ];
 our $number_of_git_cmds = 0;

@@ -871,7 +876,7 @@

        while (my ($name, $symbol) = each %cgi_param_mapping) {
                if ($symbol eq 'opt') {
-                       $input_params{$name} = [ map { decode_utf8($_) } $cgi->param($symbol) ];
+                       $input_params{$name} = [ map { decode_utf8($_) } $cgi->multi_param($symbol) ];
                } else {
                        $input_params{$name} = decode_utf8($cgi->param($symbol));
                }
@@ -7324,6 +7329,15 @@
                die_error(403, "Unsupported snapshot format");
        }

+       if (!defined($hash)) {
+               $hash = "";
+               if ( $file_name && $file_name =~ /^([^:]*):(.*)$/ ) {
+                       $hash = "$1";
+                       $file_name = "$2";
+               }
+               if ( $hash eq "") { $hash = "HEAD"; }
+               printf STDERR "Defaulted hash to '$hash' ('h=' URL argument was missing)\n";
+       }
        my $type = git_get_type("$hash^{}");
        if (!$type) {
                die_error(404, 'Object does not exist');
@@ -7341,6 +7354,14 @@
                git_cmd(), 'archive',
                "--format=$known_snapshot_formats{$format}{'format'}",
                "--prefix=$prefix/", $hash);
+       if ($file_name) {
+               # To fetch several pathnames use space-separation, e.g.
+               # "...git-web?p=proj.git;a=snapshot;f=file1%20file2
+               # To fetch pathnames with spaces, escape them, e.g.
+               # "...git-web?p=proj.git;a=snapshot;f=file\%20name
+               $cmd .= " " . $file_name;
+       }
+
        if (exists $known_snapshot_formats{$format}{'compressor'}) {
                $cmd .= ' | ' . quote_command(@{$known_snapshot_formats{$format}{'compressor'}});
        }

更新:此代码下载经过单元测试等修订和扩展,并且针对上游gitweb进行了PR ...让我们看看它是怎么回事;) 点击此处:https://github.com/git/git/pull/206

希望这有帮助, 吉姆克里莫夫