From 73c7fd59ef75a5248d71866dee76212a2b37b549 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Fri, 26 Dec 2025 19:21:11 +0800 Subject: [PATCH] feat: allow git remote names in gh repo set-default When specifying a repository for `gh repo set-default`, users can now use a git remote name (e.g., "origin", "upstream") instead of the full OWNER/REPO format. The command first checks if the argument is a git remote name. If found, it uses the corresponding repository. Otherwise, it falls back to parsing the argument as OWNER/REPO format. Example: gh repo set-default origin Fixes #9149 Signed-off-by: majiayu000 <1835304752@qq.com> --- pkg/cmd/repo/setdefault/setdefault.go | 34 +++++++++++++++------- pkg/cmd/repo/setdefault/setdefault_test.go | 30 +++++++++++++++---- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/pkg/cmd/repo/setdefault/setdefault.go b/pkg/cmd/repo/setdefault/setdefault.go index f2b4b52670f..63596d259d3 100644 --- a/pkg/cmd/repo/setdefault/setdefault.go +++ b/pkg/cmd/repo/setdefault/setdefault.go @@ -70,6 +70,9 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) * # Set a repository explicitly $ gh repo set-default owner/repo + # Set a repository using a git remote name + $ gh repo set-default origin + # View the current default repository $ gh repo set-default --view @@ -79,11 +82,28 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) * `), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + if isLocal, err := opts.GitClient.IsLocalGitRepo(cmd.Context()); err != nil { + return err + } else if !isLocal { + return errors.New("must be run from inside a git repository") + } + if len(args) > 0 { - var err error - opts.Repo, err = ghrepo.FromFullName(args[0]) - if err != nil { - return err + // First, try to find argument as a git remote name + if !strings.Contains(args[0], "/") && opts.Remotes != nil { + if remotes, err := opts.Remotes(); err == nil { + if remote, err := remotes.FindByName(args[0]); err == nil { + opts.Repo = remote.Repo + } + } + } + // If not found as remote name, try parsing as OWNER/REPO + if opts.Repo == nil { + var err error + opts.Repo, err = ghrepo.FromFullName(args[0]) + if err != nil { + return err + } } } @@ -91,12 +111,6 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) * return cmdutil.FlagErrorf("repository required when not running interactively") } - if isLocal, err := opts.GitClient.IsLocalGitRepo(cmd.Context()); err != nil { - return err - } else if !isLocal { - return errors.New("must be run from inside a git repository") - } - if runF != nil { return runF(opts) } diff --git a/pkg/cmd/repo/setdefault/setdefault_test.go b/pkg/cmd/repo/setdefault/setdefault_test.go index 0d2e2ddaacc..e910676eef8 100644 --- a/pkg/cmd/repo/setdefault/setdefault_test.go +++ b/pkg/cmd/repo/setdefault/setdefault_test.go @@ -21,6 +21,7 @@ func TestNewCmdSetDefault(t *testing.T) { tests := []struct { name string gitStubs func(*run.CommandStubber) + remotes func() (context.Remotes, error) input string output SetDefaultOptions wantErr bool @@ -43,11 +44,13 @@ func TestNewCmdSetDefault(t *testing.T) { output: SetDefaultOptions{Repo: ghrepo.New("cli", "cli")}, }, { - name: "invalid repo argument", - gitStubs: func(cs *run.CommandStubber) {}, - input: "some_invalid_format", - wantErr: true, - errMsg: `expected the "[HOST/]OWNER/REPO" format, got "some_invalid_format"`, + name: "invalid repo argument", + gitStubs: func(cs *run.CommandStubber) { + cs.Register(`git rev-parse --git-dir`, 0, ".git") + }, + input: "some_invalid_format", + wantErr: true, + errMsg: `expected the "[HOST/]OWNER/REPO" format, got "some_invalid_format"`, }, { name: "view flag", @@ -74,6 +77,22 @@ func TestNewCmdSetDefault(t *testing.T) { wantErr: true, errMsg: "must be run from inside a git repository", }, + { + name: "remote name argument", + gitStubs: func(cs *run.CommandStubber) { + cs.Register(`git rev-parse --git-dir`, 0, ".git") + }, + remotes: func() (context.Remotes, error) { + return context.Remotes{ + { + Remote: &git.Remote{Name: "origin"}, + Repo: ghrepo.New("OWNER", "REPO"), + }, + }, nil + }, + input: "origin", + output: SetDefaultOptions{Repo: ghrepo.New("OWNER", "REPO")}, + }, } for _, tt := range tests { @@ -84,6 +103,7 @@ func TestNewCmdSetDefault(t *testing.T) { f := &cmdutil.Factory{ IOStreams: io, GitClient: &git.Client{GitPath: "/fake/path/to/git"}, + Remotes: tt.remotes, } var gotOpts *SetDefaultOptions