49

拉取请求似乎是使用 Git 进行代码审查的常用方法。但是,尚不清楚该术语在使用内置git request-pull或不同工具时是否具有相同含义。

拉取请求是 Git 的内在功能,还是 GitHub、Gerrit 或 Atlassian Stash 等工具的常用术语?

代码审查的讨论和“结果”是否存储在 Git 提交历史或单独的数据库中?

4

3 回答 3

40

拉取请求是一个简单的概念,起源于 Git 创建时,但后来被带到了不同的层次。

本质是您没有对要贡献的存储库的推送权限,因此您可以分叉存储库,制作您的私有副本(顺便说一句,克隆已经这样做了),然后您为该存储库做出贡献。然后您要求原始存储库的维护者拉入您的更改。所以你本质上是在提交一个补丁。

现在正如我所说,有不同的方法可以做到这一点,但这一切都归结为请求维护者拉入你的更改,因此得名。创建 Git 的最初目的是 Linux 内核,并且他们一直在使用邮件列表进行开发。所以对他们来说,拉取请求实际上是每封电子邮件发送一个补丁。这些补丁实际上是由一些正常的电子邮件通信东西预先提交的对象——Git 有工具来生成它。

git request-pull是一个类似的工具,用于生成请求拉取请求的消息。但在这种情况下,它更接近于拉动的想法。虽然可以应用补丁,但创建的请求request-pull实际上告诉维护者从不同的远程存储库中提取更改。

Git书有这个例子:

$ git request-pull origin/master myfork
The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
  John Smith (1):
        added a new function

are available in the git repository at:

  git://githost/simplegit.git featureA

Jessica Smith (2):
      add limit to log function
      change log output to 30 from 25

 lib/simplegit.rb |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

所以它实际上只是一个生成消息以执行底层概念的实用程序。

其他源代码托管商(如 GitHub)也这样做。当您在 GitHub 上创建拉取请求时,您只需创建一个问题,其中包含维护者可以拉取的提交的更多信息。当然,这一切都在一个网站上,他们可以更多地链接所有内容,并提供例如一键式合并按钮。

但基本概念还是一样的:请求维护者拉入您所做的一些更改。唯一的区别是与此请求进行通信的方式。

于 2013-11-29T16:16:24.900 回答
9

git request-pull命令可用于在本机 git 中创建“拉取请求”。运行时,Git 会生成项目更改的摘要以及可以从中提取代码的 Git 存储库 URL。然后可以将其邮寄到邮件列表或项目维护者,然后他们可以将更改入他们自己的存储库。

Pro Git手册的这一部分git request-pull包含有关该命令的更多具体信息。

于 2013-11-29T16:15:44.443 回答
0

本质是您没有对要贡献的存储库的推送权限,因此您可以分叉存储库,制作您的私有副本(顺便说一句,克隆已经这样做了),然后您为该存储库做出贡献。

这不再是 Git 2.29(2020 年第四季度)的唯一选择:

" git receive-pack" ( man )接受请求的 " git push" 学会了将大部分 ref 更新外包给新的 " proc-receive" 钩子

参见江鑫的提交 d6edc18 ,提交1702ae6,提交c6a6a01,提交31e8595提交 b913075提交 63518a5提交 195d6ea提交 15d3af5提交 38b9197提交 917c612 jiangxin 2020 年 8 月 27 日
(由Junio C Hamano 合并gitster——提交 6c430a6中,2020 年 9 月 25 日)

receive-pack: 添加新的proc-receive钩子

签字人:蒋欣

Git 调用一个内部execute_commands函数来处理从客户端发送到git-receive-pack.

无论用户推送什么引用,如果用户具有写权限,Git 都会创建或更新相应的引用。

没有写权限的贡献者不能直接推送到存储库。
因此,贡献者必须将提交写入备用位置,并通过电子邮件或其他方式发送拉取请求。
我们将此工作流程称为分布式工作流程

在Gerrit为某些情况下提供的集中式工作流程中工作会更方便。

例如,无法直接推送到分支的只读用户可以运行以下( man )命令将提交推送到伪引用(具有前缀“ ”,而不是“ ”)以创建代码审查。git pushrefs/for/refs/heads/

git push origin \
    HEAD:refs/for/<branch-name>/<session>  

<branch-name>例中的 可以像“ master”一样简单,也可以像“ ”这样更复杂的分支名称foo/bar
<session>例中的命令可以是客户端的本地分支名称,如“ my/topic”。

我们不能通过使用 " pre-receive" + " post-receive" 优雅地实现集中式工作流,因为 Git 会调用内部函数 " execute_commands" 在这两个钩子之间创建引用(甚至是特殊的伪引用)。
即使我们可以通过 " post-receive" 钩子删除临时创建的伪引用,但对于并发推送来说,临时引用并不安全。

因此,添加一个过滤器和一个新的处理程序来支持这种工作流。

过滤器将检查引用名称的前缀,如果命令具有特殊的引用名称,过滤器将为run_proc_receive命令打开特定字段 ( )。
打开此字段的命令将由一个新的处理程序(一个名为“ proc-receive”的钩子)而不是内部execute_commands函数执行。

我们可以使用这个“ proc-receive”命令来创建拉取请求或发送电子邮件进行代码审查

Junio 建议,这个“ proc-receive”钩子读取命令、推送选项(可选),并使用pkt-line格式的协议发送结果。
在下面的例子中,字母“ S”代表“ receive-pack”,字母“ H”代表钩子。

# Version and features negotiation.
S: PKT-LINE(version=1\0push-options atomic...)
S: flush-pkt
H: PKT-LINE(version=1\0push-options...)
H: flush-pkt  

# Send commands from server to the hook.
S: PKT-LINE(<old-oid> <new-oid> <ref>)
S: ... ...
S: flush-pkt
# Send push-options only if the 'push-options' feature is enabled.
S: PKT-LINE(push-option)
S: ... ...
S: flush-pkt  

# Receive result from the hook.
# OK, run this command successfully.
H: PKT-LINE(ok <ref>)
# NO, I reject it.
H: PKT-LINE(ng <ref> <reason>)
# Fall through, let 'receive-pack' to execute it.
H: PKT-LINE(ok <ref>)
H: PKT-LINE(option fall-through)
# OK, but has an alternate reference.  The alternate reference name
# and other status can be given in options
H: PKT-LINE(ok <ref>)
H: PKT-LINE(option refname <refname>)
H: PKT-LINE(option old-oid <old-oid>)
H: PKT-LINE(option new-oid <new-oid>)
H: PKT-LINE(option forced-update)
H: ... ...
H: flush-pkt  

收到命令后,钩子会执行命令,并可能创建/更新不同的引用。

例如,用于伪引用“ refs/for/master/topic”的命令可以创建/更新不同的引用,例如“ refs/pull/123/head”。
备用参考名称和其他状态在选项行中给出。

“ ”返回的命令列表proc-receive将替换用户发送给“ receive-pack”的相关命令,“ receive-pack”将继续运行"execute_commands“ ”函数和其他例程。

最后,这些命令的执行结果将报告给最终用户。

receive-pack从 " " 到 " "的报告功能send-pack将在后面的提交中扩展,就像 " proc-receive" 钩子报告给 " receive-pack" 的内容。

于 2020-09-26T12:00:40.773 回答