Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 672
SoftTimur Avatar asked May 30 '17 11:05

SoftTimur


People also ask

Can you make a fork of a private repository public?

No. You can fork it and it still remains private. Private collaborators may fork any private repository you've added them to without their own paid plan.

Are GitHub private repos really private?

Private repository data is scanned by machine and never read by GitHub staff. Human eyes will never see the contents of your private repositories, except as described in our Terms of Service. Your individual personal or repository data will not be shared with third parties.


2 Answers

You will definitely need two repositories. But you can create a public part automatically.

For example, you can use git-exporter. It allows you to define file paths available in a public repository. This utility creates a new git repository based on an existing one with a similar commit history. Only allowed files will be included in the commit contents.

Example:

Create config.json:

{
    "forceReCreateRepo": true,
    "targetRepoPath": "my-open-source-repo",
    "sourceRepoPath": ".",
    "allowedPaths": ["build/*"],
    "ignoredPaths": ["src/*"]
}

Then run command npx gitexporter config.json.

Thus, a new repository my-open-source-repo will be created that includes only certain files while preserving the entire commit history.

Then you can push my-open-source-repo and use it as Open Source.

Like so:

cd my-open-source-repo
git remote set-url origin new.github.com/username/open-source-repo-name
git push origin master

You can also create a CI script that will update your public my-open-source-repo automatically.

like image 180
pahaz Avatar answered Sep 28 '22 12:09

pahaz


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.

like image 27
Mark Adelsberger Avatar answered Sep 28 '22 13:09

Mark Adelsberger