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的参数规范修正逻辑即可:
- 直接从查询到的父Commit对象中取关联的Tree SHA,不需要额外传入Commit SHA调用GetTree接口
- 删除新Commit对象中手动赋值的SHA字段
- 给新Commit设置Parents参数,关联查询到的父提交
- (可选但必须)创建完新提交后,调用更新分支引用的接口,把分支指针指向新生成的提交,否则提交不会关联到对应分支,无法在分支提交历史中查到
修正后的核心代码如下:
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
相关产品推荐
相关产品推荐

