Git:设置一个只获取远程服务器?

Git:设置一个只获取远程服务器?,git,workflow,Git,Workflow,当我在一个配置了远程设备的git存储库中运行git remote-v时,我发现每个远程设备都有fetch和push规范: $ git remote -v <remote-name> ssh://host/path/to/repo (fetch) <remote-name> ssh://host/path/to/repo (push) $git remote-v ssh://host/path/to/repo (取回) ssh://host/path/to/repo (推

当我在一个配置了远程设备的git存储库中运行
git remote-v
时,我发现每个远程设备都有fetch和push规范:

$ git remote -v
<remote-name> ssh://host/path/to/repo (fetch)
<remote-name> ssh://host/path/to/repo (push)
$git remote-v
ssh://host/path/to/repo (取回)
ssh://host/path/to/repo (推)
对于指向对等开发人员的远程设备,不需要推送,Git无论如何都会拒绝推送到非裸存储库。有没有办法将这些远程设备配置为“仅获取”,没有推送地址或功能?

我认为您不能删除推送URL,您只能将其覆盖为拉送URL以外的内容。所以我认为你能得到的最接近的东西是这样的:

$ git remote set-url --push origin no-pushing
$ git push
fatal: 'no-pushing' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
您正在将推送URL设置为“不推送”,只要您的工作目录中没有同名文件夹,git将无法找到该文件夹。您实际上是在强迫git使用不存在的位置。

一般性语句“git将拒绝推送到非裸存储库”是不正确的。如果您试图推送与远程存储库的签出工作目录位于同一分支上的更改,Git只会拒绝推送到非裸远程存储库

这个答案给出了一个简单的解释:


(我之所以添加此作为答案,是因为我还没有足够的声誉来添加评论)

如果您可以控制存储库,则可以通过使用权限来实现这一点。获取存储库的用户不应具有主存储库的写入权限。

除了将推送URL更改为无效的内容(例如,
git远程设置URL——推送源已禁用
),还可以使用
预推
钩子

停止git push的一种快速方法是将/usr/bin/false符号链接为钩子:

$ ln -s /usr/bin/false .git/hooks/pre-push
$ git push
error: failed to push some refs to '...'
如果需要,使用钩子可以更细粒度地控制推送。请参见
.git/hooks/pre-push.sample
,了解如何防止推送正在进行的工作提交的示例

为了防止推送到特定分支或限制推送到单个分支,在示例钩子中:

$cat.git/hooks/pre-push
#!/usr/bin/sh
#一个示例钩子脚本,用于限制推送到单个远程服务器。
#
#使用以下参数调用此挂钩:
#
#$1--正在向其进行推送的远程设备的名称
#$2—正在进行推送的URL
#
#如果此脚本以非零状态退出,则不会推送任何内容。
remote=“$1”
url=“$2”
[[“$remote”==“origin”]]
具有多个遥控器的测试回购:

$ git remote -v
origin  ../gitorigin (fetch)
origin  ../gitorigin (push)
upstream        ../gitupstream (fetch)
upstream        ../gitupstream (push)
允许推送到
原点

$ git push origin
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 222 bytes | 222.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../gitorigin
 * [new branch]      master -> master
不允许推送到任何其他远程设备:

$ git push upstream
error: failed to push some refs to '../gitupstream'

请注意,
pre-push
钩子脚本可以修改为向stderr打印一条消息,说明推送已被禁用。

如果您已经进行了远程设置,只是想防止自己做一些事情,例如意外地直接推送到
主控
发布/生产
,则,您可以使用git config防止这种情况

#防止推送到分支:主
$git config branch.master.pushRemote无需推送
#防止推至分支机构:发布/生产
$git config branch.release/production.pushRemote无需推送
对于记录,
no_push
不是一个特殊的名称。它只是任何不存在的分支的名称。因此,您可以使用
$git config branch.master.pushRemote创建\u a\u pr\u和\u不\u直接将\u推送到\u master
,这样就可以正常工作了


更多信息:

是的,您可能会认为“git remote set url--delete--push.*”会起作用,但如果您删除推送url,那么它会默认返回到获取url。我个人更喜欢使用“不允许”之类的更明显的方式。但这只是品味的问题。@Pierre OlivierVares“DONTPUSH”怎么样?!:)仅供参考,完成此操作后,git配置文件应如下所示:(注意新的pushurl选项)[remote“origin”]fetch=+refs/heads/*:refs/remotes/origin/*url=ssh://host/path/to/repo pushurl=ssh://host/no-pushing/repoSimilarly 致@Pierre OlivierVares,我使用了
git remote set url--push origin----只读--
--注意额外的
--
允许名称带有前导破折号。我觉得这更容易理解。@sehe,不,你不能。如果未指定推送URL,推送将使用获取URL。根据定义,裸存储库没有签出的工作目录。但是,您可以将其推送到特定的分支。如果您无法修改文件,您也无法获取新的更改。好主意!如果没有更复杂的脚本,您将禁用所有远程推送。@v01pe-yes。我已经更新了答案,添加了一个示例脚本。将推送过滤到单个分支并不需要太多。一个贝壳单层衬里就行了。