KEMBAR78
Find PRs using `@{push}` by Frederick888 · Pull Request #9208 · cli/cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0179381
Find PRs using @{push}
Frederick888 Jun 14, 2024
7fc35fd
Only find PRs w/ branch.<name>.merge if push.default = upstream/tracking
Frederick888 Jun 14, 2024
4254818
Find push remote using branch.<name>.pushRemote and remote.pushDefault
Frederick888 Jun 14, 2024
2d1e4d6
Add base gh pr view acceptance tests for changes
andyfeller Dec 16, 2024
eb16a75
Expand with gh pr status
andyfeller Dec 16, 2024
8bb2879
Reflect coverage for view and status subcommands
andyfeller Dec 16, 2024
be250b3
Add renamed acceptance tests
andyfeller Dec 16, 2024
0006091
Fix up intra-org fork test setup
andyfeller Dec 18, 2024
48e2681
Merge branch 'trunk' into find-pr-by-rev-parse-push
jtmcg Jan 14, 2025
0184380
Add missing git stubs to tests
jtmcg Jan 15, 2025
4a9fd95
Add comments and a bit of code cleanup
jtmcg Jan 16, 2025
d289ddd
Use PushRemoteURL instead of RemoteURL in prSelectorForCurrentBranch
jtmcg Jan 16, 2025
aef2642
fixup! Add comments and a bit of code cleanup
Frederick888 Jan 16, 2025
41729b0
Refactor finder.Find and replace parseCurrentBranch with parsePRRefs
jtmcg Jan 22, 2025
a72bef9
Error if push revision doesn't match a remote
williammartin Jan 24, 2025
6355ed7
WIP: push default defaults to simple
williammartin Jan 24, 2025
5a8dd35
Add PushDefault method to git client
jtmcg Jan 24, 2025
e4d8ed0
Remove @{push} from branch config
jtmcg Jan 24, 2025
cdead50
Moved remote.pushDefault out of ReadBranchConfig and into finder
jtmcg Jan 24, 2025
d684834
Refactor pr status to use the ParsePRRefs helper on the Finder
jtmcg Jan 24, 2025
4382bdf
Fix pr create tests
jtmcg Jan 24, 2025
62106dc
Cleanup comment
jtmcg Jan 24, 2025
e31bfd0
Cleaned up some naming and comments
jtmcg Jan 28, 2025
e0f624b
Rename PRRefs to PullRequestRefs and PR comment cleanup
jtmcg Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Only find PRs w/ branch.<name>.merge if push.default = upstream/tracking
When push.default is not 'upstream' / 'tracking' (or 'nothing'), we can
expect local and remote branch names to be the same and solely rely on
@{push} or RemoteURL.

This fixes the wrong error message 'no pull requests found for branch
"<target branch>"' when the local branch is not pushed in the
push.default = simple / current and upstream = <target branch> setup.
  • Loading branch information
Frederick888 committed Jan 6, 2025
commit 7fc35fd47d9482068a5c7666c5c67d4e5e001fce
9 changes: 7 additions & 2 deletions pkg/cmd/pr/shared/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type finder struct {
remotesFn func() (remotes.Remotes, error)
httpClient func() (*http.Client, error)
branchConfig func(string) git.BranchConfig
pushDefault func() (string, error)
progress progressIndicator

repo ghrepo.Interface
Expand All @@ -57,7 +58,10 @@ func NewFinder(factory *cmdutil.Factory) PRFinder {
branchFn: factory.Branch,
remotesFn: factory.Remotes,
httpClient: factory.HttpClient,
progress: factory.IOStreams,
pushDefault: func() (string, error) {
return factory.GitClient.Config(context.Background(), "push.default")
},
progress: factory.IOStreams,
branchConfig: func(s string) git.BranchConfig {
return factory.GitClient.ReadBranchConfig(context.Background(), s)
},
Expand Down Expand Up @@ -263,7 +267,8 @@ func (f *finder) parseCurrentBranch() (string, int, error) {
if gitRemoteRepo != nil {
if branchConfig.Push != "" {
prHeadRef = strings.TrimPrefix(branchConfig.Push, branchConfig.RemoteName+"/")
} else if strings.HasPrefix(branchConfig.MergeRef, "refs/heads/") {
} else if pushDefault, _ := f.pushDefault(); (pushDefault == "upstream" || pushDefault == "tracking") &&
strings.HasPrefix(branchConfig.MergeRef, "refs/heads/") {
prHeadRef = strings.TrimPrefix(branchConfig.MergeRef, "refs/heads/")
}
// prepend `OWNER:` if this branch is pushed to a fork
Expand Down
51 changes: 50 additions & 1 deletion pkg/cmd/pr/shared/finder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestFind(t *testing.T) {
baseRepoFn func() (ghrepo.Interface, error)
branchFn func() (string, error)
branchConfig func(string) git.BranchConfig
pushDefault func() (string, error)
remotesFn func() (context.Remotes, error)
selector string
fields []string
Expand Down Expand Up @@ -330,6 +331,7 @@ func TestFind(t *testing.T) {
c.Push = "origin/blue-upstream-berries"
return
},
pushDefault: func() (string, error) { return "upstream", nil },
remotesFn: func() (context.Remotes, error) {
return context.Remotes{{
Remote: &git.Remote{Name: "origin"},
Expand Down Expand Up @@ -373,7 +375,52 @@ func TestFind(t *testing.T) {
c.RemoteURL = u
return
},
remotesFn: nil,
pushDefault: func() (string, error) { return "upstream", nil },
remotesFn: nil,
},
httpStub: func(r *httpmock.Registry) {
r.Register(
httpmock.GraphQL(`query PullRequestForBranch\b`),
httpmock.StringResponse(`{"data":{"repository":{
"pullRequests":{"nodes":[
{
"number": 13,
"state": "OPEN",
"baseRefName": "main",
"headRefName": "blue-upstream-berries",
"isCrossRepository": true,
"headRepositoryOwner": {"login":"UPSTREAMOWNER"}
}
]}
}}}`))
},
wantPR: 13,
wantRepo: "https://github.com/OWNER/REPO",
},
{
name: "current branch with tracking (deprecated synonym of upstream) configuration",
args: args{
selector: "",
fields: []string{"id", "number"},
baseRepoFn: func() (ghrepo.Interface, error) {
return ghrepo.FromFullName("OWNER/REPO")
},
branchFn: func() (string, error) {
return "blueberries", nil
},
branchConfig: func(branch string) (c git.BranchConfig) {
c.MergeRef = "refs/heads/blue-upstream-berries"
c.RemoteName = "origin"
c.Push = "origin/blue-upstream-berries"
return
},
pushDefault: func() (string, error) { return "tracking", nil },
remotesFn: func() (context.Remotes, error) {
return context.Remotes{{
Remote: &git.Remote{Name: "origin"},
Repo: ghrepo.New("UPSTREAMOWNER", "REPO"),
}}, nil
},
},
httpStub: func(r *httpmock.Registry) {
r.Register(
Expand Down Expand Up @@ -407,6 +454,7 @@ func TestFind(t *testing.T) {
},
branchConfig: func(branch string) (c git.BranchConfig) {
c.RemoteName = "origin"
c.Push = "origin/blueberries"
return
},
remotesFn: func() (context.Remotes, error) {
Expand Down Expand Up @@ -539,6 +587,7 @@ func TestFind(t *testing.T) {
baseRepoFn: tt.args.baseRepoFn,
branchFn: tt.args.branchFn,
branchConfig: tt.args.branchConfig,
pushDefault: tt.args.pushDefault,
remotesFn: tt.args.remotesFn,
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/pr/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ func prSelectorForCurrentBranch(gitClient *git.Client, baseRepo ghrepo.Interface
if branchOwner != "" {
if branchConfig.Push != "" {
selector = strings.TrimPrefix(branchConfig.Push, branchConfig.RemoteName+"/")
} else if strings.HasPrefix(branchConfig.MergeRef, "refs/heads/") {
} else if pushDefault, _ := gitClient.Config(context.Background(), "push.default"); (pushDefault == "upstream" || pushDefault == "tracking") &&
strings.HasPrefix(branchConfig.MergeRef, "refs/heads/") {
selector = strings.TrimPrefix(branchConfig.MergeRef, "refs/heads/")
}

Choose a reason for hiding this comment

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

This block is starting to look duplicated with .../finder.go's parseCurrentBranch

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't worry, it will only get worse /s

Jokes aside, IIRC my original plan was to see if I could do a little refactoring when I got to fixing gh pr create. Now my short memory has got the best of me and I can't remember what issues gh pr create has exactly hehe. But if anyone's got some pointers in mind, feel free to share, and I can check them out when/if I find some time to get back on this :)

Choose a reason for hiding this comment

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

Sure: something to follow-up on later. Maybe I'll take a stab sometime

// prepend `OWNER:` if this branch is pushed to a fork
Expand Down
34 changes: 33 additions & 1 deletion pkg/cmd/pr/status/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ Requesting a code review from you
}
}

func Test_prSelectorForCurrentBranch(t *testing.T) {
func Test_prSelectorForCurrentBranchPushDefaultUpstream(t *testing.T) {
rs, cleanup := run.Stub()
defer cleanup(t)

Expand All @@ -384,6 +384,38 @@ func Test_prSelectorForCurrentBranch(t *testing.T) {
branch.Frederick888/main.merge refs/heads/main
`))
rs.Register(`git rev-parse --verify --quiet --abbrev-ref Frederick888/main@\{push\}`, 1, "")
rs.Register(`git config push\.default`, 0, "upstream")

repo := ghrepo.NewWithHost("octocat", "playground", "github.com")
rem := context.Remotes{
&context.Remote{
Remote: &git.Remote{Name: "origin"},
Repo: repo,
},
}
gitClient := &git.Client{GitPath: "some/path/git"}
prNum, headRef, err := prSelectorForCurrentBranch(gitClient, repo, "Frederick888/main", rem)
if err != nil {
t.Fatalf("prSelectorForCurrentBranch error: %v", err)
}
if prNum != 0 {
t.Errorf("expected prNum to be 0, got %q", prNum)
}
if headRef != "Frederick888:main" {
t.Errorf("expected headRef to be \"Frederick888:main\", got %q", headRef)
}
}

func Test_prSelectorForCurrentBranchPushDefaultTracking(t *testing.T) {
rs, cleanup := run.Stub()
defer cleanup(t)

rs.Register(`git config --get-regexp \^branch\\.`, 0, heredoc.Doc(`
branch.Frederick888/main.remote git@github.com:Frederick888/playground.git
branch.Frederick888/main.merge refs/heads/main
`))
rs.Register(`git rev-parse --verify --quiet --abbrev-ref Frederick888/main@\{push\}`, 1, "")
rs.Register(`git config push\.default`, 0, "tracking")

repo := ghrepo.NewWithHost("octocat", "playground", "github.com")
rem := context.Remotes{
Expand Down