【问题标题】:Why is git push gerrit HEAD:refs/for/master used instead of git push origin master为什么使用 git push gerrit HEAD:refs/for/master 而不是 git push origin master
【发布时间】:2012-05-05 11:05:05
【问题描述】:

我刚刚开始使用gerrit,我想知道为什么我们需要使用git push gerrit HEAD:refs/for/master 而不是git push origin master

如果我这样做 git push origin master 我会收到错误消息 ! [remote rejected] master -> master (prohibited by Gerrit)

【问题讨论】:

  • 虽然有一些答案,但就像“骗客户”,“神奇”。所以这就是我不喜欢软件工程当前状态的地方:工作中没有人真正知道发生了什么,推送实际上给出了fatal: internal server error,但连同remote: SUCCESS 的打印输出似乎相互矛盾的消息,并且有时由 Gerrit 启动的测试有效,有时则无效,根本没有任何改变。没有人知道发生了什么的感觉不好

标签: git gerrit


【解决方案1】:

Gerrit 的文档,尤其是 "Push changes" 部分,解释说您使用任何 Git 客户端工具推送到“神奇的 refs/for/'branch' ref”。

下图取自the Intro to Gerrit。当您推送到 Gerrit 时,您会执行 git push gerrit HEAD:refs/for/<BRANCH>。这会将您的更改推送到暂存区(在图中,“待更改”)。 Gerrit 实际上没有名为<BRANCH> 的分支;它对 git 客户端说谎。

在内部,Gerrit 有自己的 Git 和 SSH 堆栈实现。这允许它提供“神奇的”refs/for/<BRANCH> refs。

当收到在这些命名空间之一中创建 ref 的推送请求时,Gerrit 会执行自己的逻辑来更新数据库,然后就操作结果向客户端撒谎。成功的结果会使客户相信 Gerrit 创建了 ref,但实际上 Gerrit 根本没有创建 ref。 [Link - Gerrit, "Gritty Details"]。

补丁成功后(即补丁已经推送到Gerrit,[放到“Pending Changes”暂存区],审核,审核通过),Gerrit从“Pending Changes”推送变更进入“Authoritative Repository”,根据你推送到refs/for/<BRANCH>时的魔法来计算将它推送到哪个分支。这样,可以直接从Authoritative Repository 的正确分支中提取成功审核的补丁。

【讨论】:

  • 出于好奇,如果您只执行“git push origin”之类的操作,究竟会发生什么?我试过了,在任何地方都看不到变化,因此是这个问题。但它自然存在于我的本地日志中。
  • @Pintolaranja 我无意中做了同样的事情。你是对的,Gerrit “处理”这种情况,但它不会产生任何变化。所以实际上,它根本不处理它。这真的让我很生气,因为这真的很愚蠢。为什么允许用户提交一些 Gerrit 无法正确处理的内容?
  • @gregb 是的。箭头指示命令的源和目标,而不是任何后续数据流。例如开发人员 1 向权威存储库发出 fetch,而不是相反
  • @trejder 它允许这样做,因为 Gerrit 允许您配置一些帐户以绕过评论。通过推送到默认分支,您实际上是在说“我想在不审查的情况下合并此更改”。如果您不允许这样做,则推送失败。
  • 事实上,如果正确构建了 git/gerrit 互操作,您就不必做这种愚蠢的事情,只需执行“git push origin”(更好的是,只需“git push”)然后git/gerrit 的配置方式是,它会自动将您的更改放在暂存区进行代码审查。强迫您推送到与您打算更改的位置不同的位置是愚蠢的,会增加混乱,并导致错误。
【解决方案2】:

为了避免必须完全指定 git push 命令,您也可以修改 git 配置文件:

[remote "gerrit"]
    url = https://your.gerrit.repo:44444/repo
    fetch = +refs/heads/master:refs/remotes/origin/master
    push = refs/heads/master:refs/for/master

现在你可以简单地:

git fetch gerrit
git push gerrit

这是根据Gerrit

【讨论】:

  • +1 来自我!为我的remote.origin.push 硬编码而不是每次都输入/粘贴它会更好!
  • @SeanMurphy 您可以通过用 '*' 替换 'master' 的实例来使其更通用,这样 'git push gerrit TopicBranch' 之类的东西也可以工作。
  • 另外,如果 gerrit 是您唯一的遥控器,您根本不必指定它。我只是用上面提到的配置@DavidDoria 做git fetch 和git push。
  • push = refs/heads/*:refs/for/* 适用于所有分支
  • 您确实需要使用上游分支,而不是您当前的分支。我通常会同时进行十几个更改,因此使用单个分支是行不通的。
猜你喜欢
  • 2011-08-07
  • 2012-09-09
  • 2021-07-14
  • 1970-01-01
  • 2012-09-21
  • 2015-12-08
  • 2017-09-21
  • 2015-07-03
  • 2021-04-13
相关资源
最近更新 更多