¿Puedo hacer que el reenvío rápido esté desactivado por defecto en git?

263

Realmente no puedo pensar en un momento en el que usaría en git mergelugar de git rebasey no quiero tener una presentación de confirmación. ¿Hay alguna forma de configurar git para que tenga un reenvío rápido desactivado de forma predeterminada? El hecho de que haya una --ffopción parece implicar que hay una manera, pero parece que no puedo encontrarla en la documentación.

Jason Baker
fuente
3
Uso mergetodo el tiempo para las sucursales cuando no he realizado ninguna confirmación desde su control remoto para avanzar rápidamente. Parece la forma más sencilla y segura de hacer esto. Tengo curiosidad, obviamente tienes un caso de uso. ¿Por qué querrías crear un commit de fusión donde no hay commits en un lado de la rama?
CB Bailey
12
Utilizo ramas para crear una agrupación lógica de confirmaciones. Entonces, si hago una fusión, es básicamente una forma de decir "estas confirmaciones van juntas". Casi puedes pensar en ello como el rebase interactivo y el squash de un hombre pobre. :-)
Jason Baker
13
Desactivar el avance rápido es extremadamente útil, especialmente cuando se sigue un modelo como Un modelo de ramificación Git exitoso
steinybot
2
Cambie la respuesta aceptada para esto a la respuesta de Eric Platon stackoverflow.com/a/6810687/3408 : hice los pasos en la respuesta aceptada, luego me di cuenta de que era solo para la rama maestra en el repositorio actual, lo cual es una tontería.
rjmunro
3
@ jpmc26 Cada uno a lo suyo, supongo. Estoy en desacuerdo con ese artículo. Encontrar a los dos padres de un commit de fusión no es difícil y te dice exactamente cuáles fueron los cambios. Luego puede tomar esos cambios y hacer un "rebase en" alguna otra rama. Con el modelo plano, debe buscar manualmente y elegir cereza. Elegimos adoptar la ramificación. Claro que es complejo cuando se mira todo el árbol, pero esa es la realidad, múltiples cambios que ocurren en paralelo. Aplanar todo simplemente esconde lo que realmente sucedió.
steinybot

Respuestas:

282

Sí, hay --no-ff. Puede configurar las opciones de fusión por rama, p. Ej.

git config branch.master.mergeoptions  "--no-ff"

agrega lo siguiente a su $(REPO)/.git/configarchivo:

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

Nota al pie de página: hablando de mi experiencia, eventualmente descubrí que cambiar de avance rápido a apagado fue principalmente útil para los recién llegados a GIT; sin embargo, una vez que la sensación de los flujos de trabajo y los conceptos comiencen a hundirse, definitivamente querrás evitar difuminar tu gráfico de registro con toneladas de fusiones sin sentido. confirmaciones de tipo remoto ..blarf '.

Nota 2, una década después: las otras respuestas a continuación proporcionan opciones de configuración más modernas, pero en realidad, probablemente QUIERES mantenerte con los valores predeterminados (es decir, avanzar rápidamente siempre que sea posible) en este día y edad, porque los compromisos de fusión vacíos realmente solo hace que la historia sea mucho más difícil de razonar.

conny
fuente
142
Aprender git es un poco como escalar montañas; pero en lugar de comenzar con pequeños acantilados y progresar hacia los más difíciles, git te hace subir la misma montaña una y otra vez, solo para caer a diferentes alturas cada vez, cada vez tan sorprendido de que la línea de vida no esté conectada.
conny
12
@Thomas: Sí; git pulles git fetch+ git merge.
Michelle Tilley
9
Esto se ve bien, pero ¿hay alguna manera de hacerlo globalmente, para todas las ramas, en lugar de tener que configurarlo para cada rama?
Bwinton
33
Cuidado con los dragones. Esta opción es peligrosa tal como lo dijo @Thomas ... Cada extracción de git crea commit de fusión. git pull --ff no anula mergeoptions = no-ff en git config.
Dalibor Filus
15
¿Qué pasa si estoy cansado de escribir git merge --no-ff (branchname)? ¿Y quiero git pullfuncionar como siempre lo ha hecho?
Dogweather
341

Parece que todavía hay una pregunta pendiente en el hilo: ¿Cómo hacerlo globalmente (es decir, para todas las ramas)? Para los registros, podemos usar lo siguiente:

git config --add merge.ff false

... para que se aplique a todas las ramas en el repositorio actual. Para que se aplique a todas las ramas en todos los repositorios donde alguien no lo ha ejecutado sin la --globalopción (la configuración local anula la global) ejecute esto:

git config --global --add merge.ff false

De la documentación :

merge.ff
De forma predeterminada, git no crea una confirmación de fusión adicional al fusionar una confirmación que es descendiente de la confirmación actual. En cambio, la punta de la rama actual se reenvía rápidamente. Cuando se establece en falso, esta variable le dice a git que cree una confirmación de fusión adicional en tal caso (equivalente a dar la --no-ffopción desde la línea de comando). Cuando se establece en solo, solo se permiten tales fusiones de avance rápido (equivalente a dar la --ff-onlyopción desde la línea de comandos).

Eric Platon
fuente
18
Nota: merge.ffse introdujo en Git 1.7.6. No es efectivo en versiones anteriores.
Chris Johnsen
2
Para las personas que usan Git 1.7.6, esta es la mejor y más simple solución.
Ryan Lundy
22
Estoy usando esto junto con un aliaspuff = "pull --ff --ff-only"
stigi
11
Theres también es (ahora, ver git-scm.com/docs/git-config ) la opción pull.ff que se puede ajustar a solamente , lo que va a hacer lo mismo que el alias.
jotomo
1
Gracias @jotomo. Esa característica está disponible en Git v2.0.0 (desde commit b814da891e8261b909fc5d9fb07b4e8b13989c2d).
Eric Platon
14

Leyendo el hilo de respuestas terminé usando las siguientes dos opciones

git config --global pull.ff only # Disallows non ff merges on pull. Overrides merge.ff when pulling
git config --global merge.ff false # even create extra merge commit when fast forward merge would be possible

Solo vagamente relacionado, también he encontrado que esta configuración evita problemas durante la extracción

git config --global pull.rebase true # set up pull to rebase instead of merge
bastian
fuente
1
git config --global pull.rebase true # note 'true' al final de la línea
zowers
Gracias @zowers He arreglado esto
bastian