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?


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.


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.


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)


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


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.


Jeśli nie możesz modyfikować plików, nie możesz również pobrać nowych zmian.
Tylko student
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.