Gerrit:完成首次代码推送的完整指南

📚 使用须知

  • 本博客内容仅供学习参考
  • 建议理解思路后独立实现
  • 欢迎交流讨论

task : 将代码推送到的Gerrit服务器

Gerrit:完成首次代码推送的完整指南

面对复杂的内网环境、陌生的工具链和嵌套的代码仓库,我如何一步步将代码成功推送到团队的Gerrit服务器?本文将分享从环境配置到成功推送的完整实战经验。

写在前面

将一个本地项目推送到团队的Gerrit代码托管平台。挑战是多方面的:内网域名解析、SSH/GPG密钥配置、WSL与Windows环境差异、嵌套Git仓库处理……通过一步步探索和问题解决,成功完成了首次推送。

本文将完整记录这一过程,如果你也面临类似的企业内网开发环境挑战,相信我的经验能为你节省大量时间。

环境概览与核心问题

我的工作环境涉及三个关键部分:

  • Git与Gerrit:团队使用的代码版本控制与审阅平台
  • WSL (Windows Subsystem for Linux):在Windows上运行的Linux子系统
  • 企业内网:内部域名、特定的网络策略和访问限制

核心问题迅速浮现:在WSL中无法解析公司的内部域名,导致所有需要连接Gerrit服务器的操作都失败。

第一阶段:基础配置与密钥设置

1.1 Git基础配置

git config --global user.name “Your Name”
git config --global user.email “your.email@example.com”

这是所有Git操作的起点,确保你的提交信息正确。

1.2 SSH密钥生成与配置

SSH密钥是安全访问Git服务器的必备条件:

ssh-keygen -t ed25519 -C “your.email@example.com”
# 查看公钥
cat ~/.ssh/id_ed25519.pub

关键步骤:将输出的SSH公钥完整复制到Gerrit的 Settings → SSH Keys 中。

1.3 GPG密钥配置(用于提交签名)

虽然有些团队不强制要求,但GPG签名是代码来源可信的重要保障:

gpg --batch --passphrase ‘’ --quick-generate-key “your.email@example.com” rsa4096 sign never
# 获取密钥ID
GPG_KEY=$(gpg --list-secret-keys --with-colons | grep “^sec” | cut -d’:’ -f5 | head -n 1)
echo $GPG_KEY
# 配置Git使用此密钥
git config --global user.signingkey “$GPG_KEY”
git config --global commit.gpgsign true

同样,需要导出GPG公钥并添加到Gerrit的 Settings → GPG Keys

gpg --armor --export “your.email@example.com” > gpg.pub
cat gpg.pub

第二阶段:破解WSL内网访问难题

2.1 问题诊断:DNS解析失败

在WSL中尝试克隆仓库时,首先遇到的是域名解析问题:

git clone “ssh://username@gerrit-server:29418/project.git”
# 错误:Could not resolve hostname gerrit-server: Name or service not known

检查后确认是DNS问题:

nslookup gerrit-server.internal.company.com
# 返回:server can’t find ...: NXDOMAIN

2.2 解决方案:使用IP地址直连

由于临时无法解决WSL的DNS配置,我采用了备用方案:直接使用服务器IP地址

从团队文档或同事处获取Gerrit服务器的内网IP后:

git clone “ssh://username@10.117.115.89:29418/project.git”

注意:你需要接受服务器的SSH指纹验证(输入“yes”)。

2.3 WSL与Windows密钥同步

一个微妙但关键的问题:在Windows的Git Bash中操作正常,但在WSL中却提示权限被拒。原因在于WSL有独立的SSH密钥存储。

解决方案是从Windows复制已有的密钥到WSL:

# 复制私钥和公钥
cp /mnt/c/Users/YourName/.ssh/id_ed25519 ~/.ssh/
cp /mnt/c/Users/YourName/.ssh/id_ed25519.pub ~/.ssh/

# 设置正确的权限(SSH严格要求)
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

第三阶段:克隆仓库与安装Gerrit钩子

3.1 成功克隆仓库

使用IP地址成功克隆:

git clone “ssh://username@10.117.115.89:29418/team/project.git” && \
(cd “project” && \
mkdir -p `git rev-parse --git-dir`/hooks/ && \
curl -Lo `git rev-parse --git-dir`/hooks/commit-msg \
http://10.117.115.89/tools/hooks/commit-msg && \
chmod +x `git rev-parse --git-dir`/hooks/commit-msg)

这里遇到了SSL证书错误,因为curl尝试使用HTTPS但证书是为域名而非IP签发。临时解决方案是改用HTTP协议。

3.2 手动安装commit-msg钩子

如果上述curl命令因证书问题失败,可手动安装:

cd project
curl -kLo .git/hooks/commit-msg https://gerrit-server/tools/hooks/commit-msg
chmod +x .git/hooks/commit-msg

重要:这个commit-msg钩子会自动在提交信息中生成Change-Id,这是Gerrit追踪变更的必要标识。

第四阶段:处理复杂的嵌套代码仓库

4.1 问题:仓库中的仓库

当我尝试添加一个包含多个子项目的文件夹时,Git发出了警告:

git add repo/
# 警告:adding embedded git repository: repo/ci-tools-pro
# 提示:You’ve added another git repository inside your current repository.

4.2 解决方案选择

我面临三种选择:

  1. Git子模块 (Submodule):最规范,保持子项目独立
  2. 直接复制代码:最简单,但丢失子项目历史
  3. Git子树 (Subtree):折中方案,但操作复杂

考虑到这些子项目是团队共享的通用工具,本应使用子模块。但作为首次推送,我选择了方案二:直接复制代码,先确保代码能成功推送。

4.3 实施步骤

# 移除子项目中的.git文件夹(使其变为普通文件夹)
find repo/ -name “.git” -type d | xargs rm -rf

# 重新添加
git add repo/

第五阶段:提交与推送代码到Gerrit

5.1 标准的Git操作

# 添加变更
git add .
# 提交(会自动使用GPG签名)
git commit -m “添加新功能:简要描述”
# 推送到Gerrit的审阅队列
git push origin HEAD:refs/for/master

5.2 关键细节

  • refs/for/master 是Gerrit特有的引用格式,表示“推送到master分支的待审队列”
  • 普通的 git push origin master 会直接被拒绝(除非有强制推送权限)

5.3 成功推送的标志

成功推送后,终端会显示类似信息:

remote: SUCCESS
remote:
remote:   https://gerrit-server.company.com/c/team/project/+/19890140 [NEW]

这个URL就是你本次变更的代码审阅链接,务必保存并与团队成员分享。

问题解决流程图

以下是整个过程中关键问题的解决路径概览:

flowchart TD A[开始: 准备推送代码] --> B{WSL环境<br>克隆仓库失败} B -->|DNS解析问题| C[解决方案: 使用IP地址直连] B -->|SSH密钥问题| D[解决方案: 从Windows复制密钥] C --> E[成功克隆仓库] D --> E E --> F[安装Gerrit钩子] F --> G{遇到嵌套Git仓库} G --> H[选择方案: 移除子仓库.git目录] H --> I[正常添加与提交代码] I --> J[推送至refs/for/master] J --> K[获取Gerrit审阅链接] K --> L[完成]

经验总结与最佳实践

通过这次完整的推送过程,我总结了以下经验:

链接

1. 环境隔离是常见问题源

WSL、Windows、企业内网三者之间的环境差异常常导致意料之外的问题。优先确认当前环境是解决问题的第一步。

2. 分步验证,逐步推进

不要试图一次性完成所有配置。我的验证顺序是:

  1. 基础Git配置 → 2. SSH密钥验证 → 3. 网络连接测试 → 4. 仓库克隆 → 5. 实际推送

3. 理解工具的设计哲学

Gerrit的 refs/for/ 分支、强制代码审阅、Change-Id机制等都有其设计目的。理解而不仅仅是记忆命令,能帮助你在遇到新问题时更快找到解决方案。

4. 企业环境的特殊性

内网域名、自定义证书、网络代理、安全策略等企业环境特性,意味着公开的教程可能不能直接适用。与团队同事保持沟通,获取环境特定信息至关重要。

最后的建议

对于刚接触企业级开发环境的新手:

  1. 记录每一步操作和结果:就像这篇博客一样,详细记录有助于回溯和总结
  2. 不要害怕错误信息:错误信息是解决问题的最佳线索
  3. 利用团队资源:同事可能已经遇到过相同问题
  4. 理解而不仅仅是操作:知道“为什么”比知道“怎么做”更重要

代码推送只是协作开发的起点。

希望这篇详尽的记录能帮助你在自己的环境中顺利完成首次代码推送。

posted @ 2026-02-02 13:23  mo686  阅读(177)  评论(0)    收藏  举报