Git:设置仅获取的遥控器?


132

当我git remote -v在配置了遥控器的Git存储库之一中运行时,我看到每个遥控器都具有提取和推送规范:

$ git remote -v
<remote-name> ssh://host/path/to/repo (fetch)
<remote-name> ssh://host/path/to/repo (push)

对于指向对等开发人员的远程服务器,无需推送,而Git仍将拒绝推送至非裸仓库。有什么方法可以将这些遥控器配置为“仅获取”而没有推送地址或功能?


4
@sehe,不,你不能。没有指定推送URL,推送将使用获取URL。
2014年

Answers:


191

我认为您无法删除推送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设置为no-pushing,只要您的工作目录中没有同名文件夹,git就无法找到。本质上,您是在强制git使用不存在的位置。


14
是的,您会认为“ git remote set-url --delete --push。*”可以解决问题,但是如果删除了推入URL,则默认返回到获取URL。
2014年

6
我个人更喜欢使用“ DISALLOWED ”之类的更明显的东西。但这只是一个品味问题。
Pierre-Olivier Vares 2014年

@ Pierre- OlivierVares'DONTPUSH'呢?:)
Ali Shakiba 2015年

仅供参考,执行此操作后,您的git配置文件应如下所示:(请注意新的pushurl选项)[remote“ origin”] fetch = + refs / heads / *:refs / remotes / origin / * url = ssh:// host / path / to / repo pushurl = ssh:// host / no-pushing / repo
jaywilliams

1
与@ Pierre-OlivierVares相似,我也使用了git remote set-url --push origin -- --read-only---请注意额外的内容,--以允许使用带引号的破折号。这对我来说更具可读性。
林德斯

13

除了将推送网址更改为无效的内容(例如git remote set-url --push origin DISABLED)外,还可以使用该pre-push钩子。

一种快速的停止方法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

# An example hook script to limit pushing to a single remote.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If this script exits with a non-zero status nothing will be pushed.

remote="$1"
url="$2"

[[ "$remote" == "origin" ]]

具有多个遥控器的测试仓库:

$ git remote -v
origin  ../gitorigin (fetch)
origin  ../gitorigin (push)
upstream        ../gitupstream (fetch)
upstream        ../gitupstream (push)

origin允许推送到:

$ 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打印一条消息,指出该推送已被禁用。


好主意!没有更详尽的脚本,您将禁用所有遥控器的推送。
v01pe

1
@ v01pe是的。我已经更新了答案,以包括示例脚本。过滤到单个分支的推送实际上并不需要太多。一个shell oneliner会做。
Rodolfo Carvalho

4

通用声明“ Git将拒绝推送到非裸仓库”是不正确的。仅当您尝试将与远程存储库的检出工作目录位于同一分支上的更改推送到Git时,Git才会拒绝将其推送到非裸露的远程存储库。

这个答案给出了一个简单的解释:https : //stackoverflow.com/a/2933656/1866402

(我将其添加为答案,因为我没有足够的声誉来添加评论)


根据定义,裸仓库没有检出的工作目录。你可以推到一个特定的分支上它虽然。
埃德·兰德尔

1

如果您已经设置了远程设置,并且只是想防止自己意外执行诸如直接将其推向master或的操作release/production,则可以防止使用git config

# prevent pushing to branch: master
$ git config branch.master.pushRemote no_push

# prevent pushing to branch: release/production
$ git config branch.release/production.pushRemote no_push

出于记录,no_push不是特殊名称。它只是任何不存在的分支的名称。因此您可以使用$ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_master它,并且效果很好。

更多信息:git-config pushRemote


0

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


如果无法修改文件,则也无法获取新更改。
只是一名学生,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.