Cuando hago una git diff
o una git log -p
, ¿cómo obtengo los números de línea de los archivos de origen alineados con la salida?
Traté de buscarlo man git-diff | grep "line numbers"
e intenté buscar en Google, pero no obtuve nada rápidamente.
Cuando hago una git diff
o una git log -p
, ¿cómo obtengo los números de línea de los archivos de origen alineados con la salida?
Traté de buscarlo man git-diff | grep "line numbers"
e intenté buscar en Google, pero no obtuve nada rápidamente.
Respuestas:
git diff
Actualmente no hay opciones para que los números de línea se muestren verticalmente en el lado con git diff
.
Sin embargo, esa información está disponible en los encabezados de hunk (c) para cada cambio en la diferencia, solo está en formato de diferencia unificada :
@@ -start,count +start,count @@
El estado original del archivo se representa con -
y el nuevo estado se representa con +
(no significan adiciones y eliminaciones en el encabezado del trozo.representa start
el número de línea inicial de cada versión del archivo y count
representa cuántas líneas se incluyen , comenzando desde el punto de inicio.
diff --git a/osx/.gitconfig b/osx/.gitconfig
index 4fd8f04..fcd220c 100644
--- a/osx/.gitconfig
+++ b/osx/.gitconfig
@@ -11,7 +11,7 @@ <== HERE!
[color "branch"]
upstream = cyan
[color "diff"]
- meta = yellow
+ meta = cyan
plain = white dim
old = red bold
new = green bold
El encabezado del trozo
@@ -11,7 +11,7 @@
dice que la versión anterior del archivo comienza en la línea 11 e incluye 7 líneas:
11 [color "branch"]
12 upstream = cyan
13 [color "diff"]
14 - meta = yellow
14 + meta = cyan
15 plain = white dim
16 old = red bold
17 new = green bold
mientras que la siguiente versión del archivo también comienza en la línea 11 y también incluye 7 líneas.
Como probablemente pueda ver, el formato de diferencia unificada no facilita el cálculo de los números de línea (al menos si no es una máquina). Si realmente desea números de línea que pueda leer, necesitará usar una herramienta de diferenciación que los muestre.
--unified=0
o -U0
.
git diffn
, un reemplazo directo (envoltorio) para el git diff
que muestra los números de línea y tiene total compatibilidad con todos los usos y opciones de git diff
: stackoverflow.com/questions/24455377/…
Aquí hay dos soluciones más, ampliando el código de Andy Talkowski.
Texto sin formato:
git diff | gawk 'match($0,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
/^(---|\+\+\+|[^-+ ])/{print;next};\
{line=substr($0,2)};\
/^-/{print "-" left++ ":" line;next};\
/^[+]/{print "+" right++ ":" line;next};\
{print "(" left++ "," right++ "):"line}'
Texto en color, asumiendo que \033[66m
es el formato de los códigos de color:
git diff --color=always | \
gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
{line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
bare~/^-/{print "-"left++ ":" line;next};\
bare~/^[+]/{print "+"right++ ":" line;next};\
{print "("left++","right++"):"line;next}'
El código cambia líneas que comienzan con -
y +
a -1:-
y +1:+
, respectivamente, y las líneas que comienzan con nada a
(5,6):
. Los números son los números de línea del archivo respectivo.
git diff
mantiene cuidadosamente la alineación. Este código está sobre mi cabeza en este momento, así que ¿estaría dispuesto a arreglarlo? En otras palabras, cuando una línea dice +240:+
y la siguiente línea dice (241,257):
, debe agregar algunos espacios adicionales a la línea superior para que su código mantenga la alineación y sangría adecuadas con el código de la línea inferior. ¿Quizás esto podría hacerse fácilmente con la impresión?
printf
.
git diffn
. Vea aquí: stackoverflow.com/a/61997003/4561887 . Gracias @PFudd, por tu respuesta. Lo estudié y lo usé para aprender, luego comencé desde cero y escribí git diffn
. Una vez formateado para poder leer su código (gracias @EdMorton), pude aprender algunas cosas geniales que me ayudaron.
Aquí hay un script que intenta solucionar este problema, no lo probé con ira, pero parece estar bien. Se basa en los registros que produce git diff y usa awk para mantener el recuento de líneas.
# Massage the @@ counts so they are usable
function prep1() {
cat | awk -F',' 'BEGIN { convert = 0; }
/^@@ / { convert=1; }
/^/ { if ( convert == 1 ) { print $1,$2,$3;
} else { print $0;
}
convert=0;
}'
}
# Extract all new changes added with the line count
function prep2() {
cat | awk 'BEGIN { display=0; line=0; left=0; out=1;}
/^@@ / { out=0; inc=0; line=$4; line--; display=line; left=line; }
/^[-]/ { left++; display=left; inc=0; }
/^[+]/ { line++; display=line; inc=0; }
/^[-+][-+][-+] / { out=0; inc=0; }
/^/ {
line += inc;
left += inc;
display += inc;
if ( out == 1 ) {
print display,$0;
} else {
print $0;
}
out = 1;
inc = 1;
display = line;
}'
}
git diff $1 | prep1 | prep2
Puede utilizar git difftool
para hacer la diferencia con un editor externo que mostrará los números de línea. He aquí cómo hacerlo con vim / vimdiff:
Establecer vimdiff como difftool de git:
git config --global diff.tool vimdiff
Configure ~/.vimrc
para mostrar automáticamente los números de línea al usar vimdiff:
if &diff
set number
endif
Ejecute git difftool, que usará vimdiff con números de línea:
git difftool
Una forma rápida es usar git diff -U0
. Eso establecerá las líneas de contexto en 0, lo que hará que los valores @@ coincidan con las líneas cambiadas reales. De forma predeterminada, los valores @@ incluyen 3 líneas de contexto antes / después, lo que no es conveniente para los humanos.
Ejemplo:
git diff # default
@@ -10,8 +10,8 @@
Es difícil calcular los números de línea de las líneas cambiadas porque la línea 10 se refiere a la primera línea del contexto anterior. El número de línea real de la primera línea modificada es 10 + 3 = 13. Para calcular el número de líneas cambiadas, también debe restar el contexto antes y después: 8-3-3 = 2.
git diff -U0
@@ -13,2 +13,2 @@
Como puede ver, establecer context = 0 hace que los valores @@ sean más fáciles de leer para los humanos. Puede ver que las líneas cambiadas comienzan en la línea 13 y hay 2 líneas cambiadas.
Esto no es perfecto, ya que solo muestra el número de línea de cada bloque. Si desea ver los números de línea para cada línea, utilice difftool para un editor externo. Ver https://stackoverflow.com/a/50049752
Me gusta usar git difftool
con MELD como mi difftool. Es más fácil de ver que git diff
, tiene una buena comparación de interfaz gráfica de usuario y muestra los números de línea en cada lado.
Acabo de escribir git diffn
durante los últimos días para ser un reemplazo git diff
directo de la línea de comandos. Dale un tiro. Vea mi otra respuesta aquí .
A partir del 24 de mayo de 2020, ahora puede usar la herramienta de terceros git diffn
(divulgación completa: la escribí) para este propósito. Es un envoltorio ligero git diff
, escrito en el awk
lenguaje de programación basado en patrones / acciones. Aquí hay una salida de muestra de la ejecución git diffn
:
Desde lo alto degit-diffn.sh
:
DESCRIPCIÓN:
git-diffn.sh
¡un reemplazo git diff
directo para el que también muestra números de línea! Úselo exactamente igual git diff
, excepto que verá estos hermosos números de línea también para ayudarlo a entender sus cambios.
ya que es solo un contenedor ligero basado en el lenguaje awk git diff
, acepta TODAS las opciones y parámetros que git diff
acepta. Ejemplos:
git diffn HEAD~
git diffn HEAD~3..HEAD~2
funciona con cualquiera de sus git diff
configuraciones de color, incluso si está utilizando colores personalizados
Vea mi respuesta aquí para saber cómo configurar colores de diferencia personalizados, así como para ver una captura de pantalla de la salida de color personalizado de git diffn
: ¿Cómo se personaliza el color del encabezado de diferencias en git diff?
Aquí hay algunos git config
comandos de muestra de mi respuesta anterior para establecer git diff
colores y atributos personalizados (formato de texto):
git config --global color.diff.meta "blue"
git config --global color.diff.old "black red strike"
git config --global color.diff.new "black green italic"
git config --global color.diff.context "yellow bold"
adentro git diffn
, la salida de color está activada de forma predeterminada; si desea deshabilitar el color de salida, debe usar --no-color
o --color=never
. Consulte man git diff
para obtener más detalles. Ejemplos:
git diffn --color=never HEAD~
git diffn --no-color HEAD~3..HEAD~2
gawk
. Si es así, trate de esta : brew install gawk
.Opción 1 (mi recomendación): descargue el repositorio completo y luego cree un enlace simbólico al programa para que pueda recibir actualizaciones fácilmente haciendo una git pull
desde el repositorio cuando lo desee.
Primero, cd
a donde quieras instalar esto. Entonces corre:
git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.git
cd eRCaGuy_dotfiles/useful_scripts
mkdir -p ~/bin
ln -si "${PWD}/git-diffn.sh" ~/bin/git-diffn
¡Hecho! ¡Ahora solo haz el paso final a continuación!
Opción 2 (para aquellos que solo quieren el archivo 1): descargue solo el archivo una vez.
mkdir -p ~/bin
cd ~/bin
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/git-diffn.sh
chmod +x git-diffn.sh
mv git-diffn.sh git-diffn
¡Hecho! ¡Ahora solo haz el paso final a continuación!
Último paso:
Ahora cierre y vuelva a abrir su terminal, o recárguelo con . ~/.bashrc
, ¡y listo!
git diffn
ahora funcionará como un reemplazo directo exacto de git diff
!
Aquí hay una demostración:
git diffn
:Crea este archivo:
hello_world.c:
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
Comprométase:
git add hello_world.c
git commit -m "add hello_world.c"
Cámbielo a esto y guarde el archivo:
hello_world.c:
// Basic hello world example
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello Gabriel\n");
int i = 700;
printf("i = %i\n", i);
return 0;
}
Ahora ejecuta:
git diff
Aquí está el resultado de git diff
first para fines de comparación:
$ git diff
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+// Basic hello world example
+
#include <stdio.h>
-int main()
+int main(int argc, char *argv[])
{
- printf("Hello World\n");
-
+ printf("Hello Gabriel\n");
+
+ int i = 700;
+ printf("i = %i\n", i);
return 0;
-}
\ No newline at end of file
+}
Y una captura de pantalla para mostrar el color. Tenga en cuenta que la sección resaltada en rojo simplemente muestra espacios en blanco vacíos (espacios en este caso) que podrían eliminarse:
Ahora aquí está la salida de git diffn
. ¡Observe que muestra todos los números de línea perfectamente!
-
signo tanto en el extremo izquierdo como en el derecho del :
para ayudarlo a ver mejor, ya sea que a sus ojos les guste escanear hacia la derecha del colon o hacia abajo en el extremo a la izquierda de la pantalla.+
signo tanto a la izquierda como a la derecha del :
.,
.Salida de git diffn
:
$ git diffn
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+ 1:+// Basic hello world example
+ 2:+
1, 3: #include <stdio.h>
2, 4:
- 3 :-int main()
+ 5:+int main(int argc, char *argv[])
4, 6: {
- 5 :- printf("Hello World\n");
- 6 :-
+ 7:+ printf("Hello Gabriel\n");
+ 8:+
+ 9:+ int i = 700;
+ 10:+ printf("i = %i\n", i);
7, 11: return 0;
- 8 :-}
\ No newline at end of file
+ 12:+}
Y una captura de pantalla para mostrar el color. Tenga en cuenta que los dos puntos NO están coloreados ni estilizados para que coincidan con el texto circundante a la izquierda y a la derecha. Este es un comportamiento intencional y diseñado para actuar como un separador visual entre los números de línea agregados a la izquierda y la git diff
salida original a la derecha.
Puedes probar
git blame
en el archivo. Le muestra el confirmador, la identificación del compromiso y el número de línea para cada línea en el archivo.
git blame
solo mostrará el estado actual del archivo con números de línea.
git blame
de ninguna manera responde la pregunta; Estoy bastante desconcertado por los votos a favor aquí
git diff --unified=0 | grep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'