Skip to content

gh pr create should allow defaulting to the private fork #350

Description

@mtopolnik

This comment by @mislav seems to state the current view of the CLI project regarding the choice of whether to push the local topic branch to origin or upstream when both are accessible. The logic is simple: prefer pushing to upstream, falling back to origin when access is denied.

As a member of a medium-sized open-source project, Hazelcast Jet, I can attest that our process demands pushing to origin while developers also have write access to upstream because the same devs approve and merge PRs after review.

Proposed solution

A very convenient solution would be to introduce a property on the repository itself, visible on the GitHub web interface. The property would tell the Pull Request policy in effect, it could be "push your branch to the central repository" vs. "ask for your private fork's branch to be pulled". This would be useful on its own and would allow enforcing this policy when creating pull requests through other means as well. Then the CLI tool would just follow it.

Activity

  1. joshtriplett commented on Feb 12, 2020

    @joshtriplett

    This would be necessary for Rust developers as well, and many other projects. People with commit access to the main rust-lang/rust repository are still expected to create pull requests from their own forks, not push PR branches to the main repository.

    Having a way for projects to specify a default policy makes sense as well.

  2. viliam-durina commented on Feb 13, 2020

    @viliam-durina

    IMO it's rather unusual that branches are created in the central repository. Normally you create them in your fork and you're responsible for naming them and cleaning them up and the mess is contained in your fork, not in the central repo. If everyone has branches in the central repo, after a while you'll have stale branches for which you will have to investigate whom do they belong to.

  3. edwarnicke commented on Feb 15, 2020

    @edwarnicke

    Agreed... this behavior is both contrary to our current process and dangerous (we do things on branch create with GitHub actions, things that should not be done just because someone wants to create a PR).

    I've been doing Open Source for two decades now... I'm not aware of any major open source project where just because you have write on the upstream repo you routinely push your local dev branches there to start PRs.

  4. edwarnicke commented on Feb 15, 2020

    @edwarnicke
  5. jglick commented on Feb 17, 2020

    @jglick

    enforcing this policy when creating pull requests through other means as well

    In particular, some time back I requested that the GitHub web editor create a branch in my fork even if I happen to have write access to the repository. Currently this GUI feature is unusable in such cases as I am not comfortable polluting the shared repository with branches named jglick-patch-1, even if I do remember to clean them up after merge.

  6. billygriffin commented on Mar 2, 2020

    @billygriffin
    Contributor

    Thanks for all the feedback everyone.

    Really, it ought to be able to tell which of the remotes is the parent (regardless of their names) and then just do the obvious thing by default (issues and PRs always refer to the parent, but pushed branches should always go to the fork that you own).

    This from @lgritz in #383 aligns with what @ampinsk and I (and others) have discussed after trying to wrap our heads around these issues.

    We're thinking about this as the distinction between consuming vs. contributing.

    Consuming

    When you're consuming information, the relevant information most frequently relates to the parent repository. This includes the status, list, and view commands for both issues and PRs. This is already the behavior of GitHub CLI.

    Unfortunately, for workflows that don't have a typical parent/fork relationship as in #439, these defaults fall down, but since you're able to specify the repo with a flag, we think at least for now this is a good path forward.

    Contributing

    When you're contributing, our assumption is that if you have a fork, defaulting to push your branch to your fork seems like a reasonable assumption. This is different than our current way of defaulting to the parent and then only using the fork if you don't have write access (which is the root of #350). One important distinction though is that on pr create, we don't want to prompt you to create a new fork though unless you don't have write access.

    While we're attracted to the original proposed policy solution per repository, that's not something we're likely able to get shipped very quickly, so changing the defaults for contributing seems like a reasonable compromise.

    Let me know if anything here sounds incorrect as a next step.

  7. jglick commented on Mar 3, 2020

    @jglick

    on pr create, we don't want to prompt you to create a new fork though unless you don't have write access

    Since I rarely want to push a branch to the origin repository, and I work on a lot of different repositories some of which I only incidentally have write access to (typically via some broadly defined team), this would still make pr create too unsafe to use. Would it be possible to prompt for a fork the first time gh pr create is run on a given local repository for which only a single remote is defined, but remember the decision not to do so via a flag in .git/config?

    [ghcli]
    	fork = false
  8. mislav commented on Mar 3, 2020

    @mislav
    Contributor

    @jglick We don't intend for these prompts to be repetitive/tiresome. After the first time the person has chosen their preference, we would basically remember two bits of information per-repository:

    1. Preferred "base" for querying issues/PRs and submitting PRs to;
    2. Preferred push target when submitting PRs.

    With (1) we aim solve the use-case of people wanting to maintain their fork separately of its parent repo. With (2) we aim to solve the case of people who want to contribute to a project they have direct write access to but they still want/need to instead push to a fork.

  9. billygriffin commented on Mar 4, 2020

    @billygriffin
    Contributor

    @jglick Thanks! One clarifying question. Presumably for the repos where you do have write access, you also already have a fork, right? The case I was referring to is that if you have write access to a repo and do not already have a fork of that repo, we shouldn't prompt you to create a brand new fork. If we did ask that, we'd be inserting that prompt for every project period, and that feels way too heavy-handed to me.

    My assumption is that if the person has write access to the repo they're in and does not have a fork, pr create should just push the branch to the existing repo.

  10. lgritz commented on Mar 4, 2020

    @lgritz

    Sometimes I'm the owner (or have push privileges) for the canonical project home repo, but I still want to stage my PRs in my clone. Usually, "origin" is my clone and I have the canonical repo as remote with another name.

  11. jglick commented on Mar 4, 2020

    @jglick

    Presumably for the repos where you do have write access, you also already have a fork, right?

    No, not necessarily. I would after the first PR I filed in that repo. This was my point in #350 (comment).

    #350 (comment) seems straightforward and mostly unobtrusive.

  12. jglick commented on Mar 4, 2020

    @jglick

    "origin" is my clone and I have the canonical repo as remote with another name

    Interesting…I always name the canonical repo origin (the default from git clone) and name my fork, if and when I need one, fork. There seems to be no universal convention, unfortunately.

  13. lgritz commented on Mar 4, 2020

    @lgritz

    @jglick Haha, yeah I do this specifically because my fingers are too prone to mindlessly typing "git push origin ..." and I don't want that to accidentally push to the canonical repo that everybody else pulls from. To keep myself from making mistakes, I create my own fork on GH, clone my account's fork locally, then add the canonical home as a second remote with a name that is less habitual. I suspect this is a common workflow.

  14. joshtriplett commented on Mar 4, 2020

    @joshtriplett
  15. jglick commented on Mar 4, 2020

    @jglick

    To keep myself from making mistakes

    In my case I almost never type git push REMOTE BRANCH (I only use tracking branches), but I have on occasion solved a similar problem by using git://github.com/ORG/REPO as the origin remote, since this cannot be pushed to. (Only works for public repositories.)

    Anyway, yes the point stands that it is unwise to base any behaviors on the name or order of remotes.

  16. self-assigned this
    on Mar 5, 2020
  17. casperdcl commented on Mar 17, 2020

    @casperdcl

    Can't we just add a CLI arg for now before discussing defaults? Basically #480:

    gh pr create --remote myuser/myfork
  18. mislav commented on Mar 30, 2020

    @mislav
    Contributor

    Thank you everyone who weighed in on this.

    Since there seem to be many people who would always prefer to push to a fork even if they have write access to the canonical repository, we've changed the default for the next release.

    To keep the codebase simpler, we opted to not add any configurability for the preferred push target for the head branch at this time. (We might reconsider this in the future, based on user feedback.) Instead, what just got merged to master are these changes:

    1. When opening a pull request to OWNER/REPO, for example, if there exists your fork such as myself/REPO or an org-owned fork that you have write access to such as myorg/REPO, the fork will always be preferred as a push target, even if you technically have write access to OWNER/REPO.

      It doesn't matter whether the local repository already has a git remote pointing to that fork or not; a missing remote will be added automatically.

    2. If the user needs control over where exactly the branch is pushed before creating a pull request, they can push with git and gh will now respect that:

      $ git push myremote HEAD
      $ gh pr create  # detects that the current branch was published to "myremote"
    3. As before, explicitly choosing the pull request base repository (the repository where the pull request is to be opened in) is possible via gh pr create -R OWNER/REPO.

  19. casperdcl commented on Mar 30, 2020

    @casperdcl

    🎊 though I can see a problem where an unsuspecting user expects (1) to happen but since they've just run git push myremote HEAD, (2) actually happens.

  20. jglick commented on Mar 30, 2020

    @jglick

    if there exists your fork such as myself/REPO

    To be clear, what if your fork has a different name? Sometimes it will be for example jglick/something-1 because I already have a fork jglick/something of an unrelated repository from another org. Sometimes it will be jglick/old-name because I forked it before org/old-name was renamed to org/new-name, and had no particular need to rename my fork to match. From looking at #680 I think these cases are handled, I just wanted to confirm.

    And again as in #350 (comment), what about the case that I happen to have write access to a repository but did not happen to have forked it yet? My understanding of #680 is that gh pr create will still silently push to the origin. If I am paying attention and notice this, I can

    git push origin :topic-branch # does this close the PR?
    gh repo fork
    gh pr create # hope this works now?
  21. mislav commented on Mar 30, 2020

    @mislav
    Contributor

    To be clear, what if your fork has a different name?

    I should not matter what name does the fork have; we just look up any forks of the original repo that you are affiliated with.

    And again as in #350 (comment), what about the case that I happen to have write access to a repository but did not happen to have forked it yet? My understanding of #680 is that gh pr create will still silently push to the origin.

    That is true; thanks for bringing this up! Yes, we've made the call that if you haven't forked the repo yet and you have write access to it, we assume you want to push directly to it. People who want to avoid that should fork the repo before gh pr create, either with gh repo fork or via the GitHub web interface.

  22. jglick commented on Mar 30, 2020

    @jglick

    OK, thanks for clarifying.

  23. RWOverdijk commented on Apr 30, 2020

    @RWOverdijk

    We work on a private repo on my user account and any PR I make from the cli now gets pushed to one of my colleagues their fork. I don't care, it just looks dumb.

    I love impersonating people.

  24. casperdcl commented on Apr 30, 2020

    @casperdcl

    this comment: #350 (comment) :D

  25. gibfahn commented on May 4, 2020

    @gibfahn

    I use the @{push} branch configurations to always make sure git push goes to the right place, it would be nice if I could configure gh to respect this.

  26. xnox commented on May 29, 2024

    @xnox
    1. When opening a pull request to OWNER/REPO, for example, if there exists your fork such as myself/REPO or an org-owned fork that you have write access to such as myorg/REPO, the fork will always be preferred as a push target, even if you technically have write access to OWNER/REPO.

    this is not happening for me, I am getting a choice of repositories the first one being owner/repo (which i happen to have write access to) and my fork is listed second, and it doesn't do this automatically (i am presented with interractive menu) and i'm failing to make this work non-interractive.

    How does one troubleshoot this? The repos in question are https://github.com/wolfi-dev/os and https://github.com/xnox/os ideally want to automatically have push target at xnox/os.

  27. xnox commented on May 29, 2024

    @xnox

    is there something like gh-resolved = fork ?

  28. added a commit that references this issue on Jul 21, 2025
    9faadbf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementa request to improve CLI

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions