简体   繁体   English

拉取请求是 Git 的一部分,还是 GitHub、Gerrit 和 Atlassian Stash 等工具的功能?

[英]Are pull requests part of Git, or a feature of tools like GitHub, Gerrit and Atlassian Stash?

Pull requests seem to be the common way to do code review with Git.拉取请求似乎是使用 Git 进行代码审查的常用方法。 However, it is not clear whether this term means the same when using the built-in git request-pull , or a different tool.但是,在使用内置的git request-pull或不同的工具时,这个术语是否具有相同的含义尚不清楚。

Are pull requests an intrinsic function of Git, or is it a common term for tools like GitHub, Gerrit or Atlassian Stash?拉取请求是 Git 的固有功能,还是 GitHub、Gerrit 或 Atlassian Stash 等工具的通用术语?

Is the discussion and "result" of the code review stored in the Git commit history or in a separate database?代码审查的讨论和“结果”是存储在 Git 提交历史记录中还是存储在单独的数据库中?

Pull requests are a simple concept that originated when Git was created but has been taken to different levels since.拉取请求是一个简单的概念,它起源于 Git 被创建时,但此后已被带到不同的级别。

The essence is that you do not have push rights to the repository you want to contribute on, so instead you fork the repository, making your private copy (a clone already does this btw.) and you contribute to that one instead.本质是您没有对要贡献的存储库的推送权限,因此您可以分叉存储库,制作您的私有副本(顺便说一句,克隆已经这样做了),然后您向该存储库做出贡献。 And then you ask a maintainer of the original repository to pull in your changes.然后您要求原始存储库的维护者拉入您的更改。 So you are essentially submitting a patch.因此,您实际上是在提交补丁。

Now as I said, there are different ways to do this, but it all boils down to requesting a maintainer to pull in your changes, hence the name.现在正如我所说,有不同的方法可以做到这一点,但这一切都归结为要求维护者拉入您的更改,因此得名。 The original purpose Git was created for is the Linux kernel, and they have been developing using mailing lists forever. Git 创建的最初目的是 Linux 内核,并且他们一直在使用邮件列表进行开发。 So for them, a pull request is actually sending a patch per email;所以对他们来说,拉取请求实际上是每封电子邮件发送一个补丁; those patches are actually commit objects prepended by some normal email communication stuff—Git has tools to generate this.这些补丁实际上是由一些普通的电子邮件通信内容前置的提交对象——Git 有工具来生成它。

git request-pull is a similar tool to generate a message asking for a pull request. git request-pull是一个类似的工具,用于生成请求拉取请求的消息。 But in this case, it's closer to the pull idea.但在这种情况下,它更接近拉动的想法。 While patches can just be applied, requests created by request-pull actually tell the maintainer to pull the changes from a different remote repository.虽然补丁可以直接应用,但由request-pull创建的request-pull实际上是告诉维护者从不同的远程存储库中提取更改。

The Git book has this example: 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(-)

So it's really just a utility to generate messages to execute the underlying concept.所以它实际上只是一个生成消息以执行底层概念的实用程序。

Other source code hosters like GitHub do this similarly as well.其他源代码托管商(如 GitHub)也以类似方式执行此操作。 When you create a pull request on GitHub, you just create an issue which contains further information where the commits are the maintainer can pull.当您在 GitHub 上创建拉取请求时,您只需创建一个问题,其中包含维护者可以拉取提交的更多信息。 Of course, it all being on a single website, they can interlink everything a bit more and provide those one-click merge buttons for example.当然,这一切都在一个网站上,他们可以更多地链接所有内容,例如提供那些一键合并按钮。

But the basic concept is still the same: Requesting a maintainer to pull in some changes you have made.但基本概念仍然相同:请求维护者引入您所做的一些更改。 The only difference is the way this request is communicated with.唯一的区别是此请求的通信方式。

The git request-pull command can be used to create a "pull request" in native git. git request-pull命令可用于在本机 git 中创建“拉取请求”。 When run, Git generates a summary of changes to a project and the Git Repository URL where the code can be pulled from.运行时,Git 会生成项目更改的摘要以及可以从中提取代码的 Git 存储库 URL。 This can then be mailed to a mailing list or the project maintainers, who can then pull in the changes to their own repositories.然后可以将其邮寄到邮件列表或项目维护人员,然后他们可以将更改入他们自己的存储库。

This section of the Pro Git book contains more specific information about the git request-pull command. Pro Git书籍的这一部分包含有关git request-pull命令的更多具体信息。

The essence is that you do not have push rights to the repository you want to contribute on, so instead you fork the repository, making your private copy (a clone already does this btw.) and you contribute to that one instead.本质是您没有对要贡献的存储库的推送权限,因此您可以分叉存储库,制作您的私有副本(顺便说一句,克隆已经这样做了),然后您向该存储库做出贡献。

That is no longer the only option with Git 2.29 (Q4 2020):这不再是 Git 2.29(2020 年第四季度)的唯一选择:

" git receive-pack " ( man ) that accepts requests by " git push " learned to outsource most of the ref updates to the new " proc-receive " hook .接受“ git push ”请求的“ git receive-packman学会了将大部分 ref 更新外包给新的“ proc-receive ”钩子

See commit d6edc18 , commit 1702ae6 , commit c6a6a01 , commit 31e8595 , commit b913075 , commit 63518a5 , commit 195d6ea , commit 15d3af5 , commit 38b9197 , commit 917c612 (27 Aug 2020) by Jiang Xin ( jiangxin ) .提交d6edc18提交1702ae6提交c6a6a01提交31e8595提交b913075提交63518a5提交195d6ea提交15d3af5提交38b9197提交917c612通过(2020年8月27日),蒋欣( jiangxin
(Merged by Junio C Hamano -- gitster -- in commit 6c430a6 , 25 Sep 2020) (由Junio C gitster合并gitster 提交 6c430a6,2020年 9 月 25 日)

receive-pack : add new proc-receive hook receive-pack :添加新的proc-receive钩子

Signed-off-by: Jiang Xin签字人:蒋欣

Git calls an internal execute_commands function to handle commands sent from client to git-receive-pack . Git 调用内部execute_commands函数来处理从客户端发送到git-receive-pack

Regardless of what references the user pushes, Git creates or updates the corresponding references if the user has write-permission.无论用户推送什么引用,如果用户有写权限,Git 都会创建或更新相应的引用。

A contributor who has no write-permission, cannot push to the repository directly.没有写权限的贡献者不能直接推送到存储库。
So, the contributor has to write commits to an alternate location, and sends pull request by emails or by other ways.因此,贡献者必须将提交写入备用位置,并通过电子邮件或其他方式发送拉取请求。
We call this workflow as a distributed workflow .我们将此工作流称为分布式工作流

It would be more convenient to work in a centralized workflow like what Gerrit provided for some cases.在像Gerrit为某些情况提供的集中式工作流中工作会更方便。

For example, a read-only user who cannot push to a branch directly can run the following git push ( man ) command to push commits to a pseudo reference (has a prefix " refs/for/ ", not " refs/heads/ ") to create a code review.例如,无法直接推送到分支的只读用户可以运行以下git push ( man )命令将提交推送到伪引用(具有前缀“ refs/for/ ”,而不是“ refs/heads/ ” ) 创建代码审查。

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

The <branch-name> in the above example can be as simple as " master ", or a more complicated branch name like " foo/bar ".上面例子中的<branch-name>可以像“ master ”一样简单,也可以像“ foo/bar ”这样更复杂的分支名称。
The <session> in the above example command can be the local branch name of the client side, such as " my/topic ".上面示例命令中的<session>可以是客户端的本地分支名称,例如“ my/topic ”。

We cannot implement a centralized workflow elegantly by using " pre-receive " + " post-receive ", because Git will call the internal function " execute_commands " to create references (even the special pseudo reference) between these two hooks.我们不能通过使用“ pre-receive ”+“ post-receive ”来优雅地实现集中式工作流,因为Git会调用内部函数“ execute_commands ”在这两个钩子之间创建引用(甚至是特殊的伪引用)。
Even though we can delete the temporarily created pseudo reference via the " post-receive " hook, having a temporary reference is not safe for concurrent pushes.尽管我们可以通过“ post-receive ”钩子删除临时创建的伪引用,但是对于并发推送来说,拥有临时引用是不安全的。

So, add a filter and a new handler to support this kind of workflow.因此,添加一个过滤器和一个新的处理程序来支持这种工作流。

The filter will check the prefix of the reference name, and if the command has a special reference name, the filter will turn a specific field ( run_proc_receive ) on for the command.过滤器将检查引用名称的前缀,如果命令具有特殊的引用名称,过滤器将打开该命令的特定字段( run_proc_receive )。
Commands with this filed turned on will be executed by a new handler (a hook named " proc-receive ") instead of the internal execute_commands function.打开此字段的命令将由新处理程序(名为“ proc-receive ”的钩子)而不是内部execute_commands函数执行。

We can use this " proc-receive " command to create pull requests or send emails for code review .我们可以使用这个“ proc-receive ”命令来创建拉取请求或发送电子邮件进行代码审查

Suggested by Junio, this " proc-receive " hook reads the commands, push-options (optional), and send result using a protocol in pkt-line format. Junio 建议,这个“ proc-receive ”钩子使用pkt-line格式的协议读取命令、推送选项(可选)和发送结果。
In the following example, the letter " S " stands for " receive-pack " and letter " H " stands for the hook.在下面的例子中,字母“ 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

After receiving a command, the hook will execute the command, and may create/update different reference.钩子在接收到命令后会执行命令,并且可能会创建/更新不同的引用。

For example, a command for a pseudo reference " refs/for/master/topic " may create/update different reference such as " refs/pull/123/head ".例如,伪引用“ refs/for/master/topic ”的命令可以创建/更新不同的引用,例如“ refs/pull/123/head ”。
The alternate reference name and other status are given in option lines.备用参考名称和其他状态在选项行中给出。

The list of commands returned from " proc-receive " will replace the relevant commands that are sent from user to " receive-pack ", and " receive-pack " will continue to run the "execute_commands " function and other routines. proc-receive ”返回的命令列表将替换用户发送给“ receive-pack ”的相关命令,“ receive-pack ”将继续运行"execute_commands ”函数和其他例程。

Finally, the result of the execution of these commands will be reported to end user.最后,这些命令的执行结果将报告给最终用户。

The reporting function from " receive-pack " to " send-pack " will be extended in latter commit just like what the " proc-receive " hook reports to " receive-pack ".从“ receive-pack ”到“ send-pack ”的报告功能将在后面的提交中扩展,就像“ proc-receive ”钩子报告给“ receive-pack ”一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM