Resalte las líneas cambiadas y los bytes cambiados en cada línea cambiada

94

El proyecto de código abierto Trac tiene un resaltador de diferencias excelente: ¡resalta las líneas cambiadas y los bytes cambiados en cada línea cambiada! Consulte aquí o aquí para ver ejemplos.

¿Hay alguna forma de utilizar el mismo color de resaltado (es decir, líneas cambiadas y bytes cambiados también ) en el terminal bash git, o vim para la salida diff (archivo de parche)?

Nikolay Frantsev
fuente
¿Qué es lo que quieres resaltar? ¿Quieres una herramienta de diferencias que resalte los cambios de bytes? (Eso sería muy util). Dice vim, que yo recuerde, vim ya hace mucha manipulación de color cuando está usando plantillas de lenguaje de programación (y otras). ¿Cómo cambiarías eso? Hay bastantes técnicas disponibles para cambiar el color en una ventana de terminal que se define como VT100 (y hay docenas de otras definiciones que también admitirán secuencias de escape de color). Más detalles por favor. O lea en.wikipedia.org/wiki/VT100 y los enlaces relacionados. Quizás eso pueda ayudar.
shellter
Sé que solo te interesan las herramientas de código abierto y solo la terminal. Pero solo como punto de referencia, es posible que desee ver el diffzilla de slickedit. de las pocas herramientas de diferencias que usé, siempre parece representar mejor las diferencias de caracteres (aunque definitivamente tuvo problemas cuando las diferencias eran complejas (combinación de cambios de formato y código, lo cual siempre es una mala idea)
nhed
Parece un duplicado de stackoverflow.com/questions/3231759/…
Adam Monsen
Nota: GitHub ahora ofrece una herramienta de diferencias de este tipo en su GUI web: stackoverflow.com/a/25723584/6309
VonC
He publicado 'otra' solución pura basada en git, diff-highlight con tutoriales para 1) encontrar fácilmente el archivo diff-highlight relevante, 2) hacerlo ejecutable 3) establecer los parámetros necesarios en .gitconfig. Por favor échale un vistazo. Las instrucciones son para Ubuntu 18.04 pero deberían funcionar ampliamente en sistemas Linux.
Zorglub29

Respuestas:

60

El diff-highlightscript contrib de Perl produce una salida tan similar a la de las capturas de pantalla de Trac que es probable que Trac la esté usando:

ingrese la descripción de la imagen aquí

Instalar con:

wget https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight && chmod +x diff-highlight

Mueva el archivo diff-highlightal ~/bin/directorio (o donde sea que $PATHesté) y luego agregue lo siguiente a su ~/.gitconfig:

[pager]
        diff = diff-highlight | less
        log = diff-highlight | less
        show = diff-highlight | less

Instalación de copia única y pegado sugerida por @cirosantilli:

cd ~/bin
curl -O https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight
chmod +x diff-highlight
git config --global pager.log 'diff-highlight | less'
git config --global pager.show 'diff-highlight | less'
git config --global pager.diff 'diff-highlight | less'
git config --global interactive.diffFilter diff-highlight
Sina Samavati
fuente
Esta. Esto es excelente. Gracias. Sin embargo, parece ser un poco conservador en algunos lugares, faltan algunas líneas que obviamente tienen la mayoría del texto en común. ¿Tiene un rastreador de errores para ello?
naught101
21
Ah, esto es parte del núcleo de git ahora: github.com/git/git/tree/master/contrib/diff-highlight
naught101
2
Ahora se ha convertido en un módulo, y creo que la versión más fácil de descargar es la que se encuentra inmediatamente antes de ese cambio en raw.githubusercontent.com/git/git/…
Chris Midgley
4
Esta no solo es parte del núcleo de git, se distribuye con git y probablemente ya esté en su sistema. Agregué detalles sobre cómo habilitarlo en mi respuesta a continuación. ↓
Cory Klein
2
Esto pierde las diferencias que ve a través de git add -p. Por favor, añada también:git config --global interactive.diffFilter diff-highlight
Josch
41

Mientras usa git diffo git logy posiblemente otros, use la opción --word-diff=color(también hay otros modos para diferencias de palabras por cierto)

anydot
fuente
2
--word-diff=colores realmente mejor (especialmente con git config color.diff.old "red reverse"y git config color.diff.new "green reverse"), pero no es lo que quiero :(
Nikolay Frantsev
4
Entonces, ¿lo único que le falta es marcar en color / de alguna manera cambiaron líneas y bytes al mismo tiempo?
anydot
7
Quiero resaltar las líneas cambiadas y los bytes cambiados en cada línea cambiada, como en Trac. No solo bytes cambiados, no es lo mismo.
Nikolay Frantsev
También puede usar esto con git add --patch: stackoverflow.com/questions/10873882/…
naught101
La ventaja de diff-highlightes que funciona bien tanto para diferencias de palabra como para diferencias de línea.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
21

diff-so-fancyes un diffiluminador diseñado para ojos humanos.

Elimina los principales +/ -que son molestos para cortar / pegar y deja secciones claras entre archivos.

Coloreado git(izquierda) vs diff-so-fancy(derecha - tenga en cuenta los aspectos destacados a nivel de personaje):

salida de diff-so-fancy

Si desea la diff-so-fancysalida (del lado derecho) pero no restringida a los archivos en un gitrepositorio, agregue la siguiente función .bashrcpara usarla en cualquier archivo:

dsf() { git diff --no-index --color "$@" | diff-so-fancy; }

P.ej:

dsf original changed-file

Resaltado de nivel de carácter y diffformato estándar

Si no le gusta el formato no estándar de diff-so-fancy, pero aún desea gitresaltar a nivel de carácter , use el diff-highlightque tomará gitla salida y producirá la salida de formato estándar realmente bonita diff:

captura de pantalla de diff-highlight

Para usarlo por defecto desde git, agregue a su .gitconfig:

[color "diff-highlight"]
  oldNormal = red bold
  oldHighlight = red bold 52
  newNormal = green bold
  newHighlight = green bold 22

[pager]
  diff = diff-highlight | less -FRXsu --tabs=4

La [pager]sección le dice gitque canalice su salida ya coloreada a diff-highlightqué colores a nivel de carácter, y luego pagina la salida en menos (si es necesario), en lugar de simplemente usar el valor predeterminado less.

Tom Hale
fuente
Esto es muy interesante, ¿podrías explicarnos un poco estas gitconfigopciones?
caesarsol
Actualizado, también agregando función dsf().
Tom Hale
15

El comportamiento que desea ahora está disponible en git (como se señaló en un comentario de naught101). Para habilitarlo, debe configurar su buscapersonas en

perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

¿Dónde /usr/share/doc/git/contrib/diff-highlight/diff-highlightestá la ubicación del script resaltador en Ubuntu 13.10 (no tengo idea de por qué está en una doccarpeta)? Si no está en su sistema, intente usarlo locate diff-highlightpara encontrarlo. Tenga en cuenta que el script de resaltado no es ejecutable (al menos en mi máquina), de ahí el requisito de perl.

Para usar siempre el resaltador para los diversos comandos tipo diff, simplemente agregue lo siguiente a su ~/.gitconfigarchivo:

[pager]
    log = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    show = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    diff = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

Agregué esto como una nueva respuesta, el comentario de naught101 está enterrado y porque la configuración no es tan trivial como debería ser y al menos en la versión de Ubuntu que tengo las instrucciones en el README no funcionan.

pastor
fuente
Acabo de notar que esto no habilita el resaltado de las diferencias dentro git add -p(modo interactivo). Sin embargo, no sé cómo se puede arreglar eso, simplemente agregar agregar a la lista hace que se cuelgue.
dshepherd
5
Esto debería funcionar ahora en git 2.9.0:git config interactive.diffFilter diff-highlight
Thomas
^ ¡Esto! Desafortunadamente, diff-highlightno estaba en mi camino, así que tuve que localizarlo primero. Detalles en mi respuesta a continuación.
Cory Klein
11

Se ha distribuido una utilidad para diferencias basadas en bytes con Git oficial desde v1.7.8 1 . Solo tiene que ubicar dónde está instalado en su máquina y habilitarlo.

Encuentra dónde está instalado Git

  • MacOS con Git instalado a través de Homebrew : es/usr/local/opt/git
  • Windows con Git para Windows : Ejecutar cd / && pwd -Wpara buscar el directorio de instalación.
  • Linux: Nerd. Si aún no sabe dónde está instalado Git, entonces ll $(which git)o locate gitdebería ayudarlo.

Enlace diff-highlighta su directorio bin para que su PATH pueda encontrarlo

GIT_HOME='/usr/local/opt/git/'  # Use the value from the first step.
ln -s "${GIT_HOME}/share/git-core/contrib/diff-highlight/diff-highlight" \
      '/usr/local/bin/diff-highlight'

Habilítelo en su configuración de Git

git config --global interactive.diffFilter diff-highlight # Use on interactive prompts
git config --global pager.diff "diff-highlight | less"    # Use on git diff
git config --global pager.log  "diff-highlight | less"    # Use on git log
git config --global pager.show "diff-highlight | less"    # Use on git show

1 Aquí está la versión v1.7.8 , pero se han realizado muchos cambios desde entonces.

Cory Klein
fuente
1
Sería bueno especificar en qué versión comenzó a distribuirse con git. También supongo que las distribuciones lo pondrán en PATH de forma predeterminada, por lo que el paso de enlace simbólico no será necesario. Y which gitrequiere que esté en el PATH en primer lugar, por lo que no funcionará si no lo es :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
¡Sería bueno! Siéntase libre de agregar esa información. Y aunque Git se incluye diff-highlight, en realidad no lo instala , por lo que el paso del enlace simbólico es realmente necesario (al menos en macOS). Si encuentra que no es necesario para su plataforma, nuevamente no dude en actualizar la respuesta. Mientras tanto, which gitpor lo general funciona, porque Git hace instalar el gitalguna parte binaria en el camino.
Cory Klein
Tenga en cuenta que en Debian Unstable necesitaba "compilar" este archivo, porque acababa de tener un .perl. La compilación es trivial: simplemente ejecútela sudo makeen el diff-highlightdirectorio.
tobiasBora
10

Yo uso la --color-wordsopción y funciona bien para mí:

$ git diff --color-words | less -RS
amized
fuente
5
No, esto solo muestra la diferencia en palabras. Lo que el OP (y yo) queremos es una diferencia normal línea por línea, con las diferencias de palabras resaltadas (por lo tanto, digamos que las diferentes líneas son texto de color, y las diferencias de palabras dentro de esas líneas son texto de color normal, con resaltado de color o alguna cosa). Vea los enlaces de ejemplo ahora en la pregunta.
naught101
1
pastebin.com/1JrhYHRt En realidad, uso vimdiff como difftool y vimdiff con molokai colorscheme para obtener un buen resaltado como lo describe en su pregunta. 1- git config --global diff.tool vimdiff 2- en vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Posible esquema de colores automático con ~ / .vimrc: if & diff set background = dark colorscheme molokai endif
amized
4

como dice @dshepherd :

El comportamiento que desea ahora está disponible en git.

Pero diff-highlightse encuentra en DOC y no está disponible en shell.
Para instalar diff-highlighten su ~/bindirectorio, siga los siguientes pasos (esto guardará su escritura):

$ locate diff-highlight
$ cd /usr/share/doc/git/contrib/diff-highlight  #or path you locate
$ sudo make
$ mv diff-highlight ~/bin

Luego configure su .gitconfigdocumento oficial como dice:

[pager]
    log  = diff-highlight | less
    show = diff-highlight | less
    diff = diff-highlight | less

UPD
También puede probar el siguiente en el último gitsin ninguna instalación:

git diff --color-words=.

Mas complejo:

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Eugen Konkov
fuente
1

Emacs tiene la función ediff-patch-buffer que debería satisfacer sus necesidades.

Abra el archivo sin parchear en emacs escriba ESC-x, ediff-patch-buffer.

Siga las indicaciones y debería ver una comparación resaltada de las versiones parcheadas y originales de su archivo.

Según su comentario, lo siguiente le dará una solución bash que solo requiere dwdiff:

#!/bin/bash
paste -d'\n' <(dwdiff -2 -L -c <(cat $2) <(patch $2 -i $1 -o -)) <(dwdiff -1 -L -c <(cat $2) <(patch $2 -i $1 -o -))| uniq
Finbar Crago
fuente
lo siento, no quiero usar emacs, solo bash, git o vim
Nikolay Frantsev
Eso es comprensible. La única otra cosa que se me ocurre es usar colordiff con la salida estándar del parche: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) pero esto solo resaltará las líneas cambiadas, no las mordidas ...
Finbar Crago
Pensé un poco más en su problema y agregué una segunda solución que solo requiere dwdiff.
Finbar Crago
1
por favor lea atentamente mi pregunta, no quiero comparar archivos
Nikolay Frantsev
1
disculpe la confusión, entonces, ¿está buscando una forma de resaltar los bytes modificados en las líneas modificadas de un archivo diff? si es así, intentedwdiff -c --diff-input diff_file
Finbar Crago
1

Difícil

GitLab está usando Diffy https://github.com/samg/diffy (Ruby) para lograr una salida similar a GitHub y diff-highlight:

ingrese la descripción de la imagen aquí

Diffy crea la diferencia usando el mismo algoritmo ad Git y admite diferentes tipos de resultados, incluida la salida HTML que usa GitLab:

gem install diffy
echo '
  require "diffy"    
  puts Diffy::Diff.new("a b c\n", "a B c\n").to_s(:html)
' | ruby

Salida:

<div class="diff">
  <ul>
    <li class="del"><del>a <strong>b</strong> c</del></li>
    <li class="ins"><ins>a <strong>B</strong> c</ins></li>
  </ul>
</div>

Observe cómo strongse agregó a los bytes modificados.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
0

Sí, Vim hace esto, incluido el resaltado del texto cambiado dentro de una línea.
Consulte :h diffy :h 08.7para obtener más detalles sobre cómo diferenciar archivos.

Vim utiliza un algoritmo bastante simple para resaltar. Busca en la línea el primer carácter cambiado y luego el último carácter cambiado, y simplemente resalta todos los caracteres entre ellos.
Esto significa que no puede tener varios aspectos destacados por línea; muchas decisiones de diseño en Vim priorizan la eficiencia.

PDug
fuente
desafortunadamente, no resalta los bytes cambiados en la salida diff (establecer filetype = diff)
Nikolay Frantsev
1
Creo que ahora entiendo su pregunta: desea resaltar la sintaxis de la salida textual del comando diff para que resalte los cambios realizados dentro de una línea. La edición de este texto en Vim resalta las diferencias de línea, pero no los cambios realizados dentro de una línea.
PDug
¿Podría usar el comando: patchfile de Vim para cargar el archivo original y luego compararlo con la versión parcheada?
PDug
desafortunadamente no, quiero usar la salida de diferencias recursivas para múltiples archivos
Nikolay Frantsev
0

vimdiff file1 file2 mostrará la diferencia de caracteres entre dos archivos.

vimdiff es una herramienta de diferencias incluida en vim. (Vim debería haber sido compilado con la opción + diff, para asegurarse de que pueda verificar :version)

También puede iniciarlo desde dentro de vim. Consulte :help diffpara obtener más información y comandos.

Xavier T.
fuente
No quiero comparar archivos, quiero resaltar el archivo diff (parche).
Nikolay Frantsev
@Nikolay Frantsev Si no le importa el rendimiento, puede instalar mi complemento format.vim y hacerlo vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX
Hará una diferencia en un modo por lotes (anteponer screen -D -mo agregar &>/dev/null(la variante / dev / null a veces produce errores extraños) si no desea ver el terminal parpadeando) y saldrá de vim después de que se complete el formateo, pero es puro vimscript y incluso con mis optimizaciones es muy lento para archivos grandes.
ZyX
0

Nota : esto es un duplicado de lo que se encuentra aquí: ¿Cómo mejorar el resaltado de diferencias de git? . Sin embargo, publicar mi respuesta aquí también, ya que puede ser útil para algunas personas que encuentran directamente este hilo :)

Como se dijo en algunas respuestas anteriores, esto es posible solo con cosas de git. Publico esto porque las instrucciones pueden ser un poco más fáciles de seguir dependiendo de su sistema, pero esto es similar a varias otras respuestas.

Una solución que se basa exclusivamente en git y sus contribuciones. Esto no requiere archivos adicionales a los que vienen con git . Todas las explicaciones son para Ubuntu (probado en 18.04LTS), deberían funcionar de manera similar en otros sistemas Linux:

  • Busque el fragmento de contribución de diff-highlight:
find -L /usr -name diff-highlight -type f

en mi sistema, la única respuesta válida es:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Haga que el script de perl correspondiente sea ejecutable. En mi caso necesitaba hacer:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Actualice su ~/.gitconfigpara obtener el resultado que desea, agregando (tenga en cuenta que estos son TABS, no 4 espacios):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Disfrute del resultado (nota: esto es solo para el color diferencial + resaltado, tengo otras cosas en juego aquí también para el aviso, por supuesto :)).

diff-highligh

Zorglub29
fuente