开发者

Git: Set up a fetch-only remote?

When I run git remote -v in one of my Git repositories that has a remote(s) configured, I see that each remote has 开发者_JAVA技巧both fetch and push specs:

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

For remotes that point to peer developers there's no need to push, and Git will refuse to push to a non-bare repository anyway. Is there any way to configure these remotes as "fetch-only" with no push address or capabilities?


I don't think you can remove the push URL, you can only override it to be something other than the pull URL. So I think the closest you'll get is something like this:

$ 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

You are setting the push URL to no-pushing, which, as long as you don't have a folder of the same name in your working directory, git will not be able to locate. You are essentially forcing git to use a location that does not exist.


Apart from changing the push URL to something invalid (e.g., git remote set-url --push origin DISABLED), one can also use the pre-push hook.

One quick way to stop git push is to symlink /usr/bin/false to be the hook:

$ ln -s /usr/bin/false .git/hooks/pre-push
$ git push
error: failed to push some refs to '...'

Using a hook allows for more fine-grained control of pushes if desirable. See .git/hooks/pre-push.sample for an example of how to prevent pushing work-in-progress commits.

To prevent pushing to a specific branch or to limit pushing to a single branch, this in an example hook:

$ 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" ]]

A test repo with multiple remotes:

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

Pushing to origin is allowed:

$ 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

Pushing to any other remote is not allowed:

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

Note that the pre-push hook script can be modified to, among other things, print a message to stderr saying the push has been disabled.


The general statement "Git will refuse to push to a non-bare repository" is not true. Git will only refuse to push to a non-bare remote repository if you are attempting to push changes that are on the same branch as the remote repository's checked-out working directory.

This answer gives a simple explanation: https://stackoverflow.com/a/2933656/1866402

(I am adding this as an answer because I don't have enough reputation to add comments yet)


If you already have a remote set up and just want to prevent yourself from doing something like accidentally pushing directly to master or release/production, you can prevent this using 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

For the record, no_push is not a special name. It's just the name of any nonexistent branch. So you could use $ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_master and it would work just fine.

More info: git-config pushRemote


If you have control over the repository, you can achieve this by making use of permissions. The user who is fetching repository shouldn't have write permissions on master repository.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