Git: impostare un telecomando solo fetch?


132

Quando corro git remote -vin uno dei miei repository Git con un / i remoto / i configurato / i, vedo che ogni telecomando ha sia specifiche di recupero che push:

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

Per i telecomandi che puntano agli sviluppatori peer non c'è bisogno di spingere e Git rifiuterà comunque di spingere in un repository non nudo. Esiste un modo per configurare questi telecomandi come "solo recupero" senza indirizzo push o funzionalità?


4
@sehe, no, non puoi. Senza l'URL push specificato, i push utilizzeranno l'URL di recupero.
yoyo

Risposte:


191

Non penso che puoi rimuovere l'URL push, puoi solo sostituirlo per essere qualcosa di diverso dall'URL pull. Quindi penso che il più vicino che otterrai sia qualcosa del genere:

$ 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

Stai impostando l'URL push su no-pushing, che, fintanto che non hai una cartella con lo stesso nome nella tua directory di lavoro, git non sarà in grado di localizzare. Stai essenzialmente forzando git a usare una posizione che non esiste.


14
Sì, penseresti che "git remote set-url --delete --push. *" Farebbe il trucco, ma se elimini l'URL push allora torna all'impostazione predefinita all'URL di recupero.
yoyo

6
Personalmente preferisco usare qualcosa come " DISALLOWED ", più visibile. Ma è solo una questione di gusti.
Pierre-Olivier Vares,

@ Pierre-OlivierVares Che ne dici di "DONTPUSH" ?! :)
Ali Shakiba,

Cordiali saluti, dopo aver fatto questo il tuo file di configurazione git dovrebbe apparire così: (Nota la nuova opzione pushurl ) [remote "origin"] fetch = + refs / heads / *: refs / remotes / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-push / repo
jaywilliams

1
Analogamente a @ Pierre-OlivierVares, sono andato con git remote set-url --push origin -- --read-only--- nota l'aggiunta --per consentire un nome con trattini iniziali. Mi è sembrato più leggibile.
scade il

13

Oltre a modificare l'URL push in qualcosa di non valido (ad esempio, git remote set-url --push origin DISABLED), si può anche usare l' pre-pushhook.

Un modo rapido per interrompere git pushè /usr/bin/falseil collegamento simbolico per essere il gancio:

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

L'uso di un gancio consente un controllo più preciso delle spinte, se desiderato. Vedi .git/hooks/pre-push.sampleun esempio di come impedire il commit dei work-in-progress.

Per impedire la spinta a un ramo specifico o limitare la spinta a un ramo singolo, questo in un gancio di esempio:

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

Un repository di prova con più telecomandi:

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

Spingere verso originè permesso:

$ 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

Non è consentito premere su nessun altro telecomando:

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

Si noti che lo pre-pushscript hook può essere modificato, tra le altre cose, per stampare un messaggio su stderr dicendo che il push è stato disabilitato.


Buona idea! Senza uno script più elaborato disattiveresti push per tutti i telecomandi.
v01pe,

1
@ v01pe sì. Ho aggiornato la risposta per includere uno script di esempio. Non ha davvero bisogno di molto per filtrare le spinte verso un singolo ramo. Un oneliner di conchiglie farebbe.
Rodolfo Carvalho,

4

L'affermazione generale "Git rifiuterà di spingere in un repository non nudo" non è vera. Git rifiuterà di eseguire il push in un repository remoto non bare solo se si sta tentando di eseguire il push delle modifiche che si trovano sullo stesso ramo della directory di lavoro di checkout del repository remoto.

Questa risposta fornisce una semplice spiegazione: https://stackoverflow.com/a/2933656/1866402

(Sto aggiungendo questo come risposta perché non ho abbastanza reputazione per aggiungere ancora commenti)


un repository nudo non ha una directory di lavoro estratta, per definizione. Puoi spingerlo verso un ramo particolare su di esso.
Ed Randall

1

Se hai già una configurazione remota e vuoi solo impedirti di fare qualcosa come spingere accidentalmente direttamente verso mastero release/production, puoi impedirlo usando 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

Per la cronaca, no_pushnon è un nome speciale. È solo il nome di qualsiasi ramo inesistente. Quindi potresti usare$ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_master e funzionerebbe bene.

Ulteriori informazioni: git-config pushRemote


0

Se si ha il controllo sul repository, è possibile ottenere ciò facendo uso delle autorizzazioni. L'utente che sta recuperando il repository non dovrebbe disporre delle autorizzazioni di scrittura sul repository principale.


Se non è possibile modificare i file, non è nemmeno possibile recuperare nuove modifiche.
Solo uno studente il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.