git

.gitattributes y estrategia de fusión individual para un archivo



(4)

Tengo un maestro y una rama de prueba de mi aplicación (web). Estos proyectos son casi iguales, excepto por un archivo que configura la aplicación, por ejemplo, "configuración".

Cada vez que fusiono una rama con la otra, me gustaría que esa rama mantenga su versión de configuración. Es decir, git no debe intentar fusionar los cambios en ese archivo.

Seguí la guía del libro Pro Git y creé un archivo .gitattributes, con la línea "setup merge = ours". Sin embargo, esto no funciona, ni con las combinaciones de avance rápido, no si introduzco conflictos.

(Para ser preciso:

$: mkdir gitest $: cd gittest $: git init $: echo "setup merge=ours" >> .gitattributes $: echo "master" >> setup $: git add setup .gitattributes $: git commit -a -m ... $: git branch test $: git checkout test $: echo "test" >> setup $: git commit -a -m ... $: git checkout master $: git merge test

Resultado esperado: la instalación contiene la palabra "maestro", en lugar de eso, git realiza una fusión ff y la configuración es "prueba".


Descubrí que si modificaba los archivos en ambas ramas y confirmaba las modificaciones en cada rama, y ​​luego probaba la combinación, invocaría el controlador de combinación y escucharía mis .gitattributes que especifican merge=ours . Después de esto, los dos archivos siempre difieren en las dos ramas y, por lo tanto, el controlador de combinación siempre se invocará, por lo que no necesité tener un controlador de combinación personalizado que toque el archivo. Solo era necesario tener ambos modificados inicialmente.


El controlador de combinación solo se llama en casos no triviales, es decir, si tanto el maestro como la prueba han tocado la configuración (y primero debe definir el controlador de combinación ours ):

git init git config merge.ours.name ''"always keep ours" merge driver'' git config merge.ours.driver ''touch %A'' echo "setup merge=ours" >> .gitattributes echo "master" >> setup git add setup .gitattributes git commit -a -m ... git branch test git checkout test echo "test" >> setup git commit -a -m ... git checkout master echo "more content" >> setup git commit -a -m ... git merge test

Dicho esto, me pregunto si sería sensato tener una configuración en el repositorio. Si realmente lo quiere bajo el control de versiones, puede usar los submódulos o la estrategia de fusión de subárbol para mantener los archivos comunes sincronizados.


Tenga una secuencia de comandos de limpieza de manchas en lugar de ramas separadas. El script puede ser diferente según la máquina en la que se encuentre.


Tuve el mismo error y se puede resolver simplemente definiendo un controlador de combinación "nuestro" en .git / config:

[merge "ours"] name = "Keep ours merge" driver = true

Dado que siempre devuelve 0, el archivo temporal que contiene el estado actual no se modificará y se mantendrá como la versión final.

Puede leer más sobre el controlador de combinación aquí: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html#_defining_a_custom_merge_driver

Apéndice:

Esto funciona cada vez que se llama al controlador y esto parece ocurrir solo cuando hay confirmaciones para cambiar los mismos archivos (git, el atributo de combinación). Si hay cambios en una sola rama, no se llamará al controlador.