Git: ¿Configurar un control remoto solo para buscar?

132

Cuando ejecuto git remote -ven uno de mis repositorios de Git que tiene un control remoto (s) configurado, veo que cada control remoto tiene especificaciones de recuperación y envío:

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

Para los controles remotos que apuntan a desarrolladores pares, no hay necesidad de presionar, y Git se negará a presionar a un repositorio no desnudo de todos modos. ¿Hay alguna forma de configurar estos controles remotos como "solo de búsqueda" sin dirección de inserción o capacidades?

mtbkrdave
fuente
44
@sehe, no, no puedes. Sin una URL de inserción especificada, las notificaciones utilizarán la URL de búsqueda.
yoyo

Respuestas:

191

No creo que pueda eliminar la URL de inserción, solo puede anularla para que sea otra que la URL de extracción. Así que creo que lo más cercano que obtendrás es algo como esto:

$ 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

Está configurando la URL de inserción en no-pushing, que, mientras no tenga una carpeta con el mismo nombre en su directorio de trabajo, git no podrá ubicarla. Básicamente, estás obligando a git a usar una ubicación que no existe.

Daniel Brockman
fuente
14
Sí, usted pensaría que "git remote set-url --delete --push. *" Haría el truco, pero si elimina la url de inserción, la configuración predeterminada volverá a la url de búsqueda.
yoyo
66
Personalmente, prefiero el uso de algo como " DESACTIVADO ", más visible. Pero eso es solo cuestión de gustos.
Pierre-Olivier Vares
@ Pierre-OlivierVares ¿Qué pasa con 'DONTPUSH' ? :)
Ali Shakiba
Para su información, después de hacer esto, su archivo de configuración de git debería verse así: (Tenga en cuenta la nueva opción pushurl ) [remote "origin"] fetch = + refs / heads / *: refs / remotes / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-push / repo
jaywilliams
1
De manera similar a @ Pierre-OlivierVares, fui con git remote set-url --push origin -- --read-only--- tenga en cuenta el extra --para permitir un nombre con guiones iniciales. Esto me pareció más legible.
lindes
13

Además de cambiar la URL de inserción a algo no válido (por ejemplo, git remote set-url --push origin DISABLED), también se puede usar el pre-pushenlace.

Una forma rápida de detenerse git pushes hacer un enlace simbólico /usr/bin/falsepara ser el gancho:

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

El uso de un gancho permite un control más fino de los empujes si es deseable. Vea .git/hooks/pre-push.sampleun ejemplo de cómo evitar empujar los compromisos de trabajo en progreso.

Para evitar empujar a una rama específica o limitar el empuje a una sola rama, esto en un gancho de ejemplo:

$ 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 repositorio de prueba con múltiples controles remotos:

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

Empujar a originestá permitido:

$ 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

Empujar a cualquier otro control remoto no está permitido:

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

Tenga en cuenta que el pre-pushscript de enlace puede modificarse para, entre otras cosas, imprimir un mensaje en stderr diciendo que la inserción ha sido desactivada.

Rodolfo Carvalho
fuente
¡Buena idea! Sin una secuencia de comandos más elaborada, deshabilitaría la inserción de todos los controles remotos.
v01pe
1
@ v01pe sí. He actualizado la respuesta para incluir un script de ejemplo. Realmente no necesita mucho para filtrar los impulsos a una sola rama. Un revestimiento de concha sería suficiente.
Rodolfo Carvalho
4

La afirmación general "Git se negará a empujar a un repositorio no descubierto" no es cierta. Git solo se negará a enviar a un repositorio remoto no descubierto si está intentando enviar cambios que están en la misma rama que el directorio de trabajo desprotegido del repositorio remoto.

Esta respuesta da una explicación simple: https://stackoverflow.com/a/2933656/1866402

(Estoy agregando esto como respuesta porque todavía no tengo suficiente reputación para agregar comentarios)

pkeller
fuente
un repositorio simple no tiene directorio de trabajo desprotegido, por definición. Sin embargo, puede empujar a una rama en particular.,
Ed Randall
1

Si ya tiene un conjunto remoto y sólo quiere evitarse que hacer algo como accidentalmente empuja directamente a master, o release/production, puede evitar esto 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

Para el registro, no_pushno es un nombre especial. Es solo el nombre de cualquier rama inexistente. Entonces podría usar $ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_mastery funcionaría bien.

Más información: git-config pushRemote

PaulMest
fuente
0

Si tiene control sobre el repositorio, puede lograrlo haciendo uso de los permisos. El usuario que va a buscar el repositorio no debería tener permisos de escritura en el repositorio maestro.

Abhilash
fuente
Si no puede modificar los archivos, tampoco puede buscar nuevos cambios.
Solo estudiante