24

I forked a public repo and made the new repo private.

I added a new remote branch on my private repo with some fixes committed.

Now, I want to create a pull request from the branch in my private repo towards the public repo I forked from.

I select the branch in my private repo and click "Pull request".

I click on "Change commits".

I can't change the organisation/repo owner. I only see my organisation, but not the one of the public repo. I could only create a pull request against master branch of my private repo, but that's not what I want.

Is it not possible to fix something of a public repo in a private one and create a pull request afterwards?

cb4
  • 6,689
  • 7
  • 45
  • 57
Sebi
  • 8,323
  • 6
  • 48
  • 76
  • Why would you want to work a public repo into a private one? – TimWolla Jan 12 '12 at 12:05
  • Because I can't release all my changes to the public. I follow the public one from my private one and would get the public changes merged in. – Sebi Jan 12 '12 at 12:07
  • 6
    I just got confirmation from GitHub's support force that currently it is not possible to create a pull request from a private repo to a public one you don't own. – Sebi Jan 12 '12 at 13:46
  • 2
    And as I found out in the meantime, it is not possible at all to create a pull request from a private towards a public repository, no matter if you own the repos. – Sebi Jan 12 '12 at 18:20
  • 1
    This question does not make any sense, and it just shows a problem in your workflow. Your fork in GitHub should be public, your workink clone in your laptop is private, then you push to your public fork only the commits you intend to make public. This is the normal you to work with GitHub. – mljrg Aug 25 '17 at 10:42
  • 1
    @mljrg Please just read my previous comments, which explain why that was needed at that point in time. – Sebi Oct 05 '17 at 09:21
  • If what you needed was "Because I can't release all my changes to the public." then keep those changes just in your local working copy in your laptop, and push what you can make public to your own public fork of the repo you want to contribute to. Then from your public fork open a pull request to the latter repo. This is the typical PR workflow. Public and private generally do not play well together, because handling permissions without getting wrong is too complex, so the best is to separate public and private concepts when designing a system. This applies to Github and whatever system. – mljrg Oct 06 '17 at 11:22
  • 1
    What you propose has been posted 5 years ago already as accepted answer... – Sebi Oct 09 '17 at 13:07

3 Answers3

13

One solution would be to fork the original public repo into your own public repo on GitHub.
Then duplicate your forked public repo into a private one.

You then clone both on your local workstation, and:

  • do public and private modifications on your private local repo
  • push private modifications first to your local public repo
  • then push them to your GitHub forked public repo
  • make your pull request from your forked public repo on GitHub.
cb4
  • 6,689
  • 7
  • 45
  • 57
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    So basically I need to add an indirection by having a public repo owned by myself in between? – Sebi Jan 12 '12 at 12:21
  • 1
    @Sebi: that is the idea, to keep a clean separation between public and private modifications. – VonC Jan 12 '12 at 12:22
  • 1
    I was hoping it was possible without :-) – Sebi Jan 12 '12 at 12:37
  • @Sebi: I suspect this scenario is a bit too rare to be supported right now. – VonC Jan 12 '12 at 12:57
  • 1
    It's not working. I tried to first create a public fork and based on that fork, create a private fork. Unfortunately, you can only have a single fork of every project. Afterwards, I tried forking with a public repo and afterwards created a new private repo using my public fork as remote branch. Still, it is not possible to create a pull request between a private and public repo. So I need a completely different approach. Not very satisfying. – Sebi Jan 12 '12 at 16:38
  • 3
    @Sebi: "it is not possible to create a pull request between a private and public repo" But... you don't need to make that kind of pull request: both private and public repo would be yours. If you cannot do two forks, simply fork once, and clone that repo locally, pushing it to a private repo of yours (which is not a fork). The only pull request would be between your (fork) public repo and the original public repo. Any communication between *your* private and *your* public repo are done through pushes from your *local* repos to your remote repos (no request necessary). – VonC Jan 12 '12 at 17:11
  • @Sebi: in short, with that kind of config (one public repo fork, and one private repo, both that you own), it.will.just.work. – VonC Jan 12 '12 at 17:13
7

2021 Update

@VonC's answer is conceptually correct and still the one supported by GitHub. After nine years, @Sebi finally gets the answer he wanted -- I eliminated the "indirection" he commented on that occurs in the second bullet of VonC's answer.

For my use case, I need to make both public and private changes to a public repo. Public commits can be pushed periodically as soon as they are ready. Private changes must remain in my private repo until I complete my PhD research. At that time, I'll need all private changes to flow from my public fork to the original public repo via pull requests.

The bulk of the work is getting things set up correctly. I provided detailed steps in this SO answer. The following steps are done exclusively in the eclipse GUI (v2020-12; EGit 5.11), but can easily be translated to command line operations. The repositories I used are these:

  • eclipse/org.aspectj is the original public repo; the upstream remote for fetching
  • cb4/org.aspectj is my fork; the origin remote for pushing
  • cb4/remPrivAJ is my remote private repo; the private remote for pushing and pulling
  • I:\local is the local repo on my workstation

For github authentication, I used ssh with an ed25519 ssh key (how-to in this SO question) so my connection URIs look like this: ssh://git@github.com/<user>/<repo>.

Notation: -> is a mouse click or selection; right-> and double-> are right-click and double-click, respectively.


I separated public from private changes by putting each in separate branches: pub for public changes; priv for private changes. I'm fairly new to git, so there may be a better way to do this.

  1. Create and configure branches
  • 1.1 In the eclipse Git Perspective, under the local repo: open Branches then open Local (-> v beside each)
  • 1.2 For the private branch: right-> master -> Create Branch -> Select -> private/master -> Ok enter priv for Branch name: -> Configure upstream for push and pull -> When pulling: Merge -> Finish
  • 1.3 For the public branch: right-> master -> Create Branch enter pub for Branch name: -> Finish
  • 1.4 The result: commit numbers in my private repo private/master, my public fork orign/master, and the original public repo upstream/master all match config

  1. Make a private change and commit
  • 2.1 Make some changes, then see detailed info about them on the Git Staging tab in the Git Perspective
  • 2.2 Select individual changes and add them to the index by clicking the green plus sign
  • 2.3 OR select them all by clicking green double plus sign
  • 2.4. Enter a commit message and -> Commit and Push -> Preview -> Push -> Close
  • 2.5 Note the new commit number
    commit

  1. Push private changes to the public fork
  • right-> priv -> Push Branch -> Remote: dropdown v -> origin: URI (mine is origin:ssh://git@github.com/cb4/org.aspectj) double-> master in the Branch: text box and type priv then double-> priv [branch] -> Preview -> Push -> Close

  1. On GitHub, private changes in my public fork. Note same commit number here as above (click image to zoom). changes pushed

  1. To complete the process and open a pull request for a private change against the original public repo, just click on Compare & pull request and Voila! (click image to zoom). pull request

Additional Features and Functions

  • Of course, you can push public commits to the public fork: right-> pub -> Push Branch -> Preview -> Push -> Close
  • Pull and merge updates from the original public repo as frequently as it changes to reduce merge conflicts: under Remotes right-> upstream -> Fetch
  • Then push them to your fork: under Remotes right-> origin -> Push
  • And to your private repo: under Remotes right-> private -> Push
cb4
  • 6,689
  • 7
  • 45
  • 57
4

I doubt it's intended by Github but you can actually make a pull request from a private to a public repo with a bit of simple DOM manipulation:

  1. Make your changes on your private repo, probably on a fresh branch.
  2. Start a pull request. Hit the change commits button.
  3. Open up an editor that allows you to modify the DOM. Things like Firebug or the Safari web inspector or Chrome developer tools seem to work fine.
  4. Edit the base branch repository. You'll want to change the selected option tag's value.
  5. Next, click on the branch name (and change it if you want). You need to do this to trigger an ajax update.
  6. Update the commit range and you should be good to go.

Some caveats:

  • Clicking the commit links or view file will 404 for the public or users who aren't listed as collaborators. Everything seems fine once it's merged in, but it may be a bit weird for the maintainer of the public repo.
  • The pull request needs to be accepted only from the UI. I don't think it'll let anyone merge or cherry-pick the commits in manually. Conflicts will likely need to be resolved by the private repo owner.
Ben
  • 39
  • 3
  • 2
    Actually, that sounds like a bug to me. I just hope they don't have more such holes in their security model :-) – Sebi Apr 27 '12 at 12:35