Background: I'm in the process of cleaning up a project before releasing it as open-source. During the code history there's been a bunch of things I don't really want to show up in a public repository (swearing in comments, hardcoded paths, embarrassing pieces of code), so I only want the public to see the code base after the cleanup cut-off point - yet I want to retain full history in my own private repository.
After the cutoff point the private and public repositories are going to be kept entirely in sync. Apart from local non-pushed temporary branches, there won't be any private branches; the master branch on both repositories should be identical, except the public history is chopped at the cut-off point.
As far as I can tell Git requires repositories having full history, so I can't directly push my local master branch to both the public and private repositories. I guess it would be possible creating a separate 'public' branch and using history rewriting, but this would require merging the private branch to the public before pushing code to the repositories - I'd like a setup that requires as little manual work as possible.
The public repository is intended to be pull-only, with me doing integration. The private repository will be hosted on my own linux server, so it would be possible to set up commit hooks that auto-merge to a different (public) repo and then push to the public repo. I hope there's a cleaner solution, though - there's probably a way to structure this that I haven't thought of.
Thanks in advance for any suggestions :)
Update 1
Trying to follow VonC's recommendation, this is what I've got so far:
Assumptions: Private repository is cleaned up, committed locally, and pushed to git@server:private.git . Public repository created with files from last private commit, is committed locally, and pushed to git@server:public.git .
1) ~/priv$ git remote add public git@server:public.git
2) ~/priv$ git fetch public
warning: no common commits (stuff snipped) * [new branch] master -> public/master
3) ~/priv$ git log --format='%H %s'
d2d66cf2861ac7136ee3dc04467781825413b084 Cleaned up code base, ready for public! 9ba0ccf4c819eb85dbe4613caec959b04edfb39a Commit #2 a37c3c645dcdc4d8e5fc7ef3c53727cbf1d903ad First (private) commit.
The top hash (d2d66...) is the private head commit.
4) ~/priv$ git log --reverse --format='%H %s' public/master
090a335746ecb03ea5362909be4969b87a99ab80 First public commit! c43fccdda05319e57498f4f517650f9edbdb942a Second public commit :)
Because of --reverse, the oldest hash (090a3...) is at top.
5) ~/priv$ echo '090a335746ecb03ea5362909be4969b87a99ab80 d2d66cf2861ac7136ee3dc04467781825413b084' >> .git/info/grafts
At this point, git log public/master
shows revisionist history, but I'm unsure how to progress wrt. filter-branch and all that... I've only succe开发者_运维百科eded in messing things up :)
Once you have done your cleanup, you can create a new repo with only one commit (the "clean" one"), which you will push to your public repo.
Except that locally, you will have two repos:
- one mirroring that new (and small) public repo
- one with your full history, where you can graft your public repo to your private one, as in this example.
In this one, you will get back the full history.
精彩评论