You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go使用go-github创建Git提交报错Tree SHA is not a tree object []

问题描述

使用Go语言github.com/google/go-github/github包调用GitHub Git API实现代码提交功能时,创建新提交抛出如下错误:

Tree SHA is not a tree object []

对应问题实现代码:

br, _, err := client.Repositories.GetBranch(context, "arnavbhutani09", "readmerequest", "7june")
if err != nil {
    fmt.Println(err)
    return
}
parent, _, err := client.Git.GetCommit(context, "arnavbhutani09", "readmerequest", *br.Commit.SHA)
if err != nil {
    fmt.Println(err)
    return
}
tree, _, err := client.Git.GetTree(context, "arnavbhutani09", "readmerequest", *br.Commit.SHA, false)
if err != nil {
    fmt.Println(err)
    return
}

sha2 := tree.GetSHA()
tree2 := &github.Tree{SHA: &sha2}
commit := &github.Commit{
    SHA:     &sha2,
    Message: github.String("First Commit Using APIs"),
    Tree:    tree2,
    Author: &github.CommitAuthor{
        Name:  github.String("Arnav Bhutani"),
        Email: github.String("arnavbhu@usc.edu"),
    },
}
newcommit, _, err := client.Git.CreateCommit(context, "arnavbhutani09", "readmerequest", commit)
报错根因

代码存在3处核心逻辑错误,直接触发该报错:

  • 调用GetTree时传入参数错误:该接口要求传入Tree对象的SHA,但代码直接传入了分支最新Commit的SHA,返回结果并非合法Tree对象,其SHA值本质是Commit的SHA,不属于Tree类型对象,因此API校验时抛出类型不匹配错误。实际上父Commit对象本身已经携带关联Tree的SHA,无需额外传入Commit SHA调用GetTree。
  • 新建Commit对象时手动赋值SHA字段:Git提交的SHA是根据提交元数据、Tree、父提交等内容哈希计算生成,创建新提交时不需要手动指定该字段,手动赋值会导致参数校验异常。
  • 未关联父提交:除仓库初始提交外,所有Git提交都需要指定父提交形成完整提交链,代码虽然查询了parent提交对象,但创建Commit时未传入Parents参数,会导致提交链断裂。
修复方案

按照GitHub Git API的参数规范修正逻辑即可:

  1. 直接从查询到的父Commit对象中取关联的Tree SHA,不需要额外传入Commit SHA调用GetTree接口
  2. 删除新Commit对象中手动赋值的SHA字段
  3. 给新Commit设置Parents参数,关联查询到的父提交
  4. (可选但必须)创建完新提交后,调用更新分支引用的接口,把分支指针指向新生成的提交,否则提交不会关联到对应分支,无法在分支提交历史中查到

修正后的核心代码如下:

br, _, err := client.Repositories.GetBranch(context, "arnavbhutani09", "readmerequest", "7june")
if err != nil {
    fmt.Println(err)
    return
}
// 获取分支最新的父提交
parent, _, err := client.Git.GetCommit(context, "arnavbhutani09", "readmerequest", *br.Commit.SHA)
if err != nil {
    fmt.Println(err)
    return
}

// 直接从父提交中取关联的Tree SHA
treeSHA := parent.Tree.GetSHA()
newCommit := &github.Commit{
    Message: github.String("First Commit Using APIs"),
    Tree:    &github.Tree{SHA: &treeSHA},
    Parents: []*github.Commit{{SHA: parent.SHA}}, // 关联父提交
    Author: &github.CommitAuthor{
        Name:  github.String("Arnav Bhutani"),
        Email: github.String("arnavbhu@usc.edu"),
    },
}
// 创建新提交
createdCommit, _, err := client.Git.CreateCommit(context, "arnavbhutani09", "readmerequest", newCommit)
if err != nil {
    fmt.Println(err)
    return
}

// 更新分支引用,将7june分支指向新创建的提交
ref := &github.Reference{
    Ref:    github.String("refs/heads/7june"),
    Object: &github.GitObject{SHA: createdCommit.SHA},
}
_, _, err = client.Git.UpdateRef(context, "arnavbhutani09", "readmerequest", ref, false)
if err != nil {
    fmt.Println(err)
    return
}

如果需要修改提交中的文件内容,不能直接复用父提交的Tree,需要先创建新的Tree对象,传入修改后的文件条目,再拿新生成的Tree SHA创建提交即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:09:58