Repository: google/go-github
File: github/git_refs.go (Go)

Code before:
	// back-compat with previous behavior that didn't require 'refs/' prefix
	if !strings.HasPrefix(ref.Ref, "refs/") {
		ref.Ref = "refs/" + ref.Ref
	}

	u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
	req, err := s.client.NewRequest("POST", u, ref)
	if err != nil {
		return nil, nil, err
	}

	r := new(Reference)
	resp, err := s.client.Do(ctx, req, r)
	if err != nil {
		return nil, resp, err
	}

	return r, resp, nil
}

// UpdateRef updates an existing ref in a repository.
//
// GitHub API docs: https://docs.github.com/rest/git/refs#update-a-reference
//
//meta:operation PATCH /repos/{owner}/{repo}/git/refs/{ref}
func (s *GitService) UpdateRef(ctx context.Context, owner, repo string, ref Reference, force bool) (*Reference, *Response, error) {
	if ref.Ref == nil {
		return nil, nil, errors.New("ref must be provided")
	}

	refPath := strings.TrimPrefix(*ref.Ref, "refs/")
	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(refPath))
	req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{
		SHA:   ref.Object.SHA,
		Force: &force,
	})
	if err != nil {
		return nil, nil, err
	}

	r := new(Reference)
	resp, err := s.client.Do(ctx, req, r)
	if err != nil {
		return nil, resp, err
	}

	return r, resp, nil
}

// DeleteRef deletes a ref from a repository.
//

Review comment (suggestion):
The `Reference` has 4 fields, but this method used only two: `ref (string)` and `sha (string)`. I propose to create a separate struct similar to what we already did for `CreateRef`:

```suggestion
func (s *GitService) UpdateRef(ctx context.Context, owner, repo, ref string, updateRef UpdateRef) (*Reference, *Response, error) {
```

And this struct should be used instead of `updateRefRequest`:
```go
type UpdateRef struct {
	SHA   string `json:"sha"`
	Force *bool   `json:"force,omitempty"`
}
```

Code after:
	// ensure the 'refs/' prefix is present
	ref.Ref = "refs/" + strings.TrimPrefix(ref.Ref, "refs/")

	u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
	req, err := s.client.NewRequest("POST", u, ref)
	if err != nil {
		return nil, nil, err
	}

	r := new(Reference)
	resp, err := s.client.Do(ctx, req, r)
	if err != nil {
		return nil, resp, err
	}

	return r, resp, nil
}

// UpdateRef updates an existing ref in a repository.
//
// GitHub API docs: https://docs.github.com/rest/git/refs#update-a-reference
//
//meta:operation PATCH /repos/{owner}/{repo}/git/refs/{ref}
func (s *GitService) UpdateRef(ctx context.Context, owner, repo, ref string, updateRef UpdateRef) (*Reference, *Response, error) {
	if ref == "" {
		return nil, nil, errors.New("ref must be provided")
	}

	if updateRef.SHA == "" {
		return nil, nil, errors.New("sha must be provided")
	}

	refPath := strings.TrimPrefix(ref, "refs/")
	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refURLEscape(refPath))
	req, err := s.client.NewRequest("PATCH", u, updateRef)
	if err != nil {
		return nil, nil, err
	}

	r := new(Reference)
	resp, err := s.client.Do(ctx, req, r)
	if err != nil {
		return nil, resp, err
	}

	return r, resp, nil
}

// DeleteRef deletes a ref from a repository.
//
// GitHub API docs: https://docs.github.com/rest/git/refs#delete-a-reference