Git private and public repos for the same project
Question from a Git newbie: I have a project in a Git repository, parts of which I would like to make available as OSS. For practical reasons, the repositories of the private and the public parts of the project will have to be different, while all development wi开发者_高级运维ll happen in the private repository. At certain points in time, I would like to update the OSS version with selected commits from the private version.
Right now, I have a remote branch of the private repo setup in a local mirror of the public repo and I am using git cherry-pick
to copy the interesting commits from the remote branch of the private repo to master branch of the public repo, which I then push. However, since the private development is moving very fast, cherry picking can be very time consuming.
Are there any suggestions on how to make the workflow a bit better?
BTW, I did read SO questions #999064 and #1807036
One possible option is to use git rebase -i
to give you a text file of all the commits in a certain range in your private. Say you private
and public
heads and have 10 new commits in private
branch:
git checkout private
git pull
git checkout -b work
git rebase -i --onto public private^10
# an editor pops up listing the commits. Just delete the private ones.
git checkout public
git merge work
git branch -d work
git push
If you maintain a lastsync branch like this in addition to the above, you can replace private^10 with lastsync and not have to track rev counts:
git checkout lastsync
git merge private
While what I am about to suggest is probably similar to the answer from #999064, I will give it a go.
Basically what you want is to use two branches. master
is your main branch which all your public work goes into. work
is your private branch. So what you do is whenever you want a change to be available to public as well, you make that commit on master
. If the commit is private, you make it on the work
branch.
The trick is to merge master
back into work
continuously. This way work
will have all the changes of master
, but master
will only contain those commits that were made on master
specifically.
So what you get is:
-- work --------- c -- e ------- h
/ /
-- master -- a -- b -- d -- f -- g
master
contains the commits a, b, d, f, g. work
contains the merge commits c (contains a, b), h (contains d, f, g), and the regular commit e.
e is only on the work
branch, while all other commits (except merge commits) are on both branches.
An example for how to produce the above graph:
# on branch master
# changes for a
git add .
git commit -m 'commit a'
# changes for b
git add .
git commit -m 'commit b'
# switch to work
# merge a and b (from master) into work, producing merge commit c
git checkout work
git merge master
# switch to master
# make commits d, f and g
git checkout master
...
# switch to work
# make commit e
# merge d, f and g (from master) into work, producing merge commit h
git checkout work
git merge master
So you have two remotes, public
and private
. You push work
and master
to private
, but you only push master
to public
.
I hope that helps.
I can think of one way. You can make the public repositories submodules of the main project and then develop them separately but at the same time use them from the main project.
However, I think you should really make separate repositories for the main and public components and make the latter dependencies for the former that are separately installed.
精彩评论