如何使用Go获取GitHub仓库中指定文件的提交历史
用Go获取GitHub特定文件的提交历史记录
1. 使用GitHub官方Go SDK(go-github)
- 先安装依赖包:
go get github.com/google/go-github/v56/github - 示例代码:
package main import ( "context" "fmt" "os" "github.com/google/go-github/v56/github" "golang.org/x/oauth2" ) func main() { // 私有仓库需填入GitHub Token,公开仓库可留空 token := os.Getenv("GITHUB_TOKEN") ctx := context.Background() ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) tc := oauth2.NewClient(ctx, ts) client := github.NewClient(tc) // 配置目标仓库和文件信息 owner := "golang" repo := "go" targetFile := "README.md" // 获取仅修改该文件的提交历史,可通过Page/PerPage控制分页 commits, _, err := client.Repositories.ListCommits(ctx, owner, repo, &github.CommitsListOptions{ Path: targetFile, }) if err != nil { fmt.Printf("获取提交历史失败: %v\n", err) return } // 输出提交详情 for _, commit := range commits { fmt.Printf("提交SHA: %s\n", *commit.SHA) fmt.Printf("作者: %s <%s>\n", *commit.Commit.Author.Name, *commit.Commit.Author.Email) fmt.Printf("提交时间: %s\n", commit.Commit.Author.Date.Format("2006-01-02 15:04:05")) fmt.Printf("提交信息: %s\n\n", *commit.Commit.Message) } } - 说明:
- 借助
go-github封装的ListCommits接口,通过Path参数精准过滤修改目标文件的提交 - 公开仓库无Token也能访问,但请求频率受限;私有仓库必须提供GitHub Token(在账号设置中生成)
- 借助
2. 直接调用GitHub REST API(无第三方依赖)
- 示例代码:
package main import ( "encoding/json" "fmt" "io" "net/http" "os" ) type Commit struct { SHA string `json:"sha"` Commit struct { Author struct { Name string `json:"name"` Email string `json:"email"` Date string `json:"date"` } `json:"author"` Message string `json:"message"` } `json:"commit"` } func main() { owner := "golang" repo := "go" targetFile := "README.md" apiURL := fmt.Sprintf("https://api.github.com/repos/%s/%s/commits?path=%s", owner, repo, targetFile) req, err := http.NewRequest("GET", apiURL, nil) if err != nil { fmt.Printf("创建请求失败: %v\n", err) return } // 可选:添加Token提升请求限制 if token := os.Getenv("GITHUB_TOKEN"); token != "" { req.Header.Set("Authorization", "token "+token) } client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Printf("发送请求失败: %v\n", err) return } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) fmt.Printf("请求失败,状态码: %d,响应: %s\n", resp.StatusCode, string(body)) return } var commits []Commit if err := json.NewDecoder(resp.Body).Decode(&commits); err != nil { fmt.Printf("解析响应失败: %v\n", err) return } for _, commit := range commits { fmt.Printf("提交SHA: %s\n", commit.SHA) fmt.Printf("作者: %s <%s>\n", commit.Commit.Author.Name, commit.Commit.Author.Email) fmt.Printf("提交时间: %s\n", commit.Commit.Author.Date) fmt.Printf("提交信息: %s\n\n", commit.Commit.Message) } } - 说明:
- 直接请求GitHub的
/repos/{owner}/{repo}/commits接口,通过path参数过滤目标文件的提交 - 手动处理JSON响应解析,字段需与API返回结构完全匹配
- 直接请求GitHub的
内容的提问来源于stack exchange,提问作者user1403806
相关产品推荐
相关产品推荐

