Prevenir confirmaciones en la rama maestra

84

(Para simplificar) Tengo una masterrama y una deven mi Git-repo. Quiero asegurarme de que la mastersucursal siempre esté funcionando, por lo que todo el trabajo que haga debería estar en la devsucursal.

Sin embargo, cuando fusiono mis cambios con una --no-fffusión, tiendo a permanecer en la masterrama y simplemente sigo trabajando en ella (porque me olvido de verificar mi devrama).

¿Puedo poner una regla para la masterrama, que indique que no puedo hacer confirmaciones y fusiones de avance rápido, pero solo --no-fffusiones desde otra rama?

Esto debe funcionar para repositorios alojados privados (ergo, no GitHub y BitBucket).

Rasmus Bækgaard
fuente
4
"confirmaciones de avance rápido" no es una cosa. Las confirmaciones son solo confirmaciones, git commitcrea una nueva, no se produce ningún avance rápido. Parece que solo desea prohibir las confirmaciones ordinarias cuando la rama actual es master, en cuyo caso, busque en el pre-commitgancho.
torek

Respuestas:

154

Sí, es posible. Debe crear un gancho de confirmación previa que rechace las confirmaciones de la rama maestra. Git no llama al gancho de confirmación previa cuando llama al comando merge , por lo que este gancho rechazará solo las confirmaciones regulares.

  1. Vaya a su repositorio.
  2. Cree el archivo .git / hooks / pre-commit con el siguiente contenido:

    #!/bin/sh
    
    branch="$(git rev-parse --abbrev-ref HEAD)"
    
    if [ "$branch" = "master" ]; then
      echo "You can't commit directly to master branch"
      exit 1
    fi
    
  3. Hágalo ejecutable (no es necesario en Windows ):

    $ chmod +x .git/hooks/pre-commit
    

Para deshabilitar las combinaciones de avance rápido, también debe agregar la siguiente opción a su archivo .git / config :

[branch "master"]
    mergeoptions = --no-ff

Si también desea proteger la rama maestra en su control remoto, verifique esta respuesta: Cómo restringir el acceso a la rama maestra en git

qzb
fuente
Esto se ve exactamente como lo que necesito, ¿esto también funciona en Windows?
Rasmus Bækgaard
2
@ RasmusBækgaard sí, lo hará: el script de bash para el gancho será interpretado por el bash de Git incluido en Git para Windows. (Simplemente no necesita el paso chmod)
VonC
nota: también puede evitar empujar hacia una masterrama remota en el gancho de pre-empuje. ej .: gist.github.com/aaronhoffman/ffbfd36928f9336be2436cffe39feaec
Aaron Hoffman
4
Bien, para cualquiera que busque una manera de agregar estas reglas u otros ganchos de git en el repositorio del proyecto, consulte este paquete npm simple: github.com/kilianc/shared-git-hooks , porque no puede incluir nada que resida debajo del .git directorio en el repositorio.
George Dimitriadis
9
Además, esto es solo para nuestro repositorio de git local, ¿cómo podemos hacer cumplir las reglas en diferentes repositorios de git para todos los desarrolladores sin que cambien manualmente el contenido del directorio .git?
Alexander Mills
13

Puede utilizar la utilidad de confirmación previa para hacer esto. Tiene un no-commit-to-branchgancho incorporado que se puede usar para evitar compromisos en una o más ramas.

Preparar

El proceso de configuración básico es:

  • Instalar usando pip o brew (instrucciones en https://pre-commit.com/#install )
  • Cree un .pre-commit-config.yamlarchivo en la raíz de su proyecto (vea a continuación un primer borrador)
  • Instale los ganchos en su configuración de git ejecutando pre-commit install.

Configuración básica para proteger ramas

Aquí hay una configuración básica que incluye solo el no-commit-to-branchgancho:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master']

Si desea proteger varias ramas, puede usar incluir varios --branchargumentos en la lista de argumentos:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master', '--branch', 'staging']

¿No es todo esto exagerado?

La confirmación previa tiene muchos otros enlaces incorporados y una gran colección de enlaces creados por la comunidad que transformarán la forma en que limpia y valida sus confirmaciones. La razón por la que menciono esto es porque, si bien esta herramienta puede ser excesiva solo para evitar compromisos en una rama protegida, tiene muchas otras características que la convierten en una adición simple y convincente para cualquier proyecto de git.

JGC
fuente
7

Puede tener sentido instalarlo globalmente a través de

git config --global core.hooksPath ~/githooks

y mover ese pre-commitarchivo a ese directorio

Michel Samia
fuente
¿Qué pasa si tengo varios repositorios? ¿No los afectará a todos?
Rasmus Bækgaard
1
y eso es lo que puede hacer en la mayoría de los casos
Michel Samia
Digamos que tengo este proyecto extraño, donde se les cambió el nombre mastera Production: ¿se pueden hacer excepciones?
Rasmus Bækgaard
puede usar u operador en bash para especificar más ramas que desea proteger en el lado del cliente
Michel Samia