Skip to content

Handle repositories whose default branch is not main - #1

Merged
looplj merged 3 commits into
masterfrom
fix/default-branch-detection
Mar 23, 2026
Merged

Handle repositories whose default branch is not main#1
looplj merged 3 commits into
masterfrom
fix/default-branch-detection

Conversation

@looplj

@looplj looplj commented Mar 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • stop defaulting parsed GitHub sources to
  • detect the remote default branch before cloning when no ref is specified
  • preserve update URLs for repos whose stored source has no explicit ref

Testing

  • go test ./...

Open with Devin

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the system's ability to interact with Git repositories by removing the rigid assumption of 'main' as the default branch. It introduces dynamic detection of the actual default branch, improving compatibility with a wider range of Git hosting configurations. The changes ensure that repository cloning and source URL generation accurately reflect the remote's configuration, leading to more robust and flexible operations.

Highlights

  • Dynamic Default Branch Detection: Implemented logic to dynamically detect the default branch of a Git repository using git ls-remote when no specific reference (branch/tag) is provided for cloning.
  • Removed Hardcoded 'main' Branch: Eliminated the hardcoded assumption that 'main' is the default branch when parsing GitHub source URLs and constructing update URLs, allowing for repositories with other default branch names (e.g., 'master').
  • Improved Source URL Handling: Refactored the construction of source URLs to correctly include the branch reference only when explicitly specified, and to normalize repository URLs for consistent Git operations.
  • Comprehensive Testing: Added new unit tests to validate the default branch detection mechanism and to ensure that parsed GitHub sources correctly reflect an empty reference when no branch is specified.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

The pull request refactors the Git cloning logic to dynamically detect the default branch of a remote repository instead of hardcoding 'main'. This involves extracting URL normalization and reference resolution into new functions (normalizeRepoURL, resolveCloneRef, detectDefaultBranch) in git.go, and modifying commands.go and source.go to no longer assume 'main' as the default branch. A new test file git_test.go was added to verify the default branch detection. The primary review comment highlights a bug where the resolveCloneRef function swallows errors from detectDefaultBranch, potentially leading to less informative error messages and making subsequent error checks redundant. The reviewer suggests propagating these errors while still allowing git clone to proceed if the default branch is simply not found.

Comment thread git.go Outdated
Comment on lines +72 to +77
ref, err := detectDefaultBranch(ctx, repoURL)
if err == nil && ref != "" {
return ref, nil
}

args := []string{"clone", "--depth", "1", "--branch", ref, repoURL, tmp}
cmd := exec.CommandContext(ctx, "git", args...)
return "", nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This logic swallows any error returned by detectDefaultBranch. If git ls-remote fails due to a network issue or an invalid repository URL, the specific error is lost, and git clone will fail later with a potentially less informative message. This also makes the error check for resolveCloneRef in cloneRepo (line 28) effectively dead code.

You should propagate errors from detectDefaultBranch, while still treating the "default branch not found" case as a non-error, since git clone can handle that by using the remote's default. Using string comparison on the error message is brittle; a more robust long-term solution would be for detectDefaultBranch to return a sentinel error.

Suggested change
ref, err := detectDefaultBranch(ctx, repoURL)
if err == nil && ref != "" {
return ref, nil
}
args := []string{"clone", "--depth", "1", "--branch", ref, repoURL, tmp}
cmd := exec.CommandContext(ctx, "git", args...)
return "", nil
ref, err := detectDefaultBranch(ctx, repoURL)
if err != nil {
// "default branch not found" is not a fatal error; git clone can proceed without a branch.
// However, other errors (e.g., network, git not found) should be propagated.
if err.Error() == "default branch not found" {
return "", nil
}
return "", err
}
return ref, nil

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed: I introduced a sentinel error for the "default branch not found" case and now propagate other detectDefaultBranch failures instead of swallowing them.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment thread commands.go
Comment on lines +922 to +926
srcURL := "https://github.com/" + owner + "/" + repo
if ref != "" {
srcURL += "/tree/" + ref
}

srcURL := "https://github.com/" + owner + "/" + repo + "/tree/" + ref + "/" + strings.TrimPrefix(u.Entry.SkillPath, "/")
srcURL += "/" + strings.TrimPrefix(u.Entry.SkillPath, "/")

@devin-ai-integration devin-ai-integration Bot Mar 23, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Update constructs invalid GitHub URL (losing skill subpath) when resolveCloneRef returns empty ref

When resolveCloneRef returns an empty ref (which occurs when detectDefaultBranch at git.go:85-106 returns ErrDefaultBranchNotFound—e.g., on git servers that don't support --symref), the URL is built as https://github.com/owner/repo/skills/my-skill instead of including /tree/<branch>/. When this URL is re-parsed by ParseSource at source.go:54-62, the githubTreeRe regex won't match (no /tree/ segment), so the fallback path splits on / and returns only Owner and Repo—the skill subpath (u.Entry.SkillPath) is silently lost. This causes Add to clone the repo and scan from the root instead of the correct subdirectory, potentially installing wrong skills or failing to find the expected skill.

URL construction path when ref is empty vs non-empty

When ref is non-empty (normal case), URL is:
https://github.com/owner/repo/tree/main/skills/my-skill → ParseSource extracts Subpath correctly.

When ref is empty (ErrDefaultBranchNotFound), URL is:
https://github.com/owner/repo/skills/my-skill → ParseSource returns Owner="owner", Repo="repo", Subpath="" (lost).

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed: Update() now resolves the repo default branch when no ref is stored, so it always reconstructs a valid /tree/<branch>/... source URL and preserves the skill subpath.

looplj and others added 2 commits March 23, 2026 04:25
cloneRepo no longer calls resolveCloneRef/detectDefaultBranch. When no
explicit ref is provided, git clone is invoked without --branch, letting
git itself pick the remote's default branch. This avoids an unnecessary
network round-trip on every install.

resolveCloneRef is still used by Update() where the branch name is
needed to construct source URLs.
@looplj
looplj merged commit 55afc09 into master Mar 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant