3

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

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

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

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

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

在 Gitweb 网络界面中单击后,我发现,更改为“树”视图并移动到<subdir>然后单击“快照”使用类似于以下的 URL:

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

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


正如 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'}",
4

2 回答 2

2

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

因此,当您更深入地导航到树时,h总是代表树 id。hb另一方面,该值是提交 ID。

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

我刚刚检查了这部分的来源,你在修改这部分时可能会有运气。我不太了解 perl,无法告诉您具体要做什么,但您基本上可以检查$file_name变量是否已设置,如果是这样,只需获取$hash:$file_name. 然后你将它设置为新的哈希值,一切都可以正常工作。

于 2013-01-21T18:14:19.730 回答
0

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

随意使用和享受:

--- 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

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

于 2015-07-02T12:55:18.407 回答