github.com/google/go-github/v33@v33.0.0/github/repos_commits.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "bytes" 10 "context" 11 "fmt" 12 "time" 13 ) 14 15 // RepositoryCommit represents a commit in a repo. 16 // Note that it's wrapping a Commit, so author/committer information is in two places, 17 // but contain different details about them: in RepositoryCommit "github details", in Commit - "git details". 18 type RepositoryCommit struct { 19 NodeID *string `json:"node_id,omitempty"` 20 SHA *string `json:"sha,omitempty"` 21 Commit *Commit `json:"commit,omitempty"` 22 Author *User `json:"author,omitempty"` 23 Committer *User `json:"committer,omitempty"` 24 Parents []*Commit `json:"parents,omitempty"` 25 HTMLURL *string `json:"html_url,omitempty"` 26 URL *string `json:"url,omitempty"` 27 CommentsURL *string `json:"comments_url,omitempty"` 28 29 // Details about how many changes were made in this commit. Only filled in during GetCommit! 30 Stats *CommitStats `json:"stats,omitempty"` 31 // Details about which files, and how this commit touched. Only filled in during GetCommit! 32 Files []*CommitFile `json:"files,omitempty"` 33 } 34 35 func (r RepositoryCommit) String() string { 36 return Stringify(r) 37 } 38 39 // CommitStats represents the number of additions / deletions from a file in a given RepositoryCommit or GistCommit. 40 type CommitStats struct { 41 Additions *int `json:"additions,omitempty"` 42 Deletions *int `json:"deletions,omitempty"` 43 Total *int `json:"total,omitempty"` 44 } 45 46 func (c CommitStats) String() string { 47 return Stringify(c) 48 } 49 50 // CommitFile represents a file modified in a commit. 51 type CommitFile struct { 52 SHA *string `json:"sha,omitempty"` 53 Filename *string `json:"filename,omitempty"` 54 Additions *int `json:"additions,omitempty"` 55 Deletions *int `json:"deletions,omitempty"` 56 Changes *int `json:"changes,omitempty"` 57 Status *string `json:"status,omitempty"` 58 Patch *string `json:"patch,omitempty"` 59 BlobURL *string `json:"blob_url,omitempty"` 60 RawURL *string `json:"raw_url,omitempty"` 61 ContentsURL *string `json:"contents_url,omitempty"` 62 PreviousFilename *string `json:"previous_filename,omitempty"` 63 } 64 65 func (c CommitFile) String() string { 66 return Stringify(c) 67 } 68 69 // CommitsComparison is the result of comparing two commits. 70 // See CompareCommits() for details. 71 type CommitsComparison struct { 72 BaseCommit *RepositoryCommit `json:"base_commit,omitempty"` 73 MergeBaseCommit *RepositoryCommit `json:"merge_base_commit,omitempty"` 74 75 // Head can be 'behind' or 'ahead' 76 Status *string `json:"status,omitempty"` 77 AheadBy *int `json:"ahead_by,omitempty"` 78 BehindBy *int `json:"behind_by,omitempty"` 79 TotalCommits *int `json:"total_commits,omitempty"` 80 81 Commits []*RepositoryCommit `json:"commits,omitempty"` 82 83 Files []*CommitFile `json:"files,omitempty"` 84 85 HTMLURL *string `json:"html_url,omitempty"` 86 PermalinkURL *string `json:"permalink_url,omitempty"` 87 DiffURL *string `json:"diff_url,omitempty"` 88 PatchURL *string `json:"patch_url,omitempty"` 89 URL *string `json:"url,omitempty"` // API URL. 90 } 91 92 func (c CommitsComparison) String() string { 93 return Stringify(c) 94 } 95 96 // CommitsListOptions specifies the optional parameters to the 97 // RepositoriesService.ListCommits method. 98 type CommitsListOptions struct { 99 // SHA or branch to start listing Commits from. 100 SHA string `url:"sha,omitempty"` 101 102 // Path that should be touched by the returned Commits. 103 Path string `url:"path,omitempty"` 104 105 // Author of by which to filter Commits. 106 Author string `url:"author,omitempty"` 107 108 // Since when should Commits be included in the response. 109 Since time.Time `url:"since,omitempty"` 110 111 // Until when should Commits be included in the response. 112 Until time.Time `url:"until,omitempty"` 113 114 ListOptions 115 } 116 117 // BranchCommit is the result of listing branches with commit SHA. 118 type BranchCommit struct { 119 Name *string `json:"name,omitempty"` 120 Commit *Commit `json:"commit,omitempty"` 121 Protected *bool `json:"protected,omitempty"` 122 } 123 124 // ListCommits lists the commits of a repository. 125 // 126 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-commits 127 func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opts *CommitsListOptions) ([]*RepositoryCommit, *Response, error) { 128 u := fmt.Sprintf("repos/%v/%v/commits", owner, repo) 129 u, err := addOptions(u, opts) 130 if err != nil { 131 return nil, nil, err 132 } 133 134 req, err := s.client.NewRequest("GET", u, nil) 135 if err != nil { 136 return nil, nil, err 137 } 138 139 var commits []*RepositoryCommit 140 resp, err := s.client.Do(ctx, req, &commits) 141 if err != nil { 142 return nil, resp, err 143 } 144 145 return commits, resp, nil 146 } 147 148 // GetCommit fetches the specified commit, including all details about it. 149 // 150 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-single-commit 151 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-commit 152 func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha string) (*RepositoryCommit, *Response, error) { 153 u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) 154 155 req, err := s.client.NewRequest("GET", u, nil) 156 if err != nil { 157 return nil, nil, err 158 } 159 160 commit := new(RepositoryCommit) 161 resp, err := s.client.Do(ctx, req, commit) 162 if err != nil { 163 return nil, resp, err 164 } 165 166 return commit, resp, nil 167 } 168 169 // GetCommitRaw fetches the specified commit in raw (diff or patch) format. 170 // 171 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-commit 172 func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opts RawOptions) (string, *Response, error) { 173 u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) 174 req, err := s.client.NewRequest("GET", u, nil) 175 if err != nil { 176 return "", nil, err 177 } 178 179 switch opts.Type { 180 case Diff: 181 req.Header.Set("Accept", mediaTypeV3Diff) 182 case Patch: 183 req.Header.Set("Accept", mediaTypeV3Patch) 184 default: 185 return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type) 186 } 187 188 var buf bytes.Buffer 189 resp, err := s.client.Do(ctx, req, &buf) 190 if err != nil { 191 return "", resp, err 192 } 193 194 return buf.String(), resp, nil 195 } 196 197 // GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is 198 // supplied and no new commits have occurred, a 304 Unmodified response is returned. 199 // 200 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-commit 201 func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) { 202 u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, refURLEscape(ref)) 203 204 req, err := s.client.NewRequest("GET", u, nil) 205 if err != nil { 206 return "", nil, err 207 } 208 if lastSHA != "" { 209 req.Header.Set("If-None-Match", `"`+lastSHA+`"`) 210 } 211 212 req.Header.Set("Accept", mediaTypeV3SHA) 213 214 var buf bytes.Buffer 215 resp, err := s.client.Do(ctx, req, &buf) 216 if err != nil { 217 return "", resp, err 218 } 219 220 return buf.String(), resp, nil 221 } 222 223 // CompareCommits compares a range of commits with each other. 224 // 225 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#compare-two-commits 226 func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo string, base, head string) (*CommitsComparison, *Response, error) { 227 u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head) 228 229 req, err := s.client.NewRequest("GET", u, nil) 230 if err != nil { 231 return nil, nil, err 232 } 233 234 comp := new(CommitsComparison) 235 resp, err := s.client.Do(ctx, req, comp) 236 if err != nil { 237 return nil, resp, err 238 } 239 240 return comp, resp, nil 241 } 242 243 // CompareCommitsRaw compares a range of commits with each other in raw (diff or patch) format. 244 // 245 // Both "base" and "head" must be branch names in "repo". 246 // To compare branches across other repositories in the same network as "repo", 247 // use the format "<USERNAME>:branch". 248 // 249 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#compare-two-commits 250 func (s *RepositoriesService) CompareCommitsRaw(ctx context.Context, owner, repo, base, head string, opts RawOptions) (string, *Response, error) { 251 u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head) 252 req, err := s.client.NewRequest("GET", u, nil) 253 if err != nil { 254 return "", nil, err 255 } 256 257 switch opts.Type { 258 case Diff: 259 req.Header.Set("Accept", mediaTypeV3Diff) 260 case Patch: 261 req.Header.Set("Accept", mediaTypeV3Patch) 262 default: 263 return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type) 264 } 265 266 var buf bytes.Buffer 267 resp, err := s.client.Do(ctx, req, &buf) 268 if err != nil { 269 return "", resp, err 270 } 271 272 return buf.String(), resp, nil 273 } 274 275 // ListBranchesHeadCommit gets all branches where the given commit SHA is the HEAD, 276 // or latest commit for the branch. 277 // 278 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#list-branches-for-head-commit 279 func (s *RepositoriesService) ListBranchesHeadCommit(ctx context.Context, owner, repo, sha string) ([]*BranchCommit, *Response, error) { 280 u := fmt.Sprintf("repos/%v/%v/commits/%v/branches-where-head", owner, repo, sha) 281 282 req, err := s.client.NewRequest("GET", u, nil) 283 if err != nil { 284 return nil, nil, err 285 } 286 287 // TODO: remove custom Accept header when this API fully launches. 288 req.Header.Set("Accept", mediaTypeListPullsOrBranchesForCommitPreview) 289 var branchCommits []*BranchCommit 290 resp, err := s.client.Do(ctx, req, &branchCommits) 291 if err != nil { 292 return nil, resp, err 293 } 294 295 return branchCommits, resp, nil 296 }