Here's the situation:
I have a public repository for my open-source app on github.com. However, now I'd like to write some specific code that will not be public (I might use it in a commercial version of my application).
I figured I could use the same repository, and I'd create a "private" branch in my git repository that I wouldn't push.
But, mistakes happen. Is there some way to forbid git from ever pushing a branch to remote servers?
If there's a better way to handle this situation, I would of course welcome any suggestions.
Here's how the pre-push
hook approach works, with a branch called dontpushthis
.
Create this file as .git/hooks/pre-push
:
#!/usr/bin/bash if [[ `grep 'dontpushthis'` ]]; then echo "You really don't want to push this branch. Aborting." exit 1 fi
This works because the list of refs being pushed is passed on standard input. So this will also catch git push --all
.
Make it executable.
Do this in every local repository.
When you try to push to that branch, you'll see:
$ git checkout dontpushthis $ git push You really don't want to push this branch. Aborting. error: failed to push some refs to 'https://github.com/stevage/test.git'
Obviously this is as simple as it looks, and only prevents pushing the branch named "dontpushthis". So it's useful if you're trying to avoid directly pushing to an important branch, such as master
.
If you're trying to solve the problem of preventing confidential information leaking, it might not be sufficient. For example, if you created a sub-branch from dontpushthis
, that branch would not be detected. You'd need more sophisticated detection - you could look to see whether any of the commits on the "dontpushthis" branch were present on the current branch, for instance.
Looking at the question again, I think a better solution in this case would be:
git remote rm origin
) from that working directory.git pull https://github.com/myproj/mypublicrepo
This way, the private repo working directory never has anywhere it could push to. You essentially have a one-way valve of public information to private, but not back.
A slightly hackish solution: Make a dummy branch on GitHub with the same name as your real branch, and make sure it would not be a fast forward merge. That way, the push operation will fail.
Here's an example.
$ git clone [email protected]:user/repo.git $ cd repo $ git checkout -b secret $ echo "This is just a dummy to prevent fast-forward merges" > dummy.txt $ git add . $ git commit -m "Dummy" $ git push origin secret
Now that the dummy branch is set up, we can recreate it locally to diverge from the one on GitHub.
$ git checkout master $ git branch -D secret $ git checkout -b secret $ echo "This diverges from the GitHub branch" > new-stuff.txt $ git add . $ git commit -m "New stuff"
Now if we accidentally try to push, it will fail with a non-fast forward merge error:
$ git push origin secret To [email protected]:user/repo.git ! [rejected] secret -> secret (non-fast forward) error: failed to push some refs to ‘[email protected]:user/repo.git’
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With