Repository: google/go-github
Pull request #1233 (2019-07-19 22:27:48)

Use time.Until
Instead of manually subtracting the timestamps, we can just use time.Until.

codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=h1) Report
> Merging [#1233](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=desc) into [master](https://codecov.io/gh/google/go-github/commit/955a14c8ede799deb6529c0dc9b5b0b27d19a8bd?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `0%`.

[![Impacted file tree graph](https://codecov.io/gh/google/go-github/pull/1233/graphs/tree.svg?width=650&token=EgYjGjZlI0&height=150&src=pr)](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #1233   +/-   ##
=======================================
  Coverage   73.36%   73.36%           
=======================================
  Files          86       86           
  Lines        6026     6026           
=======================================
  Hits         4421     4421           
  Misses        836      836           
  Partials      769      769
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [github/github.go](https://codecov.io/gh/google/go-github/pull/1233/diff?src=pr&el=tree#diff-Z2l0aHViL2dpdGh1Yi5nbw==) | `89.31% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=footer). Last update [955a14c...695adab](https://codecov.io/gh/google/go-github/pull/1233?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

gmlewis: Fine by me.  Thanks, @muesli.

Awaiting second LGTM before merging.

Patch:
diff --git a/github/github-accessors.go b/github/github-accessors.go
index b4ca033d..13e60abb 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -9612,6 +9612,14 @@ func (r *Repository) GetIssuesURL() string {
 	return *r.IssuesURL
 }
 
+// GetIsTemplate returns the IsTemplate field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIsTemplate() bool {
+	if r == nil || r.IsTemplate == nil {
+		return false
+	}
+	return *r.IsTemplate
+}
+
 // GetKeysURL returns the KeysURL field if it's non-nil, zero value otherwise.
 func (r *Repository) GetKeysURL() string {
 	if r == nil || r.KeysURL == nil {
@@ -9900,6 +9908,14 @@ func (r *Repository) GetTeamsURL() string {
 	return *r.TeamsURL
 }
 
+// GetTemplateRepository returns the TemplateRepository field.
+func (r *Repository) GetTemplateRepository() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.TemplateRepository
+}
+
 // GetTreesURL returns the TreesURL field if it's non-nil, zero value otherwise.
 func (r *Repository) GetTreesURL() string {
 	if r == nil || r.TreesURL == nil {
@@ -11668,6 +11684,38 @@ func (t *TeamProjectOptions) GetPermission() string {
 	return *t.Permission
 }
 
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (t *TemplateRepoRequest) GetDescription() string {
+	if t == nil || t.Description == nil {
+		return ""
+	}
+	return *t.Description
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *TemplateRepoRequest) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetOwner returns the Owner field if it's non-nil, zero value otherwise.
+func (t *TemplateRepoRequest) GetOwner() string {
+	if t == nil || t.Owner == nil {
+		return ""
+	}
+	return *t.Owner
+}
+
+// GetPrivate returns the Private field if it's non-nil, zero value otherwise.
+func (t *TemplateRepoRequest) GetPrivate() bool {
+	if t == nil || t.Private == nil {
+		return false
+	}
+	return *t.Private
+}
+
 // GetFragment returns the Fragment field if it's non-nil, zero value otherwise.
 func (t *TextMatch) GetFragment() string {
 	if t == nil || t.Fragment == nil {
diff --git a/github/github.go b/github/github.go
index 7a82677c..6ab801f2 100644
--- a/github/github.go
+++ b/github/github.go
@@ -153,6 +153,9 @@ const (
 
 	// https://developer.github.com/v3/previews/#repository-creation-permissions
 	mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json"
+
+	// https://developer.github.com/v3/previews/#create-and-use-repository-templates
+	mediaTypeRepositoryTemplatePreview = "application/vnd.github.baptiste-preview+json"
 )
 
 // A Client manages communication with the GitHub API.
@@ -646,7 +649,7 @@ type RateLimitError struct {
 func (r *RateLimitError) Error() string {
 	return fmt.Sprintf("%v %v: %d %v %v",
 		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
-		r.Response.StatusCode, r.Message, formatRateReset(r.Rate.Reset.Time.Sub(time.Now())))
+		r.Response.StatusCode, r.Message, formatRateReset(time.Until(r.Rate.Reset.Time)))
 }
 
 // AcceptedError occurs when GitHub returns 202 Accepted response with an
diff --git a/github/repos.go b/github/repos.go
index 5f44c6d8..a380f302 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -19,45 +19,46 @@ type RepositoriesService service
 
 // Repository represents a GitHub repository.
 type Repository struct {
-	ID               *int64           `json:"id,omitempty"`
-	NodeID           *string          `json:"node_id,omitempty"`
-	Owner            *User            `json:"owner,omitempty"`
-	Name             *string          `json:"name,omitempty"`
-	FullName         *string          `json:"full_name,omitempty"`
-	Description      *string          `json:"description,omitempty"`
-	Homepage         *string          `json:"homepage,omitempty"`
-	CodeOfConduct    *CodeOfConduct   `json:"code_of_conduct,omitempty"`
-	DefaultBranch    *string          `json:"default_branch,omitempty"`
-	MasterBranch     *string          `json:"master_branch,omitempty"`
-	CreatedAt        *Timestamp       `json:"created_at,omitempty"`
-	PushedAt         *Timestamp       `json:"pushed_at,omitempty"`
-	UpdatedAt        *Timestamp       `json:"updated_at,omitempty"`
-	HTMLURL          *string          `json:"html_url,omitempty"`
-	CloneURL         *string          `json:"clone_url,omitempty"`
-	GitURL           *string          `json:"git_url,omitempty"`
-	MirrorURL        *string          `json:"mirror_url,omitempty"`
-	SSHURL           *string          `json:"ssh_url,omitempty"`
-	SVNURL           *string          `json:"svn_url,omitempty"`
-	Language         *string          `json:"language,omitempty"`
-	Fork             *bool            `json:"fork,omitempty"`
-	ForksCount       *int             `json:"forks_count,omitempty"`
-	NetworkCount     *int             `json:"network_count,omitempty"`
-	OpenIssuesCount  *int             `json:"open_issues_count,omitempty"`
-	StargazersCount  *int             `json:"stargazers_count,omitempty"`
-	SubscribersCount *int             `json:"subscribers_count,omitempty"`
-	WatchersCount    *int             `json:"watchers_count,omitempty"`
-	Size             *int             `json:"size,omitempty"`
-	AutoInit         *bool            `json:"auto_init,omitempty"`
-	Parent           *Repository      `json:"parent,omitempty"`
-	Source           *Repository      `json:"source,omitempty"`
-	Organization     *Organization    `json:"organization,omitempty"`
-	Permissions      *map[string]bool `json:"permissions,omitempty"`
-	AllowRebaseMerge *bool            `json:"allow_rebase_merge,omitempty"`
-	AllowSquashMerge *bool            `json:"allow_squash_merge,omitempty"`
-	AllowMergeCommit *bool            `json:"allow_merge_commit,omitempty"`
-	Topics           []string         `json:"topics,omitempty"`
-	Archived         *bool            `json:"archived,omitempty"`
-	Disabled         *bool            `json:"disabled,omitempty"`
+	ID                 *int64           `json:"id,omitempty"`
+	NodeID             *string          `json:"node_id,omitempty"`
+	Owner              *User            `json:"owner,omitempty"`
+	Name               *string          `json:"name,omitempty"`
+	FullName           *string          `json:"full_name,omitempty"`
+	Description        *string          `json:"description,omitempty"`
+	Homepage           *string          `json:"homepage,omitempty"`
+	CodeOfConduct      *CodeOfConduct   `json:"code_of_conduct,omitempty"`
+	DefaultBranch      *string          `json:"default_branch,omitempty"`
+	MasterBranch       *string          `json:"master_branch,omitempty"`
+	CreatedAt          *Timestamp       `json:"created_at,omitempty"`
+	PushedAt           *Timestamp       `json:"pushed_at,omitempty"`
+	UpdatedAt          *Timestamp       `json:"updated_at,omitempty"`
+	HTMLURL            *string          `json:"html_url,omitempty"`
+	CloneURL           *string          `json:"clone_url,omitempty"`
+	GitURL             *string          `json:"git_url,omitempty"`
+	MirrorURL          *string          `json:"mirror_url,omitempty"`
+	SSHURL             *string          `json:"ssh_url,omitempty"`
+	SVNURL             *string          `json:"svn_url,omitempty"`
+	Language           *string          `json:"language,omitempty"`
+	Fork               *bool            `json:"fork,omitempty"`
+	ForksCount         *int             `json:"forks_count,omitempty"`
+	NetworkCount       *int             `json:"network_count,omitempty"`
+	OpenIssuesCount    *int             `json:"open_issues_count,omitempty"`
+	StargazersCount    *int             `json:"stargazers_count,omitempty"`
+	SubscribersCount   *int             `json:"subscribers_count,omitempty"`
+	WatchersCount      *int             `json:"watchers_count,omitempty"`
+	Size               *int             `json:"size,omitempty"`
+	AutoInit           *bool            `json:"auto_init,omitempty"`
+	Parent             *Repository      `json:"parent,omitempty"`
+	Source             *Repository      `json:"source,omitempty"`
+	TemplateRepository *Repository      `json:"template_repository,omitempty"`
+	Organization       *Organization    `json:"organization,omitempty"`
+	Permissions        *map[string]bool `json:"permissions,omitempty"`
+	AllowRebaseMerge   *bool            `json:"allow_rebase_merge,omitempty"`
+	AllowSquashMerge   *bool            `json:"allow_squash_merge,omitempty"`
+	AllowMergeCommit   *bool            `json:"allow_merge_commit,omitempty"`
+	Topics             []string         `json:"topics,omitempty"`
+	Archived           *bool            `json:"archived,omitempty"`
+	Disabled           *bool            `json:"disabled,omitempty"`
 
 	// Only provided when using RepositoriesService.Get while in preview
 	License *License `json:"license,omitempty"`
@@ -69,6 +70,7 @@ type Repository struct {
 	HasPages          *bool   `json:"has_pages,omitempty"`
 	HasProjects       *bool   `json:"has_projects,omitempty"`
 	HasDownloads      *bool   `json:"has_downloads,omitempty"`
+	IsTemplate        *bool   `json:"is_template,omitempty"`
 	LicenseTemplate   *string `json:"license_template,omitempty"`
 	GitignoreTemplate *string `json:"gitignore_template,omitempty"`
 
@@ -275,6 +277,7 @@ type createRepoRequest struct {
 	HasIssues   *bool `json:"has_issues,omitempty"`
 	HasProjects *bool `json:"has_projects,omitempty"`
 	HasWiki     *bool `json:"has_wiki,omitempty"`
+	IsTemplate  *bool `json:"is_template,omitempty"`
 
 	// Creating an organization repository. Required for non-owners.
 	TeamID *int64 `json:"team_id,omitempty"`
@@ -311,6 +314,7 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
 		HasIssues:         repo.HasIssues,
 		HasProjects:       repo.HasProjects,
 		HasWiki:           repo.HasWiki,
+		IsTemplate:        repo.IsTemplate,
 		TeamID:            repo.TeamID,
 		AutoInit:          repo.AutoInit,
 		GitignoreTemplate: repo.GitignoreTemplate,
@@ -325,6 +329,38 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
 		return nil, nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview)
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// TemplateRepoRequest represents a request to create a repository from a template.
+type TemplateRepoRequest struct {
+	// Name is required when creating a repo.
+	Name        *string `json:"name,omitempty"`
+	Owner       *string `json:"owner,omitempty"`
+	Description *string `json:"description,omitempty"`
+
+	Private *bool `json:"private,omitempty"`
+}
+
+// CreateFromTemplate generates a repository from a template.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#create-repository-using-a-repository-template
+func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOwner, templateRepo string, templateRepoReq *TemplateRepoRequest) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/generate", templateOwner, templateRepo)
+
+	req, err := s.client.NewRequest("POST", u, templateRepoReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview)
 	r := new(Repository)
 	resp, err := s.client.Do(ctx, req, r)
 	if err != nil {
@@ -346,7 +382,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep
 
 	// TODO: remove custom Accept header when the license support fully launches
 	// https://developer.github.com/v3/licenses/#get-a-repositorys-license
-	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	repository := new(Repository)
@@ -409,6 +445,7 @@ func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repo
 		return nil, nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeRepositoryTemplatePreview)
 	r := new(Repository)
 	resp, err := s.client.Do(ctx, req, r)
 	if err != nil {


Test patch:
diff --git a/github/activity_test.go b/github/activity_test.go
index 9c4e566f..b577118a 100644
--- a/github/activity_test.go
+++ b/github/activity_test.go
@@ -25,7 +25,7 @@ func TestActivityService_List(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Activity.ListFeeds(ctx)
+	got, _, err := client.Activity.ListFeeds(ctx)
 	if err != nil {
 		t.Errorf("Activity.ListFeeds returned error: %v", err)
 	}
@@ -35,7 +35,7 @@ func TestActivityService_List(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Activity.ListFeeds(ctx)
+	got, resp, err := client.Activity.ListFeeds(ctx)
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListFeeds = %#v, want nil", got)
 	}
diff --git a/github/git_commits_test.go b/github/git_commits_test.go
index 580e6b05..f316f01e 100644
--- a/github/git_commits_test.go
+++ b/github/git_commits_test.go
@@ -146,6 +146,9 @@ func TestGitService_CreateSignedCommitWithKey(t *testing.T) {
 	defer teardown()
 	s := strings.NewReader(testGPGKey)
 	keyring, err := openpgp.ReadArmoredKeyRing(s)
+	if err != nil {
+		t.Errorf("Error reading keyring: %+v", err)
+	}
 
 	date, _ := time.Parse("Mon Jan 02 15:04:05 2006 -0700", "Thu May 04 00:03:43 2017 +0200")
 	author := CommitAuthor{
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index f424531e..c91f7b5a 100644
--- a/github/github-stringify_test.go
+++ b/github/github-stringify_test.go
@@ -1167,92 +1167,94 @@ func TestRepoStatus_String(t *testing.T) {
 
 func TestRepository_String(t *testing.T) {
 	v := Repository{
-		ID:                Int64(0),
-		NodeID:            String(""),
-		Owner:             &User{},
-		Name:              String(""),
-		FullName:          String(""),
-		Description:       String(""),
-		Homepage:          String(""),
-		CodeOfConduct:     &CodeOfConduct{},
-		DefaultBranch:     String(""),
-		MasterBranch:      String(""),
-		CreatedAt:         &Timestamp{},
-		PushedAt:          &Timestamp{},
-		UpdatedAt:         &Timestamp{},
-		HTMLURL:           String(""),
-		CloneURL:          String(""),
-		GitURL:            String(""),
-		MirrorURL:         String(""),
-		SSHURL:            String(""),
-		SVNURL:            String(""),
-		Language:          String(""),
-		Fork:              Bool(false),
-		ForksCount:        Int(0),
-		NetworkCount:      Int(0),
-		OpenIssuesCount:   Int(0),
-		StargazersCount:   Int(0),
-		SubscribersCount:  Int(0),
-		WatchersCount:     Int(0),
-		Size:              Int(0),
-		AutoInit:          Bool(false),
-		Parent:            &Repository{},
-		Source:            &Repository{},
-		Organization:      &Organization{},
-		AllowRebaseMerge:  Bool(false),
-		AllowSquashMerge:  Bool(false),
-		AllowMergeCommit:  Bool(false),
-		Archived:          Bool(false),
-		Disabled:          Bool(false),
-		License:           &License{},
-		Private:           Bool(false),
-		HasIssues:         Bool(false),
-		HasWiki:           Bool(false),
-		HasPages:          Bool(false),
-		HasProjects:       Bool(false),
-		HasDownloads:      Bool(false),
-		LicenseTemplate:   String(""),
-		GitignoreTemplate: String(""),
-		TeamID:            Int64(0),
-		URL:               String(""),
-		ArchiveURL:        String(""),
-		AssigneesURL:      String(""),
-		BlobsURL:          String(""),
-		BranchesURL:       String(""),
-		CollaboratorsURL:  String(""),
-		CommentsURL:       String(""),
-		CommitsURL:        String(""),
-		CompareURL:        String(""),
-		ContentsURL:       String(""),
-		ContributorsURL:   String(""),
-		DeploymentsURL:    String(""),
-		DownloadsURL:      String(""),
-		EventsURL:         String(""),
-		ForksURL:          String(""),
-		GitCommitsURL:     String(""),
-		GitRefsURL:        String(""),
-		GitTagsURL:        String(""),
-		HooksURL:          String(""),
-		IssueCommentURL:   String(""),
-		IssueEventsURL:    String(""),
-		IssuesURL:         String(""),
-		KeysURL:           String(""),
-		LabelsURL:         String(""),
-		LanguagesURL:      String(""),
-		MergesURL:         String(""),
-		MilestonesURL:     String(""),
-		NotificationsURL:  String(""),
-		PullsURL:          String(""),
-		ReleasesURL:       String(""),
-		StargazersURL:     String(""),
-		StatusesURL:       String(""),
-		SubscribersURL:    String(""),
-		SubscriptionURL:   String(""),
-		TagsURL:           String(""),
-		TreesURL:          String(""),
-		TeamsURL:          String(""),
-	}
-	want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}`
+		ID:                 Int64(0),
+		NodeID:             String(""),
+		Owner:              &User{},
+		Name:               String(""),
+		FullName:           String(""),
+		Description:        String(""),
+		Homepage:           String(""),
+		CodeOfConduct:      &CodeOfConduct{},
+		DefaultBranch:      String(""),
+		MasterBranch:       String(""),
+		CreatedAt:          &Timestamp{},
+		PushedAt:           &Timestamp{},
+		UpdatedAt:          &Timestamp{},
+		HTMLURL:            String(""),
+		CloneURL:           String(""),
+		GitURL:             String(""),
+		MirrorURL:          String(""),
+		SSHURL:             String(""),
+		SVNURL:             String(""),
+		Language:           String(""),
+		Fork:               Bool(false),
+		ForksCount:         Int(0),
+		NetworkCount:       Int(0),
+		OpenIssuesCount:    Int(0),
+		StargazersCount:    Int(0),
+		SubscribersCount:   Int(0),
+		WatchersCount:      Int(0),
+		Size:               Int(0),
+		AutoInit:           Bool(false),
+		Parent:             &Repository{},
+		Source:             &Repository{},
+		TemplateRepository: &Repository{},
+		Organization:       &Organization{},
+		AllowRebaseMerge:   Bool(false),
+		AllowSquashMerge:   Bool(false),
+		AllowMergeCommit:   Bool(false),
+		Archived:           Bool(false),
+		Disabled:           Bool(false),
+		License:            &License{},
+		Private:            Bool(false),
+		HasIssues:          Bool(false),
+		HasWiki:            Bool(false),
+		HasPages:           Bool(false),
+		HasProjects:        Bool(false),
+		HasDownloads:       Bool(false),
+		IsTemplate:         Bool(false),
+		LicenseTemplate:    String(""),
+		GitignoreTemplate:  String(""),
+		TeamID:             Int64(0),
+		URL:                String(""),
+		ArchiveURL:         String(""),
+		AssigneesURL:       String(""),
+		BlobsURL:           String(""),
+		BranchesURL:        String(""),
+		CollaboratorsURL:   String(""),
+		CommentsURL:        String(""),
+		CommitsURL:         String(""),
+		CompareURL:         String(""),
+		ContentsURL:        String(""),
+		ContributorsURL:    String(""),
+		DeploymentsURL:     String(""),
+		DownloadsURL:       String(""),
+		EventsURL:          String(""),
+		ForksURL:           String(""),
+		GitCommitsURL:      String(""),
+		GitRefsURL:         String(""),
+		GitTagsURL:         String(""),
+		HooksURL:           String(""),
+		IssueCommentURL:    String(""),
+		IssueEventsURL:     String(""),
+		IssuesURL:          String(""),
+		KeysURL:            String(""),
+		LabelsURL:          String(""),
+		LanguagesURL:       String(""),
+		MergesURL:          String(""),
+		MilestonesURL:      String(""),
+		NotificationsURL:   String(""),
+		PullsURL:           String(""),
+		ReleasesURL:        String(""),
+		StargazersURL:      String(""),
+		StatusesURL:        String(""),
+		SubscribersURL:     String(""),
+		SubscriptionURL:    String(""),
+		TagsURL:            String(""),
+		TreesURL:           String(""),
+		TeamsURL:           String(""),
+	}
+	want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:""}`
 	if got := v.String(); got != want {
 		t.Errorf("Repository.String = %v, want %v", got, want)
 	}
diff --git a/github/pulls_reviewers_test.go b/github/pulls_reviewers_test.go
index 8599bd77..98d6e656 100644
--- a/github/pulls_reviewers_test.go
+++ b/github/pulls_reviewers_test.go
@@ -26,7 +26,7 @@ func TestRequestReviewers(t *testing.T) {
 
 	// This returns a PR, unmarshalling of which is tested elsewhere
 	ctx := context.Background()
-	got, resp, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}})
+	got, _, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}})
 	if err != nil {
 		t.Errorf("PullRequests.RequestReviewers returned error: %v", err)
 	}
@@ -37,7 +37,7 @@ func TestRequestReviewers(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}})
+	got, resp, err := client.PullRequests.RequestReviewers(ctx, "o", "r", 1, ReviewersRequest{Reviewers: []string{"octocat", "googlebot"}, TeamReviewers: []string{"justice-league", "injustice-league"}})
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' RequestReviewers = %#v, want nil", got)
 	}
@@ -99,7 +99,7 @@ func TestListReviewers(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil)
+	got, _, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil)
 	if err != nil {
 		t.Errorf("PullRequests.ListReviewers returned error: %v", err)
 	}
@@ -124,7 +124,7 @@ func TestListReviewers(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil)
+	got, resp, err := client.PullRequests.ListReviewers(ctx, "o", "r", 1, nil)
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListReviewers = %#v, want nil", got)
 	}
diff --git a/github/repos_test.go b/github/repos_test.go
index ebc1d8a7..75ccbb0d 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -28,7 +28,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.List(ctx, "", nil)
+	got, _, err := client.Repositories.List(ctx, "", nil)
 	if err != nil {
 		t.Errorf("Repositories.List returned error: %v", err)
 	}
@@ -39,7 +39,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) {
 	}
 
 	// Test addOptions failure
-	got, resp, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{})
+	_, _, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{})
 	if err == nil {
 		t.Error("bad options List err = nil, want error")
 	}
@@ -47,7 +47,7 @@ func TestRepositoriesService_List_authenticatedUser(t *testing.T) {
 	// Test s.client.Do failure
 	client.BaseURL.Path = "/api-v3/"
 	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
-	got, resp, err = client.Repositories.List(ctx, "", nil)
+	got, resp, err := client.Repositories.List(ctx, "", nil)
 	if got != nil {
 		t.Errorf("rate.Reset.Time > now List = %#v, want nil", got)
 	}
@@ -148,7 +148,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) {
 
 	ctx := context.Background()
 	opt := &RepositoryListByOrgOptions{"forks", ListOptions{Page: 2}}
-	got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt)
+	got, _, err := client.Repositories.ListByOrg(ctx, "o", opt)
 	if err != nil {
 		t.Errorf("Repositories.ListByOrg returned error: %v", err)
 	}
@@ -159,7 +159,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) {
 	}
 
 	// Test addOptions failure
