You need to enable JavaScript to run this app. 如何仅使用curl向Git仓库推送commit?
优惠活动
大模型
产品
解决方案
定价
更多

如何仅使用curl向Git仓库推送commit?

你当前命令失效的核心原因
  • 你存储的raw_pack文件混入了Wireshark抓取的TCP头、HTTP头、报文分段冗余数据,不是Git协议要求的纯请求二进制内容,服务器无法解析会直接丢弃。
  • 请求路径缺失仓库的实际挂载路径,标准路由格式为<服务器根地址>/<对应仓库的完整路径>.git/git-receive-pack,路由不匹配时服务器不会返回任何内容。
  • 缺失Git Smart协议要求的前置引用协商步骤,服务器不会默认进入接收pack文件的状态。
  • 使用-d参数传输二进制pack内容,会触发curl的换行符转换逻辑,损坏pack的二进制结构。
纯curl实现POST推送的完整可执行流程

第一步:完成前置引用协商

Git的HTTP推送是两阶段交互,必须先完成协商才能进入接收状态,执行以下命令获取服务器的引用列表和支持的能力:

curl -X POST "http://<你的服务器地址>/<仓库路径>.git/git-receive-pack" \
  -H "Content-Type: application/x-git-receive-pack-request" \
  -H "Accept: application/x-git-receive-pack-result" \
  -u "你的用户名:对应密码" \
  --data ""
  • 该请求返回的是pkt-line格式的内容,包含服务器当前所有分支的commit hash、支持的推送能力列表,这部分内容是后续构造请求体的必需依据。
  • 如果没有返回正常的pkt-line内容,先核对路径、认证信息,解决路由和权限问题再继续。

第二步:构造符合协议要求的推送请求体

不要直接使用原始抓包的报文文件,请求体由三部分二进制内容拼接而成:

  1. pkt-line格式的引用更新声明
    • 每行内容前加4位十六进制长度头,计算规则为该行总字节数(包含长度头本身)的十六进制值。
    • 第一行内容格式为:<旧引用hash(新建分支填40个0)> <新生成的目标commit hash> 远端要更新的引用路径(如refs/heads/main)\0 带过来的服务器支持的能力列表
  2. 纯pack二进制内容
    从Wireshark抓包中提取纯pack的二进制数据,剔除TCP、IP、以太网帧头和HTTP头的冗余部分,这部分就是你之前生成的可被Git识别的pack文件内容。
  3. 结束分隔标记
    在请求体最后加上固定的pkt-line结束标记0000。
  • 将以上三部分按顺序拼接为单独的二进制文件push_body.bin,注意不要修改二进制内容的字节顺序。

第三步:发送正式推送请求

必须使用--data-binary参数传输二进制内容,避免curl对二进制流做格式转换:

curl -X POST "http://<你的服务器地址>/<仓库路径>.git/git-receive-pack" \
  -H "Content-Type: application/x-git-receive-pack-request" \
  -H "Accept: application/x-git-receive-pack-result" \
  -u "你的用户名:对应密码" \
  --data-binary "@push_body.bin"
  • 服务器处理完成后会返回pkt-line格式的结果,明确标注本次推送的引用更新是否成功。
  • 可直接登录服务器查看对应仓库的提交记录,验证文件是否正常生成。
常见无响应问题排查
  • 给curl命令加-v参数打印完整交互日志,根据HTTP状态码定位问题:404为路径错误、403为认证失败、200但解析失败为请求体构造错误。
  • 检查pkt-line的长度头计算是否正确,长度值错误会导致服务器直接截断报文,不会给出错误响应。
  • 确认没有跳过前置的协商请求,Smart协议的有状态交互要求必须完成协商步骤才能接收pack内容。

内容的提问来源于stack exchange,提问作者NoOneIsHere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 13:45:03