github.com/google/go-github/v69@v69.2.0/github/git_refs.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 "context" 10 "fmt" 11 "net/url" 12 "strings" 13 ) 14 15 // Reference represents a GitHub reference. 16 type Reference struct { 17 Ref *string `json:"ref"` 18 URL *string `json:"url"` 19 Object *GitObject `json:"object"` 20 NodeID *string `json:"node_id,omitempty"` 21 } 22 23 func (r Reference) String() string { 24 return Stringify(r) 25 } 26 27 // GitObject represents a Git object. 28 type GitObject struct { 29 Type *string `json:"type"` 30 SHA *string `json:"sha"` 31 URL *string `json:"url"` 32 } 33 34 func (o GitObject) String() string { 35 return Stringify(o) 36 } 37 38 // createRefRequest represents the payload for creating a reference. 39 type createRefRequest struct { 40 Ref *string `json:"ref"` 41 SHA *string `json:"sha"` 42 } 43 44 // updateRefRequest represents the payload for updating a reference. 45 type updateRefRequest struct { 46 SHA *string `json:"sha"` 47 Force *bool `json:"force"` 48 } 49 50 // GetRef fetches a single reference in a repository. 51 // 52 // GitHub API docs: https://docs.github.com/rest/git/refs#get-a-reference 53 // 54 //meta:operation GET /repos/{owner}/{repo}/git/ref/{ref} 55 func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) { 56 ref = strings.TrimPrefix(ref, "refs/") 57 u := fmt.Sprintf("repos/%v/%v/git/ref/%v", owner, repo, refURLEscape(ref)) 58 req, err := s.client.NewRequest("GET", u, nil) 59 if err != nil { 60 return nil, nil, err 61 } 62 63 r := new(Reference) 64 resp, err := s.client.Do(ctx, req, r) 65 if err != nil { 66 return nil, resp, err 67 } 68 69 return r, resp, nil 70 } 71 72 // refURLEscape escapes every path segment of the given ref. Those must 73 // not contain escaped "/" - as "%2F" - or github will not recognize it. 74 func refURLEscape(ref string) string { 75 parts := strings.Split(ref, "/") 76 for i, s := range parts { 77 parts[i] = url.PathEscape(s) 78 } 79 return strings.Join(parts, "/") 80 } 81 82 // ReferenceListOptions specifies optional parameters to the 83 // GitService.ListMatchingRefs method. 84 type ReferenceListOptions struct { 85 Ref string `url:"-"` 86 87 ListOptions 88 } 89 90 // ListMatchingRefs lists references in a repository that match a supplied ref. 91 // Use an empty ref to list all references. 92 // 93 // GitHub API docs: https://docs.github.com/rest/git/refs#list-matching-references 94 // 95 //meta:operation GET /repos/{owner}/{repo}/git/matching-refs/{ref} 96 func (s *GitService) ListMatchingRefs(ctx context.Context, owner, repo string, opts *ReferenceListOptions) ([]*Reference, *Response, error) { 97 var ref string 98 if opts != nil { 99 ref = strings.TrimPrefix(opts.Ref, "refs/") 100 } 101 u := fmt.Sprintf("repos/%v/%v/git/matching-refs/%v", owner, repo, refURLEscape(ref)) 102 u, err := addOptions(u, opts) 103 if err != nil { 104 return nil, nil, err 105 } 106 107 req, err := s.client.NewRequest("GET", u, nil) 108 if err != nil { 109 return nil, nil, err 110 } 111 112 var rs []*Reference 113 resp, err := s.client.Do(ctx, req, &rs) 114 if err != nil { 115 return nil, resp, err 116 } 117 118 return rs, resp, nil 119 } 120 121 // CreateRef creates a new ref in a repository. 122 // 123 // GitHub API docs: https://docs.github.com/rest/git/refs#create-a-reference 124 // 125 //meta:operation POST /repos/{owner}/{repo}/git/refs 126 func (s *GitService) CreateRef(ctx context.Context, owner string, repo string, ref *Reference) (*Reference, *Response, error) { 127 u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo) 128 req, err := s.client.NewRequest("POST", u, &createRefRequest{ 129 // back-compat with previous behavior that didn't require 'refs/' prefix 130 Ref: Ptr("refs/" + strings.TrimPrefix(*ref.Ref, "refs/")), 131 SHA: ref.Object.SHA, 132 }) 133 if err != nil { 134 return nil, nil, err 135 } 136 137 r := new(Reference) 138 resp, err := s.client.Do(ctx, req, r) 139 if err != nil { 140 return nil, resp, err 141 } 142 143 return r, resp, nil 144 } 145 146 // UpdateRef updates an existing ref in a repository. 147 // 148 // GitHub API docs: https://docs.github.com/rest/git/refs#update-a-reference 149 // 150 //meta:operation PATCH /repos/{owner}/{repo}/git/refs/{ref} 151 func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) { 152 refPath := strings.TrimPrefix(*ref.Ref, "refs/") 153 u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(refPath)) 154 req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{ 155 SHA: ref.Object.SHA, 156 Force: &force, 157 }) 158 if err != nil { 159 return nil, nil, err 160 } 161 162 r := new(Reference) 163 resp, err := s.client.Do(ctx, req, r) 164 if err != nil { 165 return nil, resp, err 166 } 167 168 return r, resp, nil 169 } 170 171 // DeleteRef deletes a ref from a repository. 172 // 173 // GitHub API docs: https://docs.github.com/rest/git/refs#delete-a-reference 174 // 175 //meta:operation DELETE /repos/{owner}/{repo}/git/refs/{ref} 176 func (s *GitService) DeleteRef(ctx context.Context, owner string, repo string, ref string) (*Response, error) { 177 ref = strings.TrimPrefix(ref, "refs/") 178 u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(ref)) 179 req, err := s.client.NewRequest("DELETE", u, nil) 180 if err != nil { 181 return nil, err 182 } 183 184 return s.client.Do(ctx, req, nil) 185 }