Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Improvements to push_files tool#1676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
almaleksia wants to merge1 commit intoalmaleksia/auto-resolve-default-branch
base:almaleksia/auto-resolve-default-branch
Choose a base branch
Loading
fromalmaleksia/push_files-improvements

Conversation

@almaleksia
Copy link
Contributor

Summary

This PR aims to significantly reduce failure rate for push_files tool.

  1. Added auto-init of repository if it is empty.
  2. Added auto-creation of branch if it doesn't exist

Why

push_files tool fails too often due to rigid assumptions that both ref that files are pushed to exists and repo is not empty. However, it is very often not the case and we shouldn't fail on such common cases.

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added

Prompts tested (tool changes only)

Security / limits

  • No security or limits impact
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Lint & tests

  • Linted locally with./script/lint
  • Tested locally with./script/test

Docs

  • Not needed
  • Updated (README / docs / examples)

Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Pull request overview

This PR enhances thepush_files tool to automatically handle two common failure scenarios: empty repositories and non-existent branches. Instead of failing when encountering these conditions, the tool now initializes empty repositories with an initial commit and creates missing branches from the default branch.

Key changes:

  • Added auto-initialization of empty repositories when a 409 Conflict status is detected
  • Added auto-creation of branches from the default branch when a branch is not found
  • Improved error handling and resource cleanup with nil checks before closing response bodies

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

FileDescription
pkg/github/repositories.goImplements auto-init logic for empty repositories and auto-creation of non-existent branches; adds two helper functionsinitializeRepository andcreateReferenceFromDefaultBranch
pkg/github/repositories_test.goAdds comprehensive test coverage for empty repository scenarios, branch auto-creation failures, and updates existing test expectations to match new behavior

Comment on lines +1286 to +1300
ghErr,isGhErr:=err.(*github.ErrorResponse)
ifisGhErr {
ifghErr.Response.StatusCode==http.StatusConflict&&ghErr.Message=="Git Repository is empty." {
repositoryIsEmpty=true
}elseifghErr.Response.StatusCode==http.StatusNotFound {
branchNotFound=true
}
}else {
returnghErrors.NewGitHubAPIErrorResponse(ctx,
"failed to get branch reference",
resp,
err,
),nil,nil
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The error handling logic has critical issues: (1) It doesn't check if ghErr.Response is nil before accessing ghErr.Response.StatusCode, which could cause a nil pointer dereference panic. (2) When the error is a GitHub ErrorResponse but neither a 409 Conflict nor 404 Not Found (e.g., 500 Internal Server Error, 403 Forbidden), the function silently continues execution with both repositoryIsEmpty and branchNotFound as false, then attempts to access ref.Object.SHA on line 1316 where ref is nil, causing a panic.

Copilot uses AI. Check for mistakes.
Comment on lines +1334 to +1340
ifbranch!= (*defaultRef.Ref)[len("refs/heads/"):] {
// Create the requested branch from the default branch
ref,err=createReferenceFromDefaultBranch(ctx,client,owner,repo,branch)
iferr!=nil {
returnutils.NewToolResultError(fmt.Sprintf("failed to create branch from default: %v",err)),nil,nil
}
}else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The string slicing operation (*defaultRef.Ref)[len("refs/heads/"):] can panic if defaultRef.Ref is shorter than "refs/heads/" or has an unexpected format. This should validate the ref format before slicing or use a safer method to extract the branch name.

Suggested change
ifbranch!= (*defaultRef.Ref)[len("refs/heads/"):] {
// Create the requested branch from the default branch
ref,err=createReferenceFromDefaultBranch(ctx,client,owner,repo,branch)
iferr!=nil {
returnutils.NewToolResultError(fmt.Sprintf("failed to create branch from default: %v",err)),nil,nil
}
}else {
// Safely extract the default branch name from the ref, if it has the expected format.
constheadsPrefix="refs/heads/"
defaultBranchName:=""
ifdefaultRef!=nil&&defaultRef.Ref!=nil&&
strings.HasPrefix(*defaultRef.Ref,headsPrefix)&&
len(*defaultRef.Ref)>len(headsPrefix) {
defaultBranchName= (*defaultRef.Ref)[len(headsPrefix):]
}
ifdefaultBranchName!=""&&branch!=defaultBranchName {
// Create the requested branch from the default branch
ref,err=createReferenceFromDefaultBranch(ctx,client,owner,repo,branch)
iferr!=nil {
returnutils.NewToolResultError(fmt.Sprintf("failed to create branch from default: %v",err)),nil,nil
}
}else {
// Either this is the default branch or the ref format was unexpected; use the default ref.

Copilot uses AI. Check for mistakes.

// Create the new branch reference
createdRef,resp,err:=client.Git.CreateRef(ctx,owner,repo, github.CreateRef{
Ref:*github.Ptr("refs/heads/"+branch),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The code unnecessarily wraps the string in github.Ptr and then immediately dereferences it with *. Looking at line 1176 in the same file, the Ref field of CreateRef expects a plain string, not a pointer. This should be: Ref: "refs/heads/" + branch

Suggested change
Ref:*github.Ptr("refs/heads/"+branch),
Ref:"refs/heads/"+branch,

Copilot uses AI. Check for mistakes.
Comment on lines +1450 to +1451
// Create an initial empty commit to create the default branch
createResp,resp,err:=client.Repositories.CreateFile(ctx,owner,repo,"README.md",fileOpts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The function creates an empty README.md file to initialize the repository but doesn't communicate this to the caller. This means if a user is trying to push files including a README.md with specific content, the first file will create an empty README.md, and then the user's README.md content will overwrite it. While this works, it's inefficient and creates an extra commit in the history. Consider either: (1) checking if README.md is in the files being pushed and using that content for initialization, or (2) documenting this behavior clearly.

Suggested change
// Create an initial empty commit to create the default branch
createResp,resp,err:=client.Repositories.CreateFile(ctx,owner,repo,"README.md",fileOpts)
// Create an initial empty commit to create the default branch.
// Use a non-README file so that user-provided README.md content does not
// get an extra empty commit in its history.
createResp,resp,err:=client.Repositories.CreateFile(ctx,owner,repo,".gitkeep",fileOpts)

Copilot uses AI. Check for mistakes.
deferfunc() {_=resp.Body.Close() }()
}

// Update ref to point to the new commit

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The comment says "Update ref to point to the new commit" but the code is actually just retrieving the ref, not updating it. The ref was already created by the CreateFile operation on line 1451. Consider updating the comment to: "Get the reference that was created by the initial file commit".

Suggested change
//Update ref to point tothenew commit
//Get the reference that was created bytheinitial file commit

Copilot uses AI. Check for mistakes.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@almaleksia

[8]ページ先頭

©2009-2025 Movatter.jp