使用 Gerrit(代码审查)时,我经常需要获取给定补丁集的副本以进行测试或验证。最明显、最简单的方法是通过 Gerrit Web 界面下载存档或补丁文件,然后手动将其应用到我的本地源。
虽然上述步骤非常简单并且满足了我的需求,但在最好的情况下,我希望补丁集在我的本地 Git 中显示为提交。
我环顾四周,没有找到解决方案。我发现一些稀疏信息一旦编译在一起就会给出以下解决方案。
假设您要拉取 Gerrit 变更 1222 的补丁集 2:
找到我们感兴趣的远程参考:
$ git ls-remote | grep 1220
From http://something.com:8081/MyProject
e2e0212a59240ac5cd7c11220c35542523f44b59 refs/changes/13/713/1
b8c4dceea5eaf1bad711b0ea6938c80ec932726a refs/changes/20/1220/1
6f20c182ec7f54a2aa9e8f6188a0eef1b0790df4 refs/changes/20/1220/2
ed94a98386d224ce3d86004ce99f61220905a077 refs/changes/22/1222/1
拉参考:
git pull origin refs/changes/20/1220/2
这将创建一个 Git 提交点,您最终可以对其进行变基:
git rebase
此功能是 Gerrit UI 中的标准功能。
在补丁 UI 的右上角,单击“下载”,您将看到类似以下内容:
浏览补丁时,请转到下载部分并复制命令行命令以查看补丁集,例如如下所示:
git fetch https://gerrit.googlesource.com/gerrit refs/changes/03/64403/2 && git checkout FETCH_HEAD
然后我通常会创建一个分支,以审阅号和补丁集作为名称
git checkout -b b64403-2
在这里,您可以正常工作并提交您的更改,或者在此更改上挑选/重新调整您的更改。
完成 r64403 的审核后,您的代码可以合并,或者当提交另一个补丁集时,您将需要再次执行相同的操作。
如果您没有看到将选项下载到
Checkout
或Cherry Pick
的选项,您需要编辑gerrit.config
,如下所示:
[download]
scheme = ssh
command = checkout
command = cherry_pick
更多详细信息可以在 Gerrit 文档
中找到更新: 正如 barryku 正确指出的那样,在更高版本中,您需要下载 downloads-commands 插件。这可以在初始设置期间或使用以下命令来完成:
java -jar gerrit-2.11.4.war init -d review_site --batch --install-plugin download-commands
或者您可以使用
-d
选项来进行 git-review。 例如,假设您正在使用 nova-docker 存储库,并且对 gerrit 中的这一更改感兴趣:
您可以像这样下载最新的补丁集:
git review -d 148486
或者您可以使用更改ID:
git review -d I35729a86e211391f67cc959d19416c9125c6f9eb
您还可以通过附加逗号和补丁号来请求补丁的特定修订版。例如,要获得该补丁的第二个修订版:
git review -d 148486,2
我不是 100% 确定你的问题是什么。听起来您想简化工作流程或打字。 larsks 已经提到过
git review
这是最常用的。
对于您的情况,也许自动下载所有参考文献会有所帮助,以便您可以直接引用它们。您始终可以使用 来指定所有指定的参考
git fetch origin "+refs/changes/*:refs/remotes/origin/changes/*"
然后您可以使用提交 ID 在本地工作。
可以轻松完成一个简单的 git 别名或为所有引用编写脚本。这种 while 循环的示例可以在https://github.com/saper/gerrit-fetch-all 上的脚本中找到。使用如此小的 shell 片段,您可以轻松完成跳过 ref id 的一部分到更容易参考它们:
Server side: Client side:
refs/changes/13/713/1 refs/head/713/1
refs/changes/20/1220/1 refs/head/1220/1
refs/changes/20/1220/2 refs/head/1220/2
refs/changes/22/1222/1 refs/head/1222/1
git-review
),你可以使用 gerrit API:
curl -s 'https://<your gerrit server>/r/changes/<change id>?o=CURRENT_REVISION&o=DOWNLOAD_COMMANDS' | tail -n+2 | jq -r '.revisions[.current_revision].fetch["anonymous http"].commands.Pull' | bash -
或
git pull origin `curl -s 'https://<your gerrit server>/r/changes/<change id>?o=CURRENT_REVISION' | tail -n+2 | jq -r '.revisions[.current_revision].ref'`
我真的很喜欢@tomasz-gawel 的回答与
git fetch origin "+refs/changes/*:refs/remotes/origin/changes/*"
我遇到的唯一问题是它创建的 90% 的引用对我来说毫无用处并且只会污染我的 git 日志树。 它们要么已经过时(因为更改已经有了更新的补丁集),要么有一个“元”结局。
我经常在权限上受到一定限制,因此使用git review
对我来说并不总是一个可行的选择。所以我决定创建一个 git 别名来获取所有更改引用并删除那些对我来说无用的。 这是我的
[alias]
与 gerrit 相关的部分
~/.gitconfig
(也可在我的要点中找到)
[alias]
gerrit-fetch-all-changes = "!f() {\
ORIGIN="${1:-origin}"; \
echo \"Fetching change refs from $ORIGIN..\"; \
git fetch $ORIGIN \"+refs/changes/*:refs/remotes/$ORIGIN/changes/*\"; \
}; f"
gerrit-prune-older-refs = "!f() {\
ORIGIN="${1:-origin}"; \
ALL_CHANGES_REFS=$(mktemp); \
NEWEST_CHANGES_REFS=$(mktemp); \
echo \"Prunning outdated change refs from $ORIGIN\"; \
git show-ref | grep "refs/remotes/$ORIGIN/changes" | awk -F ' ' '{print $2}' | sort -t "/" -k5,5n -k6,6n -k7,7n > $ALL_CHANGES_REFS ;\
NUMBER_OF_ALL_REFS=$(wc -l < \"$ALL_CHANGES_REFS\"); \
echo \"Found $NUMBER_OF_ALL_REFS matching refs\"; \
cat $ALL_CHANGES_REFS | awk -F'/' '{if($7 != prevR7 + 1) {print prevR}} { prevR=$0 } { prevR7=$7 } END { if (prevR != \"\") {print prevR} }'> $NEWEST_CHANGES_REFS ; \
diff --new-line-format="" --unchanged-line-format="" $ALL_CHANGES_REFS $NEWEST_CHANGES_REFS | xargs -I % git update-ref -d %; \
NUMBER_OF_LEFT_REFS=$(wc -l < \"$NEWEST_CHANGES_REFS\"); \
echo \"Prunning complited (left $NUMBER_OF_LEFT_REFS refs)\"; \
}; f"
gerrit-fc = !git gerrit-fetch-all-changes $1 && git gerrit-prune-older-refs $1
lg = log --graph --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --decorate=full
它通过远程参数化添加了更好的别名
# Fetches all gerrit changes from certain remote (defaults to origin)
git gerrit-fetch-all-changes [<remote>]
# Prunes refs changes that are not latest
git gerrit-prune-older-refs [<remote>]
# Fetches all gerrit changes and prunes not latest
git gerrit-fc [<remote>]
对于大型回购来说,这可能不是最有效的解决方案,但仍然相当可行 - 也许它会对某人有所帮助:)附注我尝试将此作为评论添加到@tomasz-gawel 答案中,但我的声誉不足