-	got, resp, err = client.Repositories.ListByOrg(ctx, "\n", opt)
+	_, _, err = client.Repositories.ListByOrg(ctx, "\n", opt)
 	if err == nil {
 		t.Error("bad options ListByOrg err = nil, want error")
 	}
@@ -167,7 +167,7 @@ func TestRepositoriesService_ListByOrg(t *testing.T) {
 	// Test s.client.Do failure
 	client.BaseURL.Path = "/api-v3/"
 	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
-	got, resp, err = client.Repositories.ListByOrg(ctx, "o", opt)
+	got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt)
 	if got != nil {
 		t.Errorf("rate.Reset.Time > now ListByOrg = %#v, want nil", got)
 	}
@@ -201,7 +201,7 @@ func TestRepositoriesService_ListAll(t *testing.T) {
 
 	ctx := context.Background()
 	opt := &RepositoryListAllOptions{1}
-	got, resp, err := client.Repositories.ListAll(ctx, opt)
+	got, _, err := client.Repositories.ListAll(ctx, opt)
 	if err != nil {
 		t.Errorf("Repositories.ListAll returned error: %v", err)
 	}
@@ -213,7 +213,7 @@ func TestRepositoriesService_ListAll(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1})
+	got, resp, err := client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1})
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListAll = %#v, want nil", got)
 	}
@@ -253,6 +253,7 @@ func TestRepositoriesService_Create_user(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview)
 		want := &createRepoRequest{Name: String("n")}
 		if !reflect.DeepEqual(v, want) {
 			t.Errorf("Request body = %+v, want %+v", v, want)
@@ -262,7 +263,7 @@ func TestRepositoriesService_Create_user(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.Create(ctx, "", input)
+	got, _, err := client.Repositories.Create(ctx, "", input)
 	if err != nil {
 		t.Errorf("Repositories.Create returned error: %v", err)
 	}
@@ -274,7 +275,7 @@ func TestRepositoriesService_Create_user(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.Create(ctx, "", input)
+	got, resp, err := client.Repositories.Create(ctx, "", input)
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' Create = %#v, want nil", got)
 	}
@@ -314,6 +315,7 @@ func TestRepositoriesService_Create_org(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview)
 		want := &createRepoRequest{Name: String("n")}
 		if !reflect.DeepEqual(v, want) {
 			t.Errorf("Request body = %+v, want %+v", v, want)
@@ -333,11 +335,72 @@ func TestRepositoriesService_Create_org(t *testing.T) {
 	}
 }
 
+func TestRepositoriesService_CreateFromTemplate(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	templateRepoReq := &TemplateRepoRequest{
+		Name: String("n"),
+	}
+
+	mux.HandleFunc("/repos/to/tr/generate", func(w http.ResponseWriter, r *http.Request) {
+		v := new(TemplateRepoRequest)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview)
+		want := &TemplateRepoRequest{Name: String("n")}
+		if !reflect.DeepEqual(v, want) {
+			t.Errorf("Request body = %+v, want %+v", v, want)
+		}
+
+		fmt.Fprint(w, `{"id":1,"name":"n"}`)
+	})
+
+	ctx := context.Background()
+	got, _, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq)
+	if err != nil {
+		t.Errorf("Repositories.CreateFromTemplate returned error: %v", err)
+	}
+
+	want := &Repository{ID: Int64(1), Name: String("n")}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Repositories.CreateFromTemplate returned %+v, want %+v", got, want)
+	}
+
+	// Test s.client.NewRequest failure
+	client.BaseURL.Path = ""
+	got, resp, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq)
+	if got != nil {
+		t.Errorf("client.BaseURL.Path='' CreateFromTemplate = %#v, want nil", got)
+	}
+	if resp != nil {
+		t.Errorf("client.BaseURL.Path='' CreateFromTemplate resp = %#v, want nil", resp)
+	}
+	if err == nil {
+		t.Error("client.BaseURL.Path='' CreateFromTemplate err = nil, want error")
+	}
+
+	// Test s.client.Do failure
+	client.BaseURL.Path = "/api-v3/"
+	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
+	got, resp, err = client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq)
+	if got != nil {
+		t.Errorf("rate.Reset.Time > now CreateFromTemplate = %#v, want nil", got)
+	}
+	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
+		t.Errorf("rate.Reset.Time > now CreateFromTemplate resp = %#v, want StatusCode=%v", resp.Response, want)
+	}
+	if err == nil {
+		t.Error("rate.Reset.Time > now CreateFromTemplate err = nil, want error")
+	}
+}
+
 func TestRepositoriesService_Get(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview}
 	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -345,7 +408,7 @@ func TestRepositoriesService_Get(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.Get(ctx, "o", "r")
+	got, _, err := client.Repositories.Get(ctx, "o", "r")
 	if err != nil {
 		t.Errorf("Repositories.Get returned error: %v", err)
 	}
@@ -358,7 +421,7 @@ func TestRepositoriesService_Get(t *testing.T) {
 	// Test s.client.Do failure
 	client.BaseURL.Path = "/api-v3/"
 	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
-	got, resp, err = client.Repositories.Get(ctx, "o", "r")
+	got, resp, err := client.Repositories.Get(ctx, "o", "r")
 	if got != nil {
 		t.Errorf("rate.Reset.Time > now Get = %#v, want nil", got)
 	}
@@ -386,7 +449,7 @@ func TestRepositoriesService_GetCodeOfConduct(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
+	got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
 	if err != nil {
 		t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err)
 	}
@@ -404,7 +467,7 @@ func TestRepositoriesService_GetCodeOfConduct(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.GetCodeOfConduct(ctx, "o", "r")
+	got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' GetCodeOfConduct = %#v, want nil", got)
 	}
@@ -440,7 +503,7 @@ func TestRepositoriesService_GetByID(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.GetByID(ctx, 1)
+	got, _, err := client.Repositories.GetByID(ctx, 1)
 	if err != nil {
 		t.Fatalf("Repositories.GetByID returned error: %v", err)
 	}
@@ -452,7 +515,7 @@ func TestRepositoriesService_GetByID(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.GetByID(ctx, 1)
+	got, resp, err := client.Repositories.GetByID(ctx, 1)
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' GetByID = %#v, want nil", got)
 	}
@@ -490,6 +553,7 @@ func TestRepositoriesService_Edit(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
+		testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -497,7 +561,7 @@ func TestRepositoriesService_Edit(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.Edit(ctx, "o", "r", input)
+	got, _, err := client.Repositories.Edit(ctx, "o", "r", input)
 	if err != nil {
 		t.Errorf("Repositories.Edit returned error: %v", err)
 	}
@@ -510,7 +574,7 @@ func TestRepositoriesService_Edit(t *testing.T) {
 	// Test s.client.Do failure
 	client.BaseURL.Path = "/api-v3/"
 	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
-	got, resp, err = client.Repositories.Edit(ctx, "o", "r", input)
+	got, resp, err := client.Repositories.Edit(ctx, "o", "r", input)
 	if got != nil {
 		t.Errorf("rate.Reset.Time > now Edit = %#v, want nil", got)
 	}
@@ -531,14 +595,14 @@ func TestRepositoriesService_Delete(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	resp, err := client.Repositories.Delete(ctx, "o", "r")
+	_, err := client.Repositories.Delete(ctx, "o", "r")
 	if err != nil {
 		t.Errorf("Repositories.Delete returned error: %v", err)
 	}
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	resp, err = client.Repositories.Delete(ctx, "o", "r")
+	resp, err := client.Repositories.Delete(ctx, "o", "r")
 	if resp != nil {
 		t.Errorf("client.BaseURL.Path='' Delete resp = %#v, want nil", resp)
 	}
diff --git a/github/repos_traffic_test.go b/github/repos_traffic_test.go
index 796544f3..1479caaa 100644
--- a/github/repos_traffic_test.go
+++ b/github/repos_traffic_test.go
@@ -27,7 +27,7 @@ func TestRepositoriesService_ListTrafficReferrers(t *testing.T) {
  		}]`)
 	})
 	ctx := context.Background()
-	got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
+	got, _, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
 	if err != nil {
 		t.Errorf("Repositories.ListTrafficReferrers returned error: %+v", err)
 	}
@@ -43,7 +43,7 @@ func TestRepositoriesService_ListTrafficReferrers(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.ListTrafficReferrers(ctx, "o", "r")
+	got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListTrafficReferrers = %#v, want nil", got)
 	}
@@ -83,7 +83,7 @@ func TestRepositoriesService_ListTrafficPaths(t *testing.T) {
  		}]`)
 	})
 	ctx := context.Background()
-	got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
+	got, _, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
 	if err != nil {
 		t.Errorf("Repositories.ListTrafficPaths returned error: %+v", err)
 	}
@@ -100,7 +100,7 @@ func TestRepositoriesService_ListTrafficPaths(t *testing.T) {
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.ListTrafficPaths(ctx, "o", "r")
+	got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListTrafficPaths = %#v, want nil", got)
 	}
@@ -142,7 +142,7 @@ func TestRepositoriesService_ListTrafficViews(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
+	got, _, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
 	if err != nil {
 		t.Errorf("Repositories.ListTrafficViews returned error: %+v", err)
 	}
@@ -162,14 +162,14 @@ func TestRepositoriesService_ListTrafficViews(t *testing.T) {
 	}
 
 	// Test addOptions failure
-	got, resp, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{})
+	_, _, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{})
 	if err == nil {
 		t.Error("bad options ListTrafficViews err = nil, want error")
 	}
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
+	got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListTrafficViews = %#v, want nil", got)
 	}
@@ -211,7 +211,7 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
+	got, _, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
 	if err != nil {
 		t.Errorf("Repositories.ListTrafficClones returned error: %+v", err)
 	}
@@ -231,14 +231,14 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) {
 	}
 
 	// Test addOptions failure
-	got, resp, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{})
+	_, _, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{})
 	if err == nil {
 		t.Error("bad options ListTrafficViews err = nil, want error")
 	}
 
 	// Test s.client.NewRequest failure
 	client.BaseURL.Path = ""
-	got, resp, err = client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
+	got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
 	if got != nil {
 		t.Errorf("client.BaseURL.Path='' ListTrafficClones = %#v, want nil", got)
 	}