Git: Configurer une télécommande à extraction uniquement?

132

Lorsque j'exécute git remote -vdans l'un de mes référentiels Git qui a une ou plusieurs télécommandes configurées, je vois que chaque télécommande a à la fois des spécifications d'extraction et de transmission:

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

Pour les télécommandes qui pointent vers des développeurs pairs, il n'est pas nécessaire de pousser, et Git refusera de toute façon de pousser vers un référentiel non nu. Existe-t-il un moyen de configurer ces télécommandes en tant que "récupération uniquement" sans adresse ou capacités push?

mtbkrdave
la source
4
@sehe, non, vous ne pouvez pas. En l'absence d'URL push, les envois utiliseront l'URL de récupération.
yoyo

Réponses:

191

Je ne pense pas que vous puissiez supprimer l'URL push, vous ne pouvez la remplacer que pour qu'elle soit autre que l'URL d'extraction. Donc, je pense que le plus proche que vous obtiendrez est quelque chose comme ceci:

$ 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

Vous définissez l'URL push sur no-pushing, qui, tant que vous n'avez pas de dossier du même nom dans votre répertoire de travail, git ne pourra pas localiser. Vous forcez essentiellement git à utiliser un emplacement qui n'existe pas.

Daniel Brockman
la source
14
Oui, vous pourriez penser que "git remote set-url --delete --push. *" Ferait l'affaire, mais si vous supprimez l'url push, elle revient par défaut à l'URL de récupération.
yoyo
6
Personnellement , je préfère utiliser quelque chose comme « DISALLOWED », plus visible. Mais ce n'est qu'une question de goût.
Pierre-Olivier Vares
@ Pierre-OlivierVares Et «DONTPUSH» ?! :)
Ali Shakiba
Pour info, après cela, votre fichier de configuration git devrait ressembler à ceci: (Notez la nouvelle option pushurl ) [remote "origin"] fetch = + refs / heads / *: refs / remotes / origin / * url = ssh: // host / chemin / vers / repo pushurl = ssh: // hôte / no-pushing / repo
jaywilliams
1
Comme pour @ Pierre-OlivierVares, je suis allé avec git remote set-url --push origin -- --read-only--- notez le supplément --pour permettre un nom avec des tirets au début. Cela me semblait plus lisible.
lindes
13

En plus de changer l'URL push en quelque chose d'invalide (par exemple git remote set-url --push origin DISABLED), on peut également utiliser le pre-pushhook.

Un moyen rapide d'arrêter git pushest de créer un lien symbolique /usr/bin/falsepour être le crochet:

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

L'utilisation d'un crochet permet un contrôle plus fin des poussées si cela est souhaitable. Voir .git/hooks/pre-push.samplepour un exemple de la façon d'empêcher l'envoi de commits de travail en cours.

Pour éviter de pousser vers une branche spécifique ou pour limiter la poussée vers une seule branche, ceci dans un exemple de hook:

$ 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 dépôt de test avec plusieurs télécommandes:

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

Pousser vers originest autorisé:

$ 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

Pousser vers une autre télécommande n'est pas autorisé:

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

Notez que le pre-pushscript de hook peut être modifié pour, entre autres, afficher un message à stderr indiquant que le push a été désactivé.

Rodolfo Carvalho
la source
Bonne idée! Sans un script plus élaboré, vous désactiveriez le push pour toutes les télécommandes.
v01pe du
1
@ v01pe oui. J'ai mis à jour la réponse pour inclure un exemple de script. Il n'est pas vraiment nécessaire de filtrer les poussées vers une seule branche. Un shell oneliner ferait l'affaire.
Rodolfo Carvalho
4

La déclaration générale "Git refusera de pousser vers un dépôt non nu" n'est pas vraie. Git refusera de pousser vers un référentiel distant non nu uniquement si vous essayez de transmettre des modifications qui se trouvent sur la même branche que le répertoire de travail extrait du référentiel distant.

Cette réponse donne une explication simple: https://stackoverflow.com/a/2933656/1866402

(J'ajoute ceci comme réponse car je n'ai pas encore assez de réputation pour ajouter des commentaires)

pkeller
la source
un référentiel nu n'a pas de répertoire de travail extrait, par définition. Vous pouvez cependant pousser vers une branche particulière.,
Ed Randall
1

Si vous avez déjà une télécommande et que vous voulez simplement vous empêcher de faire quelque chose comme pousser accidentellement directement vers masterou release/production, vous pouvez empêcher cette utilisation 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

Pour mémoire, ce no_pushn'est pas un nom spécial. C'est juste le nom d'une branche inexistante. Vous pouvez donc l'utiliser $ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_masteret cela fonctionnerait très bien.

Plus d'informations: git-config pushRemote

PaulMest
la source
0

Si vous avez le contrôle sur le référentiel, vous pouvez y parvenir en utilisant les autorisations. L'utilisateur qui récupère le référentiel ne doit pas disposer d'autorisations d'écriture sur le référentiel maître.

Abhilash
la source
Si vous ne pouvez pas modifier les fichiers, vous ne pouvez pas non plus récupérer de nouvelles modifications.
Juste un étudiant