Detect push target for local branches without upstream configuration
Commands such as pr status inspect the current branch and check its upstream configuration to see where it's pushed while resolving the branch to the associated PR.
Some branches might be pushed but have no upstream configuration (simple git push <remote> HEAD withough -u). Right now mechanisms such as prSelectorForCurrentBranch() don't recognize such branches as being published to a remote. We should perhaps iterate over all remotes and assume one to be a push target if we find a same-named tracking branch on one. (This will perhaps be prone to false-positives, but it's a marked improvement over current behavior.)
Reported by @rista404 https://github.com/cli/cli/pull/567#issuecomment-593366743
Hi!
Ideally, the first step would be to use the existing Git logic for triangular workflows, see:
These configurations are unfortunately under-used because under-advertised (and are missing command-line options) but are specifically geared toward triangular workflows (i.e. GitHub-style forking workflows).
Adding a little more details:
The way I configure my feature branches is that they track the upstream branch in which they will eventually be integrated, and I push them to my own fork. Basically the configs above enable a workflow like this:
# first time only: setup 'origin' as the default push remote (I usually fork on GitHub, then clone my fork)
git config [--global] remote.pushDefault origin
# first time only: change default push behaviour to 'current'
git config [--global] push.default current
# create a feature branch
git fetch upstream
git checkout -b my-feature upstream/master
# work work work
# push my branch to my fork
git push # no other arguments needed ! (does `git push origin my-feature`)
# work work work
# rebase on latest master
git fetch # no other arguments needed! (does `git fetch upstream`)
git rebase # no other arguments needed! (does `git rebase upstream/master`)
# or in one step:
git pull --rebase # (does `git pull --rebase upstream master`)
# or if your project's workflow uses merge:
git fetch # no other arguments needed!
git merge # no other arguments needed! (does `git merge upstream/master`)
# or in one step:
git pull # (does `git pull upstream master`)
So it enables a pretty cool workflow in my opinion, which feels really "natural".
So it would be great if gh could understand this workflow a little bit more. For example, I don't want gh to do git push -u origin my-feature when I open a pull request, because this defeats the purpose of the above configs; the "upstream" should stay upstream/master.
EDIT: here is a GitHub blog post dating from the release of Git 2.5, describing this workflow: https://github.blog/2015-07-29-git-2-5-including-multiple-worktrees-and-triangular-workflows/#improved-support-for-triangular-workflows
This makes gh pr status useless in github-actions - see https://github.com/pangaeatech/azure-test-deployment/pull/8#issuecomment-1065807897
Is there a way to specify the PR URL when calling this?
Is there a way to explicitly set the upstream config from github actions as a workaround for this?
Maybe related (or not), gh pr create seems not to work in a fork configuration with only one remote configured and a fetch/push strategy to pull from upstream and push to fork. For instance:
origin [email protected]:cli/cli.git (fetch)
origin [email protected]:org-where-forked/cli.git (push)
gh pr create gives then the following error: pull request create failed: GraphQL: Head sha can't be blank, Base sha can't be blank, No commits between <target-branch> and <current-branch>, Head ref must be a branch (createPullRequest).
gh version 2.11.3 (2022-05-25)
@stephanedaviet I would say it's related. To work around this, you can say:
gh pr create -H org-where-forked:<branch>
Worth noting that git itself tells you not to use such a configuration (e.g. from git help remote):
Note that the push URL and the fetch URL, even though they can be set differently, must still refer to the same place. What you pushed to the push URL should be what you would see if you immediately fetched from the fetch URL. If you are trying to fetch from one place (e.g. you're upstream) and push to another (e.g. your publishing repository), use two separate remotes.
(not saying gh shouldn't support it, just noting that it's not recommended)
Worth noting that git itself tells you not to use such a configuration (e.g. from
git help remote):Note that the push URL and the fetch URL, even though they can be set differently, must still refer to the same place. What you pushed to the push URL should be what you would see if you immediately fetched from the fetch URL. If you are trying to fetch from one place (e.g. you're upstream) and push to another (e.g. your publishing repository), use two separate remotes.
(not saying
ghshouldn't support it, just noting that it's not recommended)
Good catch! It will make me re-examine my practice.
@mislav I tried the same. Still couldn't create the pr. :'(