diff --git a/github/github.go b/github/github.go index 640aec7..2c7575d 100644 --- a/github/github.go +++ b/github/github.go @@ -59,6 +59,9 @@ const ( // https://developer.github.com/changes/2016-02-11-issue-locking-api/ mediaTypeIssueLockingPreview = "application/vnd.github.the-key-preview+json" + + // https://developer.github.com/changes/2016-02-24-commit-reference-sha-api/ + mediaTypeCommitReferenceSHAPreview = "application/vnd.github.chitauri-preview+sha" ) // A Client manages communication with the GitHub API. diff --git a/github/repos_commits.go b/github/repos_commits.go index 6401cb4..4c19c2f 100644 --- a/github/repos_commits.go +++ b/github/repos_commits.go @@ -6,6 +6,7 @@ package github import ( + "bytes" "fmt" "time" ) @@ -146,6 +147,33 @@ func (s *RepositoriesService) GetCommit(owner, repo, sha string) (*RepositoryCom return commit, resp, err } +// GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is +// supplied and no new commits have occurred, a 304 Unmodified response is returned. +// +// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference +func (s *RepositoriesService) GetCommitSHA1(owner, repo, ref, lastSHA string) (string, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, ref) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return "", nil, err + } + if lastSHA != "" { + req.Header.Set("If-None-Match", `"`+lastSHA+`"`) + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeCommitReferenceSHAPreview) + + var buf bytes.Buffer + resp, err := s.client.Do(req, &buf) + if err != nil { + return "", resp, err + } + + return buf.String(), resp, err +} + // CompareCommits compares a range of commits with each other. // todo: support media formats - https://github.com/google/go-github/issues/6 // diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go index 56ba8a5..3e807b6 100644 --- a/github/repos_commits_test.go +++ b/github/repos_commits_test.go @@ -119,6 +119,47 @@ func TestRepositoriesService_GetCommit(t *testing.T) { } } +func TestRepositoriesService_GetCommitSHA1(t *testing.T) { + setup() + defer teardown() + const sha1 = "01234abcde" + + mux.HandleFunc("/repos/o/r/commits/master", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeCommitReferenceSHAPreview) + + fmt.Fprintf(w, sha1) + }) + + got, _, err := client.Repositories.GetCommitSHA1("o", "r", "master", "") + if err != nil { + t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) + } + + want := sha1 + if got != want { + t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) + } + + mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeCommitReferenceSHAPreview) + testHeader(t, r, "If-None-Match", `"`+sha1+`"`) + + w.WriteHeader(http.StatusNotModified) + }) + + got, _, err = client.Repositories.GetCommitSHA1("o", "r", "tag", sha1) + if err == nil { + t.Errorf("Expected HTTP 304 response") + } + + want = "" + if got != want { + t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) + } +} + func TestRepositoriesService_CompareCommits(t *testing.T) { setup() defer teardown()