Git: ignorar archivos durante la combinación

115

Tengo un repositorio llamado myrepoen el beanstalkservidor remoto .

Lo cloné en mi máquina local. Creó dos ramas adicionales: stagingy dev. Empujó estas ramas a distancia también.

Ahora:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

Tengo un archivo llamado config.xmlque es diferente en cada rama.

Quiero ignorar este archivo solo durante las fusiones. Pero quiero que esto se incluya cuando realice el pago o confirme desde / hacia la rama de repositorio.

La razón por la que quiero esto es que tenemos un script de implementación que extrae (comprueba) la rama específica y se implementa en los servidores respectivos. Entonces, necesitamos que el config.xmlarchivo de esa rama específica ingrese al servidor específico como se indicó anteriormente cuando se implemente.

Supongo que .gitignoreno funcionará. ¿Cuáles son las otras opciones? Tenga en cuenta que el archivo ignorado debe ser parte de la verificación y confirmación, lo cual es importante. solo debe ignorarse durante las fusiones.

¡Gracias!

Kevin Rave
fuente
En su modo predeterminado, git pull es la abreviatura de git fetch seguido de git merge FETCH_HEAD. Así que sus declaraciones entran en conflicto entre sí.
zzk
Bueno, yo diría que es pago. No tirar. Actualizaré la pregunta para que quede clara.
Kevin Rave
2
¿Encontraste alguna vez una solución a esto? Los atributos git solo son útiles en el caso de que el archivo tenga conflictos entre las ramas que se fusionan, por lo que no siempre es suficiente.
pvinis
¿Buscaste enlaces simbólicos (no seguidos por git) o ​​incluso duros para el rescate?
Frank Nocke

Respuestas:

94

Superé este problema usando el comando git merge con la --no-commitopción y luego eliminé explícitamente el archivo por etapas e ignoré los cambios en el archivo. Por ejemplo: digamos que quiero ignorar cualquier cambio para myfile.txtproceder de la siguiente manera:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

Puede poner las declaraciones 2 y 3 en un bucle for, si tiene una lista de archivos para omitir.

unmesh-gurjar
fuente
2
Agregaría "--no-ff" si desea que un archivo no se sobrescriba cuando se produce la fusión en la estrategia de avance rápido.
Ilia Shakitko
1
entonces, ¿qué hace git reset HEAD myfile.txtexactamente? ¿Cómo ayuda con nuestro objetivo aquí?
Kid_Learning_C
¿Cómo pones las líneas 2 y 3 en un bucle?
AndroidDev
52

Terminé encontrando a git attributes. Probándolo. Trabajando hasta ahora. No comprobé todos los escenarios todavía. Pero debería ser la solución.

Fusionar estrategias: atributos de Git

Kevin Rave
fuente
4
pero encontré este git-scm.com/book/ch7-2.html#Merge-Strategies
Nate-
1
Aquí está el enlace correcto para la sección de estrategias de fusión de los documentos de atributos de git: git-scm.com/book/en/v2/…
Adrian Laurenzi
3
Encontré esto bien explicado en un artículo medium.com/@porteneuve/…
ShawnFeatherly
10
¿Esto parece ser un problema si no hay conflictos? ¿Los archivos aún se fusionarán?
Brett
18

.gitattributes : es un archivo de nivel raíz de su repositorio que define los atributos de un subdirectorio o subconjunto de archivos.

Puede especificar el atributo para decirle a Git que use diferentes estrategias de combinación para un archivo específico. Aquí, queremos preservar lo existente config.xmlpara nuestra rama. Tenemos que establecer el merge=oursque config.xmlen .gitattributesel archivo.

merge=ours dígale a git que use nuestro archivo (rama actual), si ocurre un conflicto de fusión.

  1. Agregar un .gitattributesarchivo en el nivel raíz del repositorio

  2. Puede configurar un atributo para confix.xml en el .gitattributesarchivo

    config.xml merge=ours
    
  3. Y luego defina una estrategia ficticia de fusión nuestra con:

    $ git config --global merge.ours.driver true
    

Si fusiona la rama de stagformulario dev, en lugar de que la fusión entre en conflicto con el archivo config.xml, el config.xml de la rama de ciervo se conserva en la versión que tenía originalmente.

eigenharsha
fuente
16
Pero, ¿y si no hay conflicto? ¿Cómo mantener siempre un archivo determinado durante la fusión?
Igor Yalovoy
2
@IgorYalovoy: Si no hay conflicto ... bueno, esto es un poco complicado, ya que en realidad funciona con ID de hash, pero: si no config.xmlha cambiado completamente desde la base de fusión a cualquiera de las versiones de punta de rama, Git solo toma la versión modificada, sin mirando el merge.ours.driverescenario. Así que tienes razón al preocuparte.
torek
1
copiar y pegar de Git Docs: Combinar estrategias - Atributos de Git. Enlace
kyb
Este método da como resultado "combinaciones de confirmaciones" cada vez que, para tu información,
rsmets
2
"nuestro" parece ser un nombre arbitrario para la nueva estrategia que se está introduciendo. Encontré esto confuso, porque theirses una estrategia de fusión incorporada. Pero parece que se puede escribir <pattern> merge=foo, entonces git config --global merge.foo.driver true, y funcionará de la misma manera.
Kyle Strand
8

Puede comenzar usando git merge --no-commit, y luego editar la combinación como desee, es decir, desestabilizando config.xmlo cualquier otro archivo, luego confirme . Sospecho que querrás automatizarlo aún más después de eso usando ganchos, pero creo que valdría la pena revisarlo manualmente al menos una vez.

gcbenison
fuente
2
¿Ofrece git attributesalguna solución directa? No puedo entender esto. git-scm.com/book/en/…
Kevin Rave
4

Puede usar .gitignorepara mantener el archivo config.xmlfuera del repositorio y luego usar un enlace posterior a la confirmación para cargar el config.xmlarchivo apropiado en el servidor.

tlehman
fuente
1
Sé que es una especie de truco. Estoy tratando de encontrar una solución limpia. ¿Qué pasa con git attributes? ¿Alguna idea de cómo funciona? No puedo entender esto. git-scm.com/book/en/…
Kevin Rave
1
No he oído hablar de estos, estoy tratando de aplicar el atributo merge = our, parece prometedor.
tlehman
1
¡Los atributos de Git son increíbles! ¡Incluso puede decirle a git cómo diferenciar archivos que no son de texto, por lo que podría usar pdf2text para diferenciar PDF!
tlehman
2

Ejemplo:

  1. Usted tiene dos ramas: master,develop
  2. Creó un archivo en la developrama y desea ignorarlo mientras fusiona

Código:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

También puede ignorar archivos con la misma extensión

por ejemplo, todos los archivos con .txtextensión:

echo "*.txt merge=ours" >> .gitattributes
Sole Sensei
fuente
1

Aquí git-update-index: registra el contenido del archivo en el árbol de trabajo en el índice.

git update-index --assume-unchanged <PATH_OF_THE_FILE>

Ejemplo:-

git update-index --assume-unchanged somelocation/pom.xml

Sireesh Yarlagadda
fuente
Eso es bueno al presionar, pero aún se queja cuando al extraerlo se puede sobrescribir el archivo.
Rolf
1
¿Ha intentado agregar la entrada de su archivo en el archivo .gitignore? @Rolf
Sireesh Yarlagadda