tener tag remove qué proyecto practices podemos para oneline nuestros mayor log herramienta hacer hace control best git version-control latex

tag - ¿qué hace git log-oneline?



Git fusionarse dentro de una línea (3)

Preámbulo

Estoy usando git como sistema de control de versiones para un papel que está escribiendo mi laboratorio, en LaTeX. Hay varias personas colaborando.

Me estoy topando con Git siendo terco acerca de cómo se fusiona. Digamos que dos personas han realizado cambios de una sola palabra en una línea y luego intentan fusionarlos. Aunque git diff --word-diff parece capaz de MOSTRAR la diferencia entre las ramas palabra por palabra, git merge parece incapaz de realizar la combinación palabra por palabra, y en su lugar requiere una combinación manual.

Con un documento LaTeX esto es particularmente molesto, ya que el hábito común al escribir LaTeX es escribir un párrafo completo por línea y simplemente dejar que su editor de texto maneje el ajuste de palabras cuando lo muestre. Estamos trabajando por el momento agregando una nueva línea para cada oración, de modo que git pueda al menos combinar cambios en diferentes oraciones dentro de un párrafo. Pero todavía se confundirá con los múltiples cambios dentro de una oración, y esto hace que el texto ya no se ajuste bien, por supuesto.

La pregunta

¿Hay alguna manera de combinar dos archivos "palabra por palabra" en lugar de "línea por línea"?


Aquí hay una solución en la misma línea que la de Sehe, con algunos cambios que esperamos que respondan a sus comentarios:

  • Esta solución considera la fusión por oración en lugar de por palabra, como lo había estado haciendo a mano, solo ahora, el usuario verá una sola línea por párrafo, pero git verá los párrafos divididos en oraciones. Esto parece ser más lógico porque agregar / eliminar una oración de un párrafo puede ser compatible con otros cambios en el párrafo, pero probablemente sea más conveniente tener una fusión manual cuando la misma oración se edita con dos confirmaciones. Esto también tiene el beneficio de que las instantáneas "limpias" siguen siendo algo legibles por los humanos (¡y compilables con látex!).
  • Los filtros son comandos de una línea, lo que debería facilitar la transferencia de esto a los colaboradores.

Como en la solución de saha, haga un (o agregue a) .gittatributes .

*.tex filter=sentencebreak

Ahora para implementar los filtros de limpiar y manchar:

git config filter.sentencebreak.clean "perl -pe /"s/[.]*?(//?|//!|//.|'''') /$&%NL%//n/g unless m/%/||m/^[// *//////]//"" git config filter.sentencebreak.smudge "perl -pe /"s/%NL%/n//gm/""

He creado un archivo de prueba con el siguiente contenido, observe el párrafo de una línea.

/chapter{Tumbling Tumbleweeds. Intro} A way out west there was a fella, fella I want to tell you about, fella by the name of Jeff Lebowski. At least, that was the handle his lovin'' parents gave him, but he never had much use for it himself. This Lebowski, he called himself the Dude. Now, Dude, that''s a name no one would self-apply where I come from. But then, there was a lot about the Dude that didn''t make a whole lot of sense to me. And a lot about where he lived, like- wise. But then again, maybe that''s why I found the place s''durned innarestin''. This line has two sentences. But it also ends with a comment. % here

Después de enviarlo al repositorio local, podemos ver los contenidos en bruto.

$ git show HEAD:test.tex /chapter{Tumbling Tumbleweeds. Intro} A way out west there was a fella, fella I want to tell you about, fella by the name of Jeff Lebowski. %NL% At least, that was the handle his lovin'' parents gave him, but he never had much use for it himself. %NL% This Lebowski, he called himself the Dude. %NL% Now, Dude, that''s a name no one would self-apply where I come from. %NL% But then, there was a lot about the Dude that didn''t make a whole lot of sense to me. %NL% And a lot about where he lived, like- wise. %NL% But then again, maybe that''s why I found the place s''durned innarestin''. This line has two sentences. But it also ends with a comment. % here

Así que las reglas del filtro limpio son cada vez que encuentra una cadena de texto que termina con . o ? o ! o '''' (esa es la forma de látex de hacer comillas dobles) luego un espacio, agregará% NL% y un carácter de nueva línea. Pero ignora las líneas que comienzan con / (comandos de látex) o contienen un comentario en cualquier lugar (por lo que los comentarios no pueden formar parte del texto principal).

El filtro de manchas elimina% NL% y la nueva línea.

La diferenciación y fusión se realiza en los archivos "limpios" para que los cambios a los párrafos se combinen frase por frase. Este es el comportamiento deseado.

Lo bueno es que el archivo de látex debe compilarse en estado limpio o manchado, por lo que hay una esperanza para que los colaboradores no tengan que hacer nada. Finalmente, podría poner los comandos de git config en un script de shell que forma parte del repositorio, por lo que un colaborador solo tendría que ejecutarlo en la raíz del repositorio para configurarse.

#!/bin/bash git config filter.sentencebreak.clean "perl -pe /"s/[.]*?(//?|//!|//.|'''') /$&%NL%//n/g unless m/%/||m/^[// *//////]//"" git config filter.sentencebreak.smudge "perl -pe /"s/%NL%/n//gm/"" fileArray=($(find . -iname "*.tex")) for (( i=0; i<${#fileArray[@]}; i++ )); do perl -pe "s/%NL%/n//gm" < ${fileArray[$i]} > temp mv temp ${fileArray[$i]} done

Lo último es un truco porque cuando se ejecuta este script por primera vez, la rama ya está desprotegida (en forma limpia) y no se mancha automáticamente.

Puede agregar esta secuencia de comandos y el archivo .gitattributes al repositorio, luego los nuevos usuarios solo necesitan clonar y luego ejecutar la secuencia de comandos en la raíz del repositorio.

Creo que este script incluso se ejecuta en Windows Git si se hace en Git Bash.

Inconvenientes:

  • Esto no maneja las líneas con comentarios inteligentemente, simplemente los ignora.
  • % NL% es algo feo
  • Los filtros pueden confundir algunas ecuaciones (no estoy seguro de esto).

Creo que el algoritmo de git merge es bastante simple (aunque puedes hacerlo trabajar más duro con la estrategia de combinación de "paciencia").
Su elemento de trabajo seguirá siendo la línea.

Pero la idea general es delegar cualquier mecanismo de git config mergetool detección de grano fino a una herramienta de terceros que pueda configurar con git config mergetool .
Si algunas palabras dentro de una línea larga difieren, esa herramienta externa ( KDiff3 , DiffMerge , ...) podrá captar ese cambio y DiffMerge .


Podrías probar esto:

En lugar de cambiar un motor de combinación ( difícil ), puede hacer algún tipo de "normalización" (canonicalización, si lo desea). No hablo LateX, pero permítanme ilustrar lo siguiente:

Digamos que tienes entrada como test.raw

curve ball well received {misfit} whatever proprietary format extinction {benefit}.

Quieres que difiera / fusione palabra por palabra. Agregue el siguiente archivo .gitattributes

*.raw filter=wordbyword

Entonces

git config --global filter.wordbyword.clean /home/username/bin/wordbyword.clean git config --global filter.wordbyword.smudge /home/username/bin/wordbyword.smudge

Una implementación minimalista de los filtros sería

/home/username/bin/wordbyword.clean

#!/usr/bin/perl use strict; use warnings; while (<>) { print "$_/n" foreach (m/(.*?/s+)/go); print ''#@#DELIM#@#'' . "/n"; }

/home/username/bin/wordbyword.smudge

#!/usr/bin/perl use strict; use warnings; while (<>) { chomp; ''#@#DELIM#@#'' eq $_ and print "/n" or print; }

Después de confirmar el archivo, inspeccione el contenido sin formato del blob confirmado con `git show

HEAD:test.raw`: curve ball well received {misfit} whatever #@#DELIM#@# proprietary format extinction {benefit}. #@#DELIM#@#

Después de cambiar los contenidos de test.raw a

curve ball welled repreived {misfit} whatever proprietary extinction format {benefit}.

La salida de git diff --patch-with-stat será probablemente lo que querías:

test.raw | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test.raw b/test.raw index b0b0b88..ed8c393 100644 --- a/test.raw +++ b/test.raw @@ -1,14 +1,14 @@ curve ball -well -received +welled +repreived {misfit} whatever #@#DELIM#@# proprietary -format extinction +format {benefit}. #@#DELIM#@#

Puede ver cómo esto funcionaría mágicamente para las combinaciones resultantes en la diferenciación y fusión palabra por palabra. QED

( Espero que te guste mi uso creativo de .gitattributes. Si no, disfruté haciendo este pequeño ejercicio )