阻止 git 分支被推送
情况是这样的:
我在 github.com 上有一个开源应用程序的公共存储库。但是,现在我想编写一些不公开的特定代码(我可能会在我的应用程序的商业版本中使用它)。
我想我可以使用相同的存储库,并且我会在我的 git 存储库中创建一个我不会推送的“私有”分支。
但是,错误是会发生的。有没有办法禁止 git 将分支推送到远程服务器?
如果有更好的方法来处理这种情况,我当然欢迎任何建议。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
以下是
pre-push
挂钩方法的工作原理,其中有一个名为dontpushthis
的分支。创建此文件作为
.git/hooks/pre-push
:这是有效的,因为正在推送的引用列表是通过标准输入传递的。所以这也会捕获 git push --all 。
使其可执行。
在每个本地存储库中执行此操作。
当您尝试推送到该分支时,您会看到:
显然,这就像看起来一样简单,并且只会阻止推送名为“dontpushthis”的分支。因此,如果您试图避免直接推送到重要分支(例如
master
),那么它会很有用。如果您试图解决防止机密信息泄露的问题,这可能还不够。例如,如果您从
dontpushthis
创建了一个子分支,则不会检测到该分支。您需要更复杂的检测 - 例如,您可以查看当前分支上是否存在“dontpushthis”分支上的任何提交。更安全的解决方案
再次查看这个问题,我认为在这种情况下更好的解决方案是:
git remote rm origin
) 从该工作目录。这样,私有存储库工作目录就永远没有可以推送到的任何地方。从本质上讲,你有一个将公共信息转为私人信息的单向阀,但不能返回。
Here's how the
pre-push
hook approach works, with a branch calleddontpushthis
.Create this file as
.git/hooks/pre-push
: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:
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.A safer solution
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.
一个稍微有点黑客的解决方案:在 GitHub 上创建一个与真实分支同名的虚拟分支,并确保它不会是快进合并。这样,推送操作就会失败。
这是一个例子。
现在虚拟分支已经设置完毕,我们可以在本地重新创建它,以区别于 GitHub 上的分支。
现在,如果我们不小心尝试推送,它将失败并出现非快进合并错误:
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.
Now that the dummy branch is set up, we can recreate it locally to diverge from the one on GitHub.
Now if we accidentally try to push, it will fail with a non-fast forward merge error:
来自 @steve-bennett 的 .git/hooks/pre-push 脚本的修改
A touch up of the .git/hooks/pre-push script from @steve-bennett
为什么不简单地使用当前 git 版本提供的预推送示例呢?
这个想法是用单词
PRIVATE: 开始私有分支的第一次提交的提交消息。
设置预推送脚本后,每次推送都会检查所有推送引用日志的提交消息。如果它们以 PRIVATE: 开头,则推送将被阻止。
步骤如下:
.git/hooks/pre-push
中创建一个文件,在其中添加以下脚本
<前><代码>#!/bin/sh
远程=“$1”
网址=“$2”
z40=0000000000000000000000000000000000000000
IFS=''
当读取 local_ref local_sha 远程_ref 远程_sha
做
如果[“$local_sha”=$z40]
然后
# 处理删除
:
别的
如果[“$remote_sha”=$z40]
然后
# 新分支,检查所有提交
范围=“$local_sha”
别的
# 更新现有分支,检查新提交
范围=“$remote_sha..$local_sha”
菲
# 检查 WIP 提交
commit=`git rev-list -n 1 --grep '^PRIVATE:' "$range"`
if [ -n "$commit" ]
然后
echo“错误:在 $local_ref 中找到私人提交。”
echo "提交在 $range 范围内。"
echo“不要推!”
1号出口
菲
菲
完毕
出口0
远程=“$1”
网址=“$2”
失败示例
要使分支再次可推送,您可以删除挂钩,或者更好的是修改提交消息以删除禁止的单词。
可以通过检查
remote_ref
将此脚本修改为仅考虑一个禁止的遥控器。但在这种情况下,不要忘记在允许接收此分支的所有存储库中复制此挂钩。Why not simply use the example of pre-push provided with current git version?
The idea is to begin the commit message of the first commit of your private branch with the word
PRIVATE:
.After setting the pre-push script, for every push it checks the commit messages of all the log of pushed refs. If they start with PRIVATE:, the push will be blocked.
Here are the steps:
.git/hooks/pre-push
Past the following script in it
Example of failure
To make the branch pushable again, you can either remove the hook or, better, modify the commit message to remove the forbidden word.
This script can be modified to only consider one forbidden remote by checking
remote_ref
. But in that case, do not forget to copy this hook in all the repos allowed to receive this branch.如果您使用 GitHub,则可以在 GitHub 上创建一个与您的分支同名的分支。不需要向它推送任何提交,只需在 master 或其他任何地方创建一个空分支(您可以在 GitHub 界面中通过在“branch”弹出窗口中输入分支并单击
createbranch
)。然后,转到存储库的分支设置(例如,
https://github.com///settings/branches/
)并为您的分支启用分支保护。请务必选中所有复选框,特别是需要评论或状态复选框,这不允许直接推送分支(必须从拉取请求推送),并且还要确保选中包含的复选框管理员。那么GitHub将不允许你推送到分支,即使你使用
-f
。您会收到类似这样的消息If you use GitHub, you can create a branch on GitHub with the same name as your branch. There is no need to push any commits to it, just make an empty branch off master or whatever (you can do it in the GitHub interface by typing the branch in the "branch" popdown and clicking
create branch <branch-name>
).Then, go to the branch settings for the repository (e.g.,
https://github.com/<user>/<repo>/settings/branches/<branch-name>
) and enable branch protection for your branch. Be sure to check all the boxes, particularly, the require reviews or status checks boxes, which disallows the branch from being pushed to directly (it would have to be pushed from a pull request), and also be sure to check the box to include administrators.Then GitHub will not allow you to push to the branch, even if you use
-f
. You'll get a message like有多种解决方案:
git-push
防止使用 git Push 进行推送There are multiple solutions:
git-push
to prevent the push with git push您可以创建远程存储库中不存在的分支。
这样,如果您这样做:
它将仅推送远程存储库上存在的分支。
创建分支后还要查看 .git/config(在本地存储库目录中)文件 - 您将看到每个本地分支都可以分配不同的远程存储库。您可以通过将此分支分配给单独的(私有)存储库来利用这一点,但这不是通用解决方案(如果明确订购,或通过命令 git push origin<,分支仍然可以推送到原始远程) /代码>)。
You can create a branch that does not exist in your remote repository.
That way if you just do:
it will push only branches that exist on the remote repository.
Also look into
.git/config
(within the local repository directory) file after creating the branch - you will see that every local branch can have different remote repository assigned. You can take advantage of that by assigning this branch to separate (private) repository, but the is not the universal solution (the branch still can be pushed to origin remote, if explicitly ordered to, or by commandgit push origin
).