Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referencing the upstream/remote PR branch #9024

Open
Rob-Hague opened this issue Apr 29, 2024 · 3 comments
Open

Referencing the upstream/remote PR branch #9024

Rob-Hague opened this issue Apr 29, 2024 · 3 comments
Labels
enhancement a request to improve CLI gh-pr relating to the gh pr command needs-triage needs to be reviewed

Comments

@Rob-Hague
Copy link

Describe the feature or problem you’d like to solve

Often I want to checkout a PR with gh pr checkout NNN and then reference the upstream/"remote-tracking branch" in some way, e.g. git log @{u} or git reset @{u}. Unfortunately, because of the way the branch is configured, I cannot refer to the upstream branch in this way. The error is something like "fatal: upstream branch 'refs/heads/XXX' not stored as a remote-tracking branch".

Proposed solution

I don't have a great solution in mind. The cli currently configures the branch like so:

branch.<name>.remote=<fork url>
branch.<name>.pushremote=<fork url>
branch.<name>.merge=refs/heads/XXX

My first thought was just to set branch.<name>.remote=upstream and branch.<name>.merge=refs/pull/NNN/head, but it seems one cannot push to refs/pull/*.

Then I thought to add back branch.<name>.pushremote=<fork url> but AFAICT there exists no branch-level config for defining the refspec to push to, i.e. a push version of branch.<name>.merge. (We want to fetch from refs/pull/NNN/head at the defined upstream remote but push to refs/heads/XXX at the fork)

So I think having a remote-tracking branch basically requires a remote to be defined, which the cli currently doesn't do for PRs. That's nice because it keeps the remotes clean but personally I would prefer (in the absence of a better solution) if the cli defined a new remote where necessary so that I can have a remote-tracking branch for a PR and refer to it with @{u}.

Additional context

There is a workaround which is to use FETCH_HEAD, i.e. git reset FETCH_HEAD. But one must make sure to do git fetch beforehand when switching regularly between branches.

@Rob-Hague Rob-Hague added the enhancement a request to improve CLI label Apr 29, 2024
@cliAutomation cliAutomation added the needs-triage needs to be reviewed label Apr 29, 2024
@andyfeller andyfeller added the gh-pr relating to the gh pr command label May 10, 2024
@andyfeller
Copy link
Contributor

andyfeller commented May 10, 2024

@Rob-Hague : Thank you for opening this issue! ❤ I'll admit I also don't have a great solution in mind just yet.

There's 2 things I'd like to do to investigate this further:

  1. Understand how git is treating @{u} relative to branch.<name>.remote=upstream and whether this only works on repository remotes for git log and other commands.
  2. Bring this back to the team to discuss how additional remotes may affect other git and/or gh operations.

At the least, this could be a flag or configuration someone elects to turn on assuming no glaring issues. 🤔

Notes

branch.<name>.remote documentation

branch.<name>.remote

When on branch <name>, it tells git fetch and git push which remote to fetch from or push to. The remote to push to may be overridden with remote.pushDefault (for all branches). The remote to push to, for the current branch, may be further overridden by branch.<name>.pushRemote. If no remote is configured, or if you are not on any branch and there is more than one remote defined in the repository, it defaults to origin for fetching and remote.pushDefault for pushing. Additionally, . (a period) is the current local repository (a dot-repository), see branch.<name>.merge's final note below.

The salient bit being "it tells git fetch and git push which remote to fetch from or push to" makes me wonder if this is a use case for git to expand this to other commands.

remote_for_branch(...) logic in git

At a glance, it seems the blast radius of the configuration above is fairly limited, however one particular bit of code is ref-filter.c saying only local branches may have an upstream:

		else if (atom_type == ATOM_UPSTREAM) {
			const char *branch_name;
			/* only local branches may have an upstream */
			if (!skip_prefix(ref->refname, "refs/heads/",
					 &branch_name)) {
				v->s = xstrdup("");
				continue;
			}
			branch = branch_get(branch_name);

			refname = branch_get_upstream(branch, NULL);
			if (refname)
				fill_remote_ref_details(atom, refname, branch, &v->s);
			else
				v->s = xstrdup("");
			continue;

Original gh pr checkout PR

Just going back in time to confirm we've been consistent with branch-specific remotes and seeing the design considerations of the time (no issue behind this unfortunately) 🤔

@andyfeller
Copy link
Contributor

@Rob-Hague : While we figure this out, have you tried manually adding remotes for the repo and modifying the branches to use said remote? seeing how it affected other operations?

@Rob-Hague
Copy link
Author

Thanks for looking into it. Here are some scenarios (run from my fork of https://github.com/sshnet/SSH.NET)

1.

gh pr checkout 1392
# output
From https://github.com/sshnet/SSH.NET
 * [new ref]           refs/pull/1392/head -> nullable
Switched to branch 'nullable'
# output from git config --list
branch.nullable.remote=https://github.com/mus65/SSH.NET.git
branch.nullable.pushremote=https://github.com/mus65/SSH.NET.git
branch.nullable.merge=refs/heads/nullable

git log @{u} does not work here

2.

gh pr checkout 1392
git remote add mus65 https://github.com/mus65/SSH.NET.git
git config branch.nullable.remote mus65
git fetch
# output from git config --list
branch.nullable.remote=mus65
branch.nullable.pushremote=https://github.com/mus65/SSH.NET.git
branch.nullable.merge=refs/heads/nullable

Now git log @{u} works as desired here

3.

git remote add mus65 https://github.com/mus65/SSH.NET.git
gh pr checkout 1392
# output
From https://github.com/mus65/SSH.NET
 * [new branch]        nullable   -> mus65/nullable
Switched to a new branch 'nullable'
branch 'nullable' set up to track 'mus65/nullable'.
# output from git config --list
branch.nullable.remote=mus65
branch.nullable.merge=refs/heads/nullable

git log @{u} works as desired here.

Actually I didn't realise it works in (3) i.e. when the remote is preexisting. Still, it would be nice if the cli could add the remote for me, assuming that one cannot achieve the ideal scenario:

gh pr checkout 1392
# output from git config --list
branch.nullable.remote=upstream
branch.nullable.merge=refs/pull/1392/head
branch.nullable.pushremote=https://github.com/mus65/SSH.NET.git
branch.nullable.???push???=refs/heads/nullable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement a request to improve CLI gh-pr relating to the gh pr command needs-triage needs to be reviewed
Projects
None yet
Development

No branches or pull requests

3 participants