Git: Mengatur remote fetch-only?

132

Ketika saya menjalankan git remote -vdi salah satu repositori Git saya yang memiliki kendali jarak jauh, saya melihat bahwa setiap kendali jarak jauh mengambil dan mendorong spesifikasi:

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

Untuk remote yang menunjuk ke peer developer, Anda tidak perlu mendorong, dan Git akan menolak untuk mendorong ke repositori yang tidak kosong. Apakah ada cara untuk mengkonfigurasi remote ini sebagai "hanya-ambil" tanpa alamat atau kemampuan push?

mtbkrdave
sumber
4
Ya ampun, kamu tidak bisa. Tanpa URL push yang ditentukan, push akan menggunakan URL ambil.
yoyo

Jawaban:

191

Saya tidak berpikir Anda dapat menghapus URL push, Anda hanya bisa menimpanya menjadi sesuatu selain dari URL tarikan. Jadi saya pikir yang paling dekat Anda akan dapatkan adalah sesuatu seperti ini:

$ 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

Anda mengatur URL push to no-pushing, yang, selama Anda tidak memiliki folder dengan nama yang sama di direktori kerja Anda, git tidak akan dapat menemukan. Anda pada dasarnya memaksa git untuk menggunakan lokasi yang tidak ada.

Daniel Brockman
sumber
14
Yup, Anda akan berpikir "git remote set-url --delete --push. *" Akan melakukan trik, tetapi jika Anda menghapus url dorong maka defaultnya kembali ke url ambil.
yoyo
6
Saya pribadi lebih suka menggunakan sesuatu seperti ' DILARANG ', lebih terlihat. Tapi itu hanya masalah selera.
Pierre-Olivier Vares
@ Pierre-OlivierVares Bagaimana dengan 'DONTPUSH' ?! :)
Ali Shakiba
FYI, setelah melakukan ini, file konfigurasi git Anda akan terlihat seperti ini: (Perhatikan opsi pushurl baru ) [remote "origin"] fetch = + refs / heads / *: refs / remote / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-pushing / repo
jaywilliams
1
Demikian pula dengan @ Pierre-OlivierVares, saya pergi dengan git remote set-url --push origin -- --read-only--- perhatikan tambahan --untuk memungkinkan nama dengan tanda hubung utama. Ini terasa lebih mudah dibaca oleh saya.
lindes
13

Selain mengubah URL push menjadi sesuatu yang tidak valid (misalnya, git remote set-url --push origin DISABLED), Anda juga dapat menggunakan pre-pushhook.

Salah satu cara cepat untuk berhenti git pushadalah dengan symlink /usr/bin/falsemenjadi hook:

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

Menggunakan kait memungkinkan untuk kontrol yang lebih halus dari dorongan jika diinginkan. Lihat .git/hooks/pre-push.samplecontoh bagaimana mencegah mendorong komitmen dalam pekerjaan.

Untuk mencegah mendorong ke cabang tertentu atau membatasi mendorong ke cabang tunggal, ini dalam contoh kait:

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

Repo uji dengan beberapa remote:

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

Mendorong ke origindiizinkan:

$ 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

Mendorong ke remote lain tidak diizinkan:

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

Perhatikan bahwa pre-pushskrip kait dapat dimodifikasi untuk, antara lain, mencetak pesan ke stderr dengan mengatakan push telah dinonaktifkan.

Rodolfo Carvalho
sumber
Ide bagus! Tanpa skrip yang lebih rumit, Anda akan menonaktifkan push untuk semua remote.
v01pe
1
@ v01pe ya. Saya telah memperbarui jawaban untuk menyertakan contoh skrip. Tidak perlu banyak untuk memfilter push ke satu cabang. Oneliner shell akan dilakukan.
Rodolfo Carvalho
4

Pernyataan umum "Git akan menolak untuk mendorong ke repositori non-telanjang" tidak benar. Git hanya akan menolak untuk mendorong ke repositori jarak jauh yang tidak kosong jika Anda mencoba untuk mendorong perubahan yang ada di cabang yang sama dengan direktori kerja yang dicentang dari repositori jauh.

Jawaban ini memberikan penjelasan sederhana: https://stackoverflow.com/a/2933656/1866402

(Saya menambahkan ini sebagai jawaban karena saya belum memiliki reputasi yang cukup untuk menambahkan komentar)

pkeller
sumber
repositori yang kosong tidak memiliki direktori kerja yang diperiksa, menurut definisi. Anda dapat mendorong ke cabang tertentu di atasnya.,
Ed Randall
1

Jika Anda sudah memiliki pengaturan jarak jauh dan hanya ingin mencegah diri Anda melakukan sesuatu seperti mendorong langsung ke masteratau release/production, Anda dapat mencegahnya menggunakan ini 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

Untuk catatan, no_push bukan nama khusus. Itu hanya nama cabang yang tidak ada. Jadi Anda bisa menggunakan $ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_masterdan itu akan berfungsi dengan baik.

Info lebih lanjut: git-config pushRemote

PaulMest
sumber
0

Jika Anda memiliki kendali atas repositori, Anda dapat mencapainya dengan memanfaatkan izin. Pengguna yang mengambil repositori tidak boleh memiliki izin menulis di repositori master.

Abhilash
sumber
Jika Anda tidak dapat memodifikasi file, Anda juga tidak dapat mengambil perubahan baru.
Hanya seorang siswa