Skip to content

gh pr checkout defies negative refspec in remote.*.<name> #10254

Description

@Frederick888

Describe the bug

We have some release Actions that push artefacts to v123-deploy when v123 tag is created. I never need the *-deploy tags, so to avoid fetching them, in my .git/config:

[remote "origin"]
	url = [email protected]:org/repo.git
	fetch = +refs/heads/*:refs/remotes/origin/*
        fetch = ^refs/heads/*-deploy
        fetch = ^refs/tags/*-deploy

However if I do a gh pr checkout 123456, it'll fetch all those *-deploy tags.

$ gh --version
gh version 2.65.0-11-g0006091d7 (2025-01-07)
https://github.com/cli/cli/releases/latest

Steps to reproduce the behavior

  1. Set up negative fetch refspecs (doc: https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt-ltrefspecgt)
  2. Run gh pr checkout 123456
  3. It'll start fetching all the ignored tags

Expected vs actual behavior

gh respects my remote.*.<name> configs.

Logs

Paste the activity from your command line. Redact if needed.

$ GH_DEBUG=true gh pr checkout 123456
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-01-16 15:24:11.714671 +1100 AEDT m=+0.135416674
* Request to https://api.github.com/graphql
* Request took 611.486474ms
⣾* Request at 2025-01-16 15:24:12.327912 +1100 AEDT m=+0.748639651
* Request to https://api.github.com/graphql
⢿* Request took 382.392664ms
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
[git show-ref --verify -- refs/heads/feat-branch]
[git -c credential.helper= -c credential.helper=!"/usr/local/bin/gh" auth git-credential fetch origin +refs/heads/feat-branch:refs/remotes/origin/feat-branch]
From github.com:org/repo
 * [new tag]             v782-deploy -> v782-deploy
 * [new tag]             v783-deploy -> v783-deploy
 * [new tag]             v784-deploy -> v784-deploy
 * [new tag]             v785-deploy -> v785-deploy
 * [new tag]             v786-deploy -> v786-deploy
 * [new tag]             v787-deploy -> v787-deploy
 * [new tag]             v788-deploy -> v788-deploy
 * [new tag]             v789-deploy -> v789-deploy
 * [new tag]             v790-deploy -> v790-deploy
 * [new tag]             v791-deploy -> v791-deploy
[git checkout -b feat-branch --track origin/feat-branch]
branch 'feat-branch' set up to track 'origin/feat-branch'.
Switched to a new branch 'feat-branch'

# delete all *-deploy tags
$ git tag -l | rg -- '-deploy$' | xargs -I{} -- git tag -d {}
# the command I use to fetch
# perhaps we just need to add --tags into gh too?
$ git fetch --all --prune --tags --jobs=10

Activity

  1. self-assigned this
    on Jan 16, 2025
  2. BagToad commented on Jan 17, 2025

    @BagToad
    Member

    👋 Hey @Frederick888, thanks for this issue ✨

    I started digging into this, and what may be happening is that when you provide a command line refspec to git fetch the refspec(s) in your Git config are ignored:

    Specifies which refs to fetch and which local refs to update. When no <refspec>s appear on the command line, the refs to fetch are read from remote.<repository>.fetch variables instead

    Since we need to provide a refspec on the command line to checkout the PR, I am not sure what options are available to us in gh. Perhaps getting the config and appending it to the command line refspec?

    I saw that you could configure the default tag fetch policy, which may help preventing tags from being fetched generally - though I recognize that's not exactly what you're looking for:

    --no-tags
    By default, tags that point at objects that are downloaded from the remote repository are fetched and stored locally. This option disables this automatic tag following. The default behavior for a remote may be specified with the remote.<name>.tagOpt setting. See git-config[1].

    💭 All this in mind, I think this is intended behavior.

    Please let me know if I understood correctly and if you have any other ideas or feedback 😁❤

  3. added
    enhancementa request to improve CLI
    more-info-neededMore info needed from user/contributor
    and removed
    bugSomething isn't working
    on Jan 17, 2025
  4. Frederick888 commented on Jan 20, 2025

    @Frederick888
    ContributorAuthor

    @BagToad Git's behaviour is a bit confusing. With my config, somehow

    $ git fetch origin
    # will fetch *-deploy tags
    
    $ git fetch --tags origin
    # will NOT fetch *-deploy tags
    $ git fetch --no-tags origin
    # will NOT fetch ANY tags
    
    $ git fetch origin '+refs/heads/feat-branch:refs/remotes/origin/feat-branch'
    # so while this will fetch *-deploy tags
    
    $ git fetch --tags origin '+refs/heads/feat-branch:refs/remotes/origin/feat-branch' '^refs/heads/*-deploy' '^refs/tags/*-deploy'
    # ...this will not fetch *-deploy tags (but other tags will be fetched, which can be considered expected)

    So I think when a PR is from an existing remote in .git/config, we can add --tags + process the output of git config --get-all remote.origin.fetch to append the additional negative refspecs.

  5. williammartin commented on Jan 23, 2025

    @williammartin
    Member

    @Frederick888,

    I can't think of a reason we would need tags for pr checkout since PRs are based entirely around branches.

    Can you think of a reason we shouldn't just provide --no-tags to the git fetch command here?

  6. Frederick888 commented on Jan 23, 2025

    @Frederick888
    ContributorAuthor

    @williammartin Yup that works for me too!

    I wasn't sure about how the code was structured and whether the git fetch command was reused in any way. But in terms of gh pr checkout, --no-tags sounds good to me 👍

  7. BagToad commented on Feb 5, 2025

    @BagToad
    Member

    Acceptance Criteria

    Given I have a repository with Git tags
    When I run gh pr checkout
    Then the branch is fetched with --no-tags

  8. removed their assignment
    on Feb 5, 2025
  9. added and removed
    more-info-neededMore info needed from user/contributor
    on Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementa request to improve CLIgh-prrelating to the gh pr commandhelp wantedContributions welcome

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions