Git:フェッチ専用のリモートをセットアップしますか?


132

git remote -vリモートが構成されているGitリポジトリの1つで実行すると、各リモートにフェッチ仕様とプッシュ仕様の両方があることがわかります。

$ 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年

回答:


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 2016

1
@ Pierre-OlivierVaresと同様に、私は一緒に行きましたgit remote set-url --push origin -- --read-only--- --先頭にダッシュを付けた名前を許可するための追加に注意してください。これは私には読みやすく感じました。
lindes 16

13

プッシュURLを無効なもの(たとえばgit remote set-url --push origin DISABLED)に変更する以外に、pre-pushフックを使用することもできます。

停止する簡単な方法の1つ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はい。答えを更新して、サンプルスクリプトを含めました。単一のブランチへのプッシュをフィルタリングするためにそれほど多くは必要ありません。シェルのワンライナーでできます。
Rodolfo Carvalho

4

「Gitはベアリポジトリ以外へのプッシュを拒否します」という一般的なステートメントは正しくありません。Gitは、リモートリポジトリのチェックアウトされた作業ディレクトリと同じブランチにある変更をプッシュしようとしている場合にのみ、非ベアリモートリポジトリへのプッシュを拒否します。

この回答は簡単な説明です:https : //stackoverflow.com/a/2933656/1866402

(まだコメントを追加するのに十分な評判がないため、これを回答として追加します)


ベアリポジトリには、定義上、チェックアウトされた作業ディレクトリはありません。あなたはかかわらず、それに特定のブランチにプッシュすることができ、。
エド・ランドール

1

すでにリモート設定があり、誤って直接masterrelease/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

リポジトリを制御できる場合は、権限を利用することでこれを実現できます。リポジトリをフェッチしているユーザーには、マスターリポジトリへの書き込み権限がありません。


ファイルを変更できない場合、新しい変更をフェッチすることもできません。
学生のみ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.