0

I'd like to open source a bunch of our private code, while still allowing us to work in private, sharing subsets back with the public community, and incorporate community changes back into our private repo. I believe GitHub can do all of this, but am struggling to make it work in practice. Can you help me figure out how to make this work?

I'm reasonably savvy with git/GitHub for basic flows, but I'm out of my depth for this exercise. I've seen a very good overview here, but it leaves much of the detail as an "exercise to the reader" -- and I can't figure it out. Specifically, here's what I've done so far to test (in glorious detail for future reference by others):

  1. Created a new private repo containing nothing but a README.md file in Expensify/dbarrett_PrivateTest (Can't link to it because it's private)

  2. Cloned it locally with: git clone git@github.com:Expensify/dbarrett_PrivateTest.git

  3. Created a new public repo: https://github.com/Expensify/dbarrett_PublicTest

  4. Made a "bare clone" of the private repo locally: git clone --bare git@github.com:Expensify/dbarrett_PrivateTest.git

  5. Pushed it to the public repo: cd dbarrett_PrivateTest.git git push --mirror git@github.com:Expensify/dbarrett_PublicTest.git

  6. Pulled down my public repo (which is now joyously populated with the private commits): git clone git@github.com:Expensify/dbarrett_PublicTest.git

  7. Edited README.md in the public repo and pushed the public commit: vim README.md git commit -a git push origin master

  8. Rejoiced as I successfully pushed a public commit to the public repo, just as I'm hoping future open source contributors will.

  9. Replayed the same steps in (7) in my private repo, and successfully pushed a private commit to my private repo (and confirmed it didn't show up in the public repo).

    However, that's as far as I've gotten. Here's what I'd like to do next, but can't figure out how:

  10. Pull that public commit down into my private repo, simulating how I would incorporate public contributions into my private codebase.

  11. Push that private commit into the public repo, simulating how I would contribute my own changes back into the community.

I've seen talk of some more advance git concepts than I know how to handle (remotes, fetching, etc), so I'm a bit over my head and can't figure out the next step. Can you make any suggestions? Thanks!

Community
  • 1
  • 1
quinthar
  • 443
  • 4
  • 8

1 Answers1

0

It might be easier if you use the same local repo for managing both the private and public repos, instead of having them in different local folders. You would have a master branch, an origin/master (presumably the private remote repo), and public/master (public remote repo). It would also make sense to have different branch names locally for the private and public repos (master_private vs master_public) to easily manage them separately but in the same repo.

master_public tracks the master branch on the public repository. master_private (or just plain master) tracks the master branch on the private repository.

To handle step 10:

git fetch public
git checkout master_public
git merge public/master

#local master_public is now updated with 
#changes in public repository's master branch

git checkout master_private
git merge master_public
#local master_private now contains changes from public repo

git push origin master_private:master
#remote private repo now contains changes from public repo

To handle step 11:

git fetch origin
#origin is the private remote name
git checkout master_private
...commit work locally or merge with feature branch ...
git push master_public:master

#remote private repo has local changes you made but public repo does not

git checkout master_public
git merge master_private
#local master_public branch has private changes
git push master_public:public

#public remote has changes from private remote now

If you only want to subsets of changes from the private repo, that is a different story. It will become rather tedious to manage. If you're wanting that, I think git cherry-pick would help with that http://git-scm.com/docs/git-cherry-pick

kmc059000
  • 2,937
  • 1
  • 23
  • 27
  • Ooh, this is interesting: use two branches locally, and push each branch to a separate GH repo globally -- one public, and one private? That's interesting. The challenge is the private branch will have a ton of code that should never make it into the public branch (eg, projects that depend on the same shared code, but that aren't open sourced). My fear is accidentally pushing a ton of private code to the public repo. Accordingly, you're probably right that the only safe way to do it is with cherry-picks, which will be pretty tedious. Maybe doing it by hand with diff/patch is easier/safer. – quinthar Jul 27 '14 at 18:38
  • Regardless, I'm going to accept this answer as it seems like as good a solution as any, even though I'm starting to second-guess the whole approach in the first place. Thanks! – quinthar Jul 27 '14 at 18:44
  • I was worried that is what you were trying to do. Personally, I'd consider what you're wanting to do a fools errand. Without knowing your project, chances are that the changes you want to make public will be so intertwined with the private changes, that even cherry picking wont work well. – kmc059000 Jul 28 '14 at 02:05