Search code examples
gitgithubrepository

GitHub: Make a private repository partially public


I have built a project with html + css + javascript on GitHub for a half year. It has been in a private repository, there is only one branch.

Now I want to make this repository partially public, such that:

  1. Users can use the issues feature to ask questions or write requirements, I could respond to them, we could have discussion.

  2. Actually, users don't need to see the code. But as we are on GitHub, I may want to make a small part of files public.

  3. I don't want to lose the commit history.

Could anyone tell me what are the steps (and commands ideally) I should follow?

Do I have to re-organize my folders, for example, make a public folder and a private folder?


Solution

  • The first thing to understand is the GitHub permissions model. To submit issues, etc. requires some level of permission to a repo. Read should be sufficient.

    But read does also mean "able to see all code and history". And able to see even means able to copy and fork, even though you control what can be written back to your repo. And there is no access level lower than "read (all the code)".

    So if you want to keep your code to yourself, then creating some sort of project page apart from github, and tapping into a dedicated issue tracking system there, may just make more sense for what you're trying to do.

    If you do decide that some code should be public, then you'd have to have two repos. The repo with the public code could be made read only, or read/write if that better meets your needs for that subset of the code. Either way it could then host issue discussions, etc.

    Splitting a subset of code into a public repo isn't too hard, though it's harder if you want the public repo to have full history as well. You'll want to avoid creating two divergent histories of the public code, so you'll probably have to remove the public code from the private repo. (It can be re-introduced as a submodule - a link to the public repo - but in the simplest case that does mean you'll want to organize the public code under a single directory.)

    If only current versions need to be made public, then it's straightforward. You init the new repo, move the files from one to the other, create the submodule link if you want it.

    If you want to publish history of the published files, then you'd have to do something like git filter-branch to create the public repo from (a clone of) the original repo. The exact procedure depends on the exact requirements, but generally you might use either (a) a subdirectory-filter to publish only the contents of one directory (to the root of the new repo) - but it sounds like your code isn't arranged to make that easy; or (b) an index-filter to remove the files you want to keep private (while keeping the existing directory structure for the files that remain); or (c) a tree-filter and as complex a script as you like to move, remove, or add files around, transforming an "original repo" version into a corresponding "public repo" version.

    If you do split the history, you'll probably still want to keep the history of the public files in the original repo simply because linking the repos' histories is rather difficult. It's not a huge practical limitation most of the time, unless the size of the history is considerable.