3

I am using the following function to simply create a new commit in a branch using go-github library

func GHAPICreateCommit(ctx context.Context, client *github.Client, commitOpts *CommitOptions) error {
    // Get the reference of the branch
    ref, _, err := client.Git.GetRef(ctx, repoOwner, commitOpts.Repo, "refs/heads/"+commitOpts.Branch)
    if err != nil {
        return err
    }
    commit, _, err := client.Git.GetCommit(ctx, repoOwner, commitOpts.Repo, *ref.Object.SHA)
    if err != nil {
        return err
    }

    commit.Message = github.String(commitOpts.CommitMessage)

    // Create a new commit with the updated commit message
    newCommit, _, err := client.Git.CreateCommit(ctx, repoOwner, commitOpts.Repo, commit)
    if err != nil {
        return err
    }
    // Attach the new commit to the reference
    ref.Object.SHA = newCommit.SHA

    // Update the branch reference to point to the new commit
    _, _, err = client.Git.UpdateRef(ctx, repoOwner, commitOpts.Repo, ref, false)
    if err != nil {
        return err
    }

    return nil
}

This fails with:

PATCH https://api.github.com/repos/MyOrg/myrepo/git/refs/heads/the-branch-I-am-creating-the-new-commit-to: 422 Update is not a fast forward []

Why isn't a fast-forward? It is simply a new commit created from an existing branch/commit.

PS: I EXPLICITLY DO NOT want to create new files on my commit.

pkaramol
  • 16,451
  • 43
  • 149
  • 324
  • I can’t read Go but it seems like you are amending a commit, i.e. creating a new commit and then replacing the tip of your branch with that new commit (discarding the old one). If your remote has that old commit then it will be denied (non-fast-forward) unless you do a force-push. – Guildenstern Apr 30 '23 at 11:36
  • Sorry typo, the correct one is `422`, title fixed – pkaramol Apr 30 '23 at 13:01

1 Answers1

2
func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string, commit *Commit) (*Commit, *Response, error)

The parameter commit is used to specify some of the information of the new commit, including the parents of the new commit (see the implementation).

In your code, the new commit and the old commit has the same parents, so this is not a fast-forward push to the branch. To make it a fast-forward push to the branch, the parents of the new commit should point to the old commit.

I guess the following change would make it a fast-forward:

+ commit.Parents = []*github.Commit{commit}
  newCommit, _, err := client.Git.CreateCommit(ctx, repoOwner, commitOpts.Repo, commit)
Zeke Lu
  • 6,349
  • 1
  • 17
  • 23
  • 1) That did the trick so thank you 2) the correct code is `commit.Parents = []github.Commit{*commit}` in case you want to update your answer 3) I am having a new issue now since `_, _, err = client.Git.UpdateRef(ctx, repoOwner, commitOpts.Repo, ref, false)` does not error out but the change is not reflected in the remote (still points to the old commit); I guess this is for a new question – pkaramol Apr 30 '23 at 15:48
  • The [package](https://pkg.go.dev/github.com/google/go-github/v52/github#Commit) I checked states that the type of `Parents` is `[]*Commit`. Maybe we are checking different packages? I would have a check on another issue. But you're right, it's better to create a new question for it. – Zeke Lu Apr 30 '23 at 15:58