Skip to content

Allow configured Git remotes to be used for the '-R' argument #1481

Description

@phil-blain

Describe the feature or problem you’d like to solve

If I have a configured remote named <remote> in my Git repository and want to open a PR against that remote, I'd like to able to do

gh pr create -R <remote>

but right now I have to do

gh pr create -R <github-user-or-org>/<repo-name>

which can be considerably longer depending on the project.

Proposed solution

How will it benefit CLI and its users?

This will allow them to type less :)

Additional context

This ideally would work for every gh command accepting a -R argument, when run from inside a Git repository.

Activity

  1. phil-blain commented on Aug 3, 2020

    @phil-blain
    Author

    See also : #317

  2. added
    coreThis issue is not accepting PRs from outside contributors
    on Oct 7, 2020
  3. choeppler commented on Jun 21, 2024

    @choeppler

    In a setting where the upstream repo is on github.com and you also have a mirror on a GitHub Enterprise Server, this feature would save even more typing.

    My current workaround is to define a git alias url = remote get-url. Then, instead of

    gh pr -R https://<github-server-url>/<github-user-or-org>/<repo-name> checkout 42

    I can

    gh pr -R `git url <remote>` checkout <pr-number>

    Still, the possibility to specify a remote directly, would make life even easier 😄

    gh pr -R <remote> checkout <pr-number>
  4. Ariel096 commented on Jun 21, 2024

    @Ariel096
  5. rmacklin commented on Jul 24, 2024

    @rmacklin

    I'm interested in this feature, too. It would be nice to be able to run a one-off like gh pr list -R upstream when upstream is a different remote than what's configured via gh repo set-default.

    One thing that probably needs to be decided is how it should handle a remote name that happens to match the :owner/:repo pattern - i.e. given a configuration like:

    $ git remote -v
    origin	[email protected]:my/repository.git (fetch)
    origin	[email protected]:my/repository.git (push)
    forks/someone	[email protected]:someone/repository.git (fetch)
    forks/someone	[email protected]:someone/repository.git (push)
    forks/another1	[email protected]:another1/repository.git (fetch)
    forks/another1	[email protected]:another1/repository.git (push)
    

    Should -R forks/someone use the configured remote (github.com/someone/repository), or should that always attempt to use the github.com repository that matches (github.com/forks/someone in that example)? I tend to prefer the behavior of always favoring a configured remote, but I'm not sure if the maintainers would want any :owner/:repo parameter to assume github.com (as it currently does)

    @andyfeller @williammartin Curious if you have thoughts on this (and if you're supportive of the feature in general, or if you'd be against such a contribution)?

  6. andyfeller commented on Sep 18, 2024

    @andyfeller
    Contributor

    Should -R forks/someone use the configured remote (github.com/someone/repository), or should that always attempt to use the github.com repository that matches (github.com/forks/someone in that example)? I tend to prefer the behavior of always favoring a configured remote, but I'm not sure if the maintainers would want any :owner/:repo parameter to assume github.com (as it currently does)

    @andyfeller @williammartin Curious if you have thoughts on this (and if you're supportive of the feature in general, or if you'd be against such a contribution)?

    Apologies for letting this hide in the backlog of notifications 😓

    If we had this support, I'd assume we first check the remotes before falling back on an actual remote GitHub repository. There are fewer remotes and should be fairly easy. The main challenge is that remote names allow characters and formats that look closely like a GitHub name with owner.

    All of that said, I think the biggest challenge is the scope of a change like this as 1) it affects a lot of commands and 2) it cuts across various layers. For example, the code below powers the -R, --repo logic across multiple commands, which would need to determine if the provided repo matches the remotes before falling back to a GitHub repo.

    func EnableRepoOverride(cmd *cobra.Command, f *Factory) {
    cmd.PersistentFlags().StringP("repo", "R", "", "Select another repository using the `[HOST/]OWNER/REPO` format")
    _ = cmd.RegisterFlagCompletionFunc("repo", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    remotes, err := f.Remotes()
    if err != nil {
    return nil, cobra.ShellCompDirectiveError
    }
    config, err := f.Config()
    if err != nil {
    return nil, cobra.ShellCompDirectiveError
    }
    defaultHost, _ := config.Authentication().DefaultHost()
    var results []string
    for _, remote := range remotes {
    repo := remote.RepoOwner() + "/" + remote.RepoName()
    if !strings.EqualFold(remote.RepoHost(), defaultHost) {
    repo = remote.RepoHost() + "/" + repo
    }
    if strings.HasPrefix(repo, toComplete) {
    results = append(results, repo)
    }
    }
    sort.Strings(results)
    return results, cobra.ShellCompDirectiveNoFileComp
    })
    cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
    if err := executeParentHooks(cmd, args); err != nil {
    return err
    }
    repoOverride, _ := cmd.Flags().GetString("repo")
    f.BaseRepo = OverrideBaseRepoFunc(f, repoOverride)
    return nil
    }
    }
    func OverrideBaseRepoFunc(f *Factory, override string) func() (ghrepo.Interface, error) {
    if override == "" {
    override = os.Getenv("GH_REPO")
    }
    if override != "" {
    return func() (ghrepo.Interface, error) {
    return ghrepo.FromFullName(override)
    }
    }
    return f.BaseRepo
    }

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

    coreThis issue is not accepting PRs from outside contributorsenhancementa request to improve CLI

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions