Git: Skonfigurować pilota obsługującego tylko pobieranie?

136

Kiedy uruchamiam git remote -vw jednym z moich repozytoriów Git, który ma skonfigurowany pilot (y), widzę, że każdy pilot ma zarówno specyfikacje pobierania, jak i przesyłania:

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

W przypadku pilotów, które wskazują równorzędnym programistom, nie ma potrzeby wypychania, a Git i tak odmówi wysłania do nie-gołego repozytorium. Czy istnieje sposób skonfigurowania tych pilotów jako „tylko do pobierania”, bez adresu lub funkcji push?

mtbkrdave
źródło
4
@sehe, nie, nie możesz. Jeśli nie określono adresu URL wypychania, operacje wypychania będą używać adresu URL pobierania.
jojo

Odpowiedzi:

197

Nie sądzę, aby można było usunąć adres URL push, można go tylko zastąpić innym niż adres URL pobierania. Myślę więc, że najbliższe będzie coś takiego:

$ 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

Ustawiasz adres URL wypychania na no-pushing, którego git nie będzie w stanie zlokalizować, dopóki nie masz folderu o tej samej nazwie w katalogu roboczym. Zasadniczo zmuszasz git do korzystania z lokalizacji, która nie istnieje.

Daniel Brockman
źródło
14
Tak, można by pomyśleć, że „git remote set-url --delete --push. *” Załatwi sprawę, ale jeśli usuniesz adres URL wypychania, domyślnie powróci do adresu URL pobierania.
jojo
7
Osobiście wolę używać czegoś takiego jak „ NIEWOLNE ”, bardziej widoczne. Ale to tylko kwestia gustu.
Pierre-Olivier Vares
@ Pierre-OlivierVares A co z „DONTPUSH” ?! :)
Ali Shakiba,
Do Twojej wiadomości, po wykonaniu tej czynności twój plik konfiguracyjny git powinien wyglądać tak: (Zwróć uwagę na nową opcję pushurl ) [zdalne "źródło"] fetch = + refs / heads / *: refs / remotes / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-pushing / repo
jaywilliams
1
Podobnie jak @ Pierre-OlivierVares, poszedłem z git remote set-url --push origin -- --read-only--- zwróć uwagę na dodatek, --aby zezwolić na nazwę z początkowymi myślnikami. Wydało mi się to bardziej czytelne.
Lindes
15

Oprócz zmiany adresu URL push na nieprawidłowy (np. git remote set-url --push origin DISABLED), Można również użyć pre-pushhooka.

Jednym z szybkich sposobów zatrzymania git pushjest użycie linku symbolicznego, /usr/bin/falsektóry ma być hakiem:

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

Użycie haka pozwala na dokładniejszą kontrolę pchnięć, jeśli jest to pożądane. Zobacz .git/hooks/pre-push.sampleprzykład, jak zapobiegać wypychaniu zatwierdzeń pracy w toku.

Aby zapobiec wypychaniu do określonej gałęzi lub ograniczyć wypychanie do jednej gałęzi, w przykładzie haka:

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

Repozytorium testowe z wieloma pilotami:

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

Pchanie do originjest dozwolone:

$ 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

Pchanie do innego pilota jest niedozwolone:

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

Należy zauważyć, że pre-pushskrypt przechwytujący można zmodyfikować, aby, między innymi, wypisywać na stderr komunikat informujący, że wypychanie zostało wyłączone.

Rodolfo Carvalho
źródło
Dobry pomysł! Bez bardziej rozbudowanego skryptu wyłączyłbyś opcję wypychania dla wszystkich pilotów.
v01pe,
1
@ v01pe yes. Zaktualizowałem odpowiedź, aby zawierała przykładowy skrypt. Naprawdę nie potrzeba wiele, aby filtrować wypychania do jednej gałęzi. Wystarczyłby oneliner.
Rodolfo Carvalho
4

Ogólne stwierdzenie „Git odmówi wypychania do nie-nagiego repozytorium” nie jest prawdziwe. Git odmówi wypchnięcia do innego niż nagie repozytorium zdalnego, jeśli spróbujesz wypchnąć zmiany, które znajdują się w tej samej gałęzi, co wyewidencjonowany katalog roboczy repozytorium zdalnego.

Ta odpowiedź daje proste wyjaśnienie: https://stackoverflow.com/a/2933656/1866402

(Dodaję to jako odpowiedź, ponieważ nie mam jeszcze wystarczającej reputacji, aby dodawać komentarze)

pkeller
źródło
czyste repozytorium z definicji nie ma wyewidencjonowanego katalogu roboczego. Możesz jednak naciskać na konkretną gałąź na nim.,
Ed Randall
2

Jeśli masz już zdalną konfigurację i po prostu chcesz zapobiec zrobieniu czegoś takiego jak przypadkowe naciśnięcie bezpośrednio do masterlub release/production, możesz temu zapobiec 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

Dla przypomnienia, no_pushnie jest to specjalne imię. To tylko nazwa nieistniejącej gałęzi. Możesz więc użyć $ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_masteri będzie działać dobrze.

Więcej informacji: git-config pushRemote

PaulMest
źródło
0

Jeśli masz kontrolę nad repozytorium, możesz to osiągnąć, korzystając z uprawnień. Użytkownik, który pobiera repozytorium, nie powinien mieć uprawnień do zapisu w repozytorium głównym.

Abhilash
źródło
Jeśli nie możesz modyfikować plików, nie możesz również pobrać nowych zmian.
Tylko student