¿Es posible que git-merge ignore las diferencias de fin de línea?


¿Es posible que git merge ignore las diferencias de fin de línea?

Tal vez estoy haciendo la pregunta equivocada ... pero:

Probé uisng config.crlf inputpero las cosas se pusieron un poco desordenadas y fuera de control, especialmente cuando lo apliqué después del hecho.

Por un lado, aplicar esta configuración después del hecho no parece afectar a los archivos que fueron confirmados en el repositorio antes de aplicar esta opción. Otra cosa es que de repente todas las confirmaciones ahora resultan en un montón de advertencias molestas mensajes sobre la conversión de CRLF a LF.

Para ser honesto, realmente no me importa qué final de línea se use, personalmente prefiero el estilo Unix \n, pero lo que sea. Todo lo que me importa, es que git merge sea un poco más inteligente e ignore las diferencias en los finales de línea.

A veces tengo dos archivos idénticos, pero git los marcaría como en conflicto (y el conflicto es el archivo completo) simplemente porque usan una terminación de línea diferente caracter.

Actualización:

Descubrí que git diff acepta una opción --ignore-space-at-eol, ¿sería posible dejar que git merge use esta opción también?

Author: hippietrail, 2009-05-14

12 answers

Actualización 2013:

Las versiones más recientes de git autorizan el uso de la opción merge con strategy recursive y strategy (-X):

git merge -s recursive -Xignore-space-at-eol

Pero usando "-Xignore-space-change" es también una posibilidad


Jakub.g también comenta que las estrategias funcionan también con la recolección de cerezas :

git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize 

Esto funciona mucho mejor que ignore-all-space.


Respuesta original (mayo de 2009)

El parche para ignorar el estilo eol se propuso en junio de 2007, pero solo concierne a git diff --ignore-space-at-eol, no a git merge.

En ese momento, la pregunta ha sido formulada: {[18]]}

Debería --ignore-space-at-eol ser una opción a git-merge ?
Las fusiones son donde esta funcionalidad importa.
¿Cuáles son las semánticas de una fusión auto-resuelta con esas opciones en efecto are ¿solo se usan para la detección de nombres, o nosotros, por ejemplo, no marcamos conflictos con solo cambios de espacios en blanco ? Y si no lo hacemos, ¿qué versión aceptamos automáticamente ?

Julio C Hamano no estaba exactamente entusiasmado: {[18]]}

Esto ciertamente es tentador, pero sospecho que debería dejarse para rondas posteriores.
Sospecho que introduciría un concepto de dos tipos diferentes de diffs, uno para ser procesado mecánicamente (es decir, uso en fusión con "git-merge-recursive", y aplicar con "git-am"), y otro para ser inspeccionado por los seres humanos para entender.
A menudo puede ser útil para munge la entrada para el último caso, a pesar de que la salida de la comparación de archivos de entrada munged puede no ser fácilmente utilizable para aplicaciones mecánicas.

La idea general, cuando se trata de git merge, es confiar en la herramienta de fusión de terceros.

Por ejemplo, he configurado DiffMerge para ser la herramienta para Git merge, estableciendo un conjunto de reglas que permiten que la herramienta merge ignore eol para cierto tipo de archivos.


Configuración en Windows, con MSysGit1.6. 3, ya sea para DOS o Git bash session, con DiffMerge o KDiff3:

  • establece un directorio en tu RUTA (aquí: c:\HOMEWARE\cmd).
  • añadir en ese directorio el script merge.sh (envoltura para su herramienta de fusión favorita)

Merge.sh:

#!/bin/sh

# Passing the following parameters to mergetool:
#  local base remote merge_result

alocal=$1
base=$2
remote=$3
result=$4

if [ -f $base ]
then
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$base" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # for merge respecting eol, KDiff3 is better than DiffMerge (which will always convert LF into CRLF)
    # KDiff3 will display eol choices (if Windows: CRLF, if Unix LF)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$alocal" "$remote" -o "$result"
else
    #there is not always a common ancestor: DiffMerge needing 3 files, BASE will be the result
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$result" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # KDiff3 however does know how to merge based on 2 files (not just 3)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$remote" -o "$result"
fi
  • Declara tu envoltorio merge para Git

Git comandos de configuración:

git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd "merge.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\"
git config --global mergetool.diffmerge.trustExitCode false
git config --global mergetool.diffmerge.keepBackup false
  • Compruebe que autoCRLF es false

Configuración de Git a nivel del sistema:

git config ---system core.autoCRLF=false
  • Pruebe que, cuando dos líneas son idénticas (pero sus caracteres eol), tanto DiffMerge como KDiff3 ignorarán esas líneas durante una fusión.

Script DOS (nota: el comando dos2unix viene de aquí, y se usa para simular un estilo Unix eol. Ese comando ha sido copiado en el directorio mencionado al principio de este respuesta.):

C:\HOMEWARE\git\test>mkdir test_merge C:\HOMEWARE\git\test>cd test_merge C:\HOMEWARE\git\test\test_merge>git init C:\HOMEWARE\git\test\test_merge>echo a1 > a.txt & echo a2 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "a.txt, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout -b windows Switched to a new branch 'windows' C:\HOMEWARE\git\test\test_merge>echo a3 >> a.txt & echo a4 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add two lines, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout master C:\HOMEWARE\git\test\test_merge>git checkout -b unix Switched to a new branch 'unix' C:\HOMEWARE\git\test\test_merge>echo au3 >> a.txt & echo au4 >> a.txt && echo au5 >> a.txt C:\HOMEWARE\git\test\test_merge>dos2unix a.txt Dos2Unix: Processing file a.txt ... C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add 3 lines, all file unix eol style" [unix c433a63] add 3 lines, all file unix eol style C:\HOMEWARE\git\test\test_merge>git merge windows Auto-merging a.txt CONFLICT (content): Merge conflict in a.txt Automatic merge failed; fix conflicts and then commit the result. C:\HOMEWARE\git\test\test_merge>git ls-files -u 100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1 a.txt 100644 28b3d018872c08b0696764118b76dd3d0b448fca 2 a.txt 100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3 a.txt C:\HOMEWARE\git\test\test_merge>git mergetool Merging the files: a.txt Normal merge conflict for 'a.txt': {local}: modified {remote}: modified Hit return to start merge resolution tool (diffmerge):

En este punto (pulsando "return"), se abrirá DiffMerge o KDiff3, y verá por sí mismo qué líneas se fusionan realmente y qué líneas se ignoran.

Advertencia : el archivo de resultado siempre estará en modo eol de Windows (CRLF) con DiffMerge...
KDiff3 ofrece ahorrar de una forma u otra.

 97
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:29

Estaba buscando la misma respuesta y descubrí esto

Fusionando ramas con diferentes atributos de checkin/checkout

Si ha agregado atributos a un archivo que causan la formato de repositorio para que ese archivo cambie, como agregar un filtro limpio / difuminado o atributos de texto / eol / ident, fusionando cualquier cosa donde el atributo no está en su lugar normalmente causaría la fusión conflicto.

Para evitar estas fusiones innecesarias conflictos, a git se le puede decir que ejecute un check-out virtual y check-in de las tres etapas de un archivo cuando resolver una fusión de tres vías configurando la fusión.renormalizar variable de configuración. Esto evita los cambios causados por el check-in conversión de causar conflictos de fusión espuria cuando un archivo convertido se fusiona con un archivo no convertido.

Siempre y cuando un "smudge→clean" resulte en la misma salida que un " clean" incluso en archivos que ya están manchados, esta estrategia resolver automáticamente todos los conflictos relacionados con filtros. Filtros que hacen no actuar de esta manera puede causar conflictos de fusión adicionales que deben ser resuelto manualmente.

Así que ejecutar este comando en cualquier repositorio hará el truco:

git config merge.renormalize true
 79
Author: Fabio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-30 10:25:38

Después de leer https://stackoverflow.com/a/12194759/1441706 y https://stackoverflow.com/a/14195253/1441706

Para mí, este comando hizo el truco perfectamente:

git merge master -s recursive -X renormalize
 18
Author: Fab V.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:13

Como en esta respuesta: https://stackoverflow.com/a/5262473/943928

Puedes intentar: git merge -s recursive -Xignore-space-at-eol

 6
Author: Rune Schjellerup Philosof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:54

Lo que hice fue dejar todo como predeterminado (es decir, autocrlf=true), tocar todos los archivos (find . - exec touch {}\;), deja que git los vea como 'modificados' y los confirme, y termina con esto. De lo contrario, siempre estará plagado de mensajes molestos o diferencias sorprendentes, o tendrá que desactivar todas las funciones de espacios en blanco de git.

Perderás la información de la culpa, pero es mejor hacerlo más pronto que tarde:)

 4
Author: Ben Hymers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-14 08:10:40

"git merge-Xrenormalize" funciona como un encanto.

 4
Author: Jake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-04 21:25:09

No parece que esto se pueda hacer directamente, pero este post sugiere una solución.

Http://osdir.com/ml/git/2009-02/msg02532.html

 1
Author: Dean Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-14 08:03:34

Http://stahlforce.com/dev/index.php?tool=remcrlf

Lo intenté, pero si después de la última línea de tu código no tenías CRLF añade por sí mismo un LF y el archivo parece cambiado en git. Aparte de eso, funciona.

 1
Author: antman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-24 19:53:15

Me parece ahora que la mejor manera es normalizar las terminaciones de línea en ambas ramas (y commit) antes de fusionarlas.

Busqué en Google "convertir crlf a lf" y encontré esto como los primeros resultados:
http://stahlforce.com/dev/index.php?tool=remcrlf

Lo descargué y lo usé, parece una buena herramienta.

>sfk remcr . .py

Sin embargo, asegúrese de especificar un directorio y un tipo de archivo (por ejemplo .py) de lo contrario podría tratar de interferir con el contenido del directorio .git!

 0
Author: hasen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-16 03:12:15

AFAICT, (no lo he probado) podría usar git diff para comparar la rama que desea fusionar con el ancestro común, luego aplicar los resultados con git apply. Ambos comandos tienen opciones --ignore-whitespace para ignorar los errores de fin de línea y espacio en blanco.

Desafortunadamente, si el parche no se aplica de forma limpia, se interrumpe toda la operación. No puede solucionar los conflictos de fusión. Hay una opción --reject para dejar trozos no reproducibles en los archivos .rej, lo que ayuda, pero no es lo mismo que tener los conflictos de fusión que se muestran en un archivo.

 0
Author: rjmunro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-23 09:49:27

Después de leer Resolver conflictos de fusión: Forzar sobrescribir todos los archivos

Finalmente resolví mi versión de este problema. Estaba tratando de sacar actualizaciones del repositorio de upstream, pero mi actual estaba teniendo problemas relacionados con CRLF y no pudo fusionarse como resultado. Cabe señalar que NO tenía CAMBIOS LOCALES de los que tuviera que preocuparme. Los siguientes pasos resolvieron mi problema:

Según las instrucciones de github sobre la sincronización de bifurcaciones ( https://help.github.com/articles/syncing-a-fork/):

  1. git fetch upstream

  2. git reset --hard upstream/master
    Mi comprensión limitada de git me dice que esto está haciendo lo que quiero reb rebasando mi bifurcación (sin cambios reales sin confirmar) para obtener todos los cambios realizados en el código fuente original. De acuerdo con la página fuente, este paso normalmente no debería ser requerido, pero el problema CRLF lo hizo obligatorio.

  3. git merge upstream/master

  4. git push
 -1
Author: propagated,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:25

Sin embargo, sugiero usar herramientas como sed para lograr finales de línea correctos, y luego archivos diff. Pasé un par de horas en diffing proyectos con varios finales de línea.

La mejor manera era:

  1. copie solo los archivos de proyecto (omita el directorio .git) a otro directorio cree un repositorio en él, luego agregue archivos y confírmelos (debería estar en la rama maestra en el nuevo repositorio).
  2. copiar archivos del segundo proyecto a la misma carpeta, pero otra rama por ejemplo dev (git checkout -b dev), confirmar archivos en esta rama y ejecutar (si el primer proyecto está en master): git diff master..dev --names-only para ver solo los nombres de los archivos modificados
 -1
Author: user4686964,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-18 20:35:32