Skip to content

gh pr view cannot find PR from branch when fork is in the same org as upstream #10077

@williammartin

Description

@williammartin

Describe the bug

When there is a PR from a fork in the same org as the upstream, pr view will fail to find it, when determining the PR via the branch.

Testscript to demonstrate the issue. Note that we have to use gh api to create the PR because pr create cannot handle fork in the same org as the upstream for different reasons.

# Setup environment variables used for testscript
env REPO=${SCRIPT_NAME}-${RANDOM_STRING}
env FORK=${REPO}-fork

# Use gh as a credential helper
exec gh auth setup-git

# Create a repository to act as upstream with a file so it has a default branch
exec gh repo create ${ORG}/${REPO} --add-readme --private

# Defer repo cleanup of upstream
defer gh repo delete --yes ${ORG}/${REPO}
exec gh repo view ${ORG}/${REPO} --json id --jq '.id'
stdout2env REPO_ID

# Create a fork in the same org
exec gh repo fork ${ORG}/${REPO} --org ${ORG} --fork-name ${FORK}

# Defer repo cleanup of fork
defer gh repo delete --yes ${ORG}/${FORK}
sleep 1
exec gh repo view ${ORG}/${FORK} --json id --jq '.id'
stdout2env FORK_ID

# Clone the fork
exec gh repo clone ${ORG}/${FORK}
cd ${FORK}

# Prepare a branch
exec git checkout -b feature-branch
exec git commit --allow-empty -m 'Empty Commit'
exec git push -u origin feature-branch

# Create the PR spanning upstream and fork repositories, gh pr create does not support headRepositoryId needed for private forks
exec gh api graphql -F repositoryId="${REPO_ID}" -F headRepositoryId="${FORK_ID}" -F query='mutation CreatePullRequest($headRepositoryId: ID!, $repositoryId: ID!) { createPullRequest(input:{ baseRefName: "main", body: "Feature Body", draft: false, headRefName: "feature-branch", headRepositoryId: $headRepositoryId, repositoryId: $repositoryId, title:"Feature Title" }){ pullRequest{ id url } } }'

# View the PR
exec gh pr view
stdout 'Feature Title'

Implementation Details

When using the PR Finder, gh will resolve the current branch name from git. It then uses the git remote for that branch, and determines whether it should be prepended with <owner>:

if !strings.EqualFold(branchOwner, f.repo.RepoOwner()) {
prHeadRef = fmt.Sprintf("%s:%s", branchOwner, prHeadRef)
}

Later, it does another string concatenation based on whether a fetched PR isCrossRepository, inside the pr.HeadLabel() method, which is then compared to the aforementioned branch:

if pr.HeadLabel() == headBranch && (baseBranch == "" || pr.BaseRefName == baseBranch) && (pr.State == "OPEN" || resp.Repository.DefaultBranchRef.Name != headBranch) {

However, the original decision to prepend with owner only makes sense if the fork is in a different org.

Acceptance Criteria

Given I have a PR between a fork and upstream in the same org
And Given I have the fork PR branch checked out locally
When I run gh pr view
Then I should see the PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggh-prrelating to the gh pr commandp3Affects a small number of users or is largely cosmetic

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions