-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
Description
Note
This is very similar to #9364, but instead of all branches pushing to a particular remote (git config remote.pushDefault origin
), we can select just one (git config branch.<branch>.pushRemote origin
).
When using a triangular workflow, it is possible to have a branch merge changes from upstream
while pushing changes to a fork
. For example, imagine that we are working on a branch feature
in our fork and we want to continually be rebasing on upstream/main
, we could do that like so:
First we clone the fork:
➜ gh repo clone williammartin/test-repo
Cloning into 'test-repo'...
remote: Enumerating objects: 160, done.
remote: Counting objects: 100% (45/45), done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 160 (delta 33), reused 21 (delta 20), pack-reused 115
Receiving objects: 100% (160/160), 24.89 KiB | 2.26 MiB/s, done.
Resolving deltas: 100% (53/53), done.
From https://github.com/williammartin-test-org/test-repo
* [new branch] main -> upstream/main
* [new tag] vDraftTriage -> vDraftTriage
* [new tag] vDraftyBoi -> vDraftyBoi
! Repository williammartin-test-org/test-repo set as the default repository. To learn more about the default repository, run: gh repo set-default --help
➜ cd test-repo
Then we check out a branch so that it is tracking upstream/main
:
➜ git checkout -b remote-branch-push-remote-feature upstream/main
branch 'remote-branch-push-remote-feature' set up to track 'upstream/main'.
Switched to a new branch 'remote-branch-push-remote-feature'
➜ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = https://github.com/williammartin/test-repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
[remote "upstream"]
url = https://github.com/williammartin-test-org/test-repo.git
fetch = +refs/heads/*:refs/remotes/upstream/*
gh-resolved = base
[branch "remote-branch-push-remote-feature"]
remote = upstream
merge = refs/heads/main
Then we set branch.<branch>.pushRemote
to origin
so that our new branch is pushed to origin
instead of upstream
:
➜ git config branch.remote-branch-push-remote-feature.pushRemote origin
➜ test-repo git:(remote-branch-push-remote-feature) cat .git/config
...
[branch "remote-branch-push-remote-feature"]
remote = upstream
merge = refs/heads/main
pushRemote = origin
So we create new a commit on the branch, and a new pull request (note that git push
knew where to push to due to branch.<name>.pushRemote
):
➜ git commit --allow-empty -m "remote-branch-push-remote-feature" && git push
[remote-branch-push-remote-feature 7841070] remote-branch-push-remote-feature
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 202 bytes | 202.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'remote-branch-push-remote-feature' on GitHub by visiting:
remote: https://github.com/williammartin/test-repo/pull/new/remote-branch-push-remote-feature
remote:
To https://github.com/williammartin/test-repo.git
* [new branch] remote-branch-push-remote-feature -> remote-branch-push-remote-feature
➜ gh pr create -H williammartin:remote-branch-push-remote-feature --title remote-branch-push-remote-feature --body remote-branch-push-remote-feature
Creating pull request for williammartin:remote-branch-push-remote-feature into main in williammartin-test-org/test-repo
https://github.com/williammartin-test-org/test-repo/pull/48
However when we try to view our newly created PR it fails because it is trying to find a PR from main
since that is the current merge
entry in the branch config:
➜ gh pr view
no pull requests found for branch "main"
Unfortunately, resolving @{push}
doesn't work because the merge
entry for the branch config has a different branch name:
➜ git rev-parse --abbrev-ref remote-branch-push-remote-feature@{push}
fatal: cannot resolve 'simple' push to a single destination
Proposed Solution
Fortunately we know that if our push.default = current / simple
(meaning local and remote branch have the same name) then with the branch.<name>.pushRemote
telling us the correct remote we can concatenate these which will give us: origin/remote-branch-push-remote-feature
and we'll be able to find the PR!
Additional context
This is already implemented by #9208, I'm just capturing the specific enhancement separately as it was kind of hard for me to understand as someone that's never used these features before.