...

Source file src/github.com/google/go-github/v55/github/repos_commits.go

Documentation: github.com/google/go-github/v55/github

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

View as plain text