¿Puedo hacer 'git diff' solo los números de línea Y los nombres de archivo modificados?


276

Esta pregunta requiere "números de línea", si no le importan los números de línea en la salida, vea esta pregunta y responda .


Básicamente, no quiero ver el contenido modificado, solo los nombres de archivo y los números de línea.


Tengo curiosidad, ¿son realmente útiles los números de línea sin código? ¿O quieres cambiar el número de líneas?
Andrew Marshall

bueno, no particularmente, pero lo necesito para marcar donde he cambiado mi código.
wei

1
Un uso de esto sería combinar la información con un informe de cobertura de código, para evaluar si el código nuevo o modificado en una confirmación está cubierto por pruebas
AntonyG

@AntonyG Encontré esta pregunta al intentar crear una utilidad que hace exactamente lo mismo (cobertura frente a líneas cambiadas). ¿Conseguiste construir el informe? Si es así, ¿lo publicaste en alguna parte?
Andrew Newdigate

@AndrewNewdigate sería una herramienta genial, pero nunca la construí. Estaba haciendo otro tipo de procesamiento de resultados de cobertura de código cuando me encontré con esta pregunta, pero no podía justificar el tiempo requerido para implementar mi sugerencia
AntonyG

Respuestas:


70

Nota: si solo está buscando los nombres de los archivos modificados ( sin los números de línea de las líneas que se modificaron), es fácil, haga clic en este enlace para obtener otra respuesta aquí .


No hay una opción integrada para esto (y tampoco creo que sea tan útil), pero es posible hacerlo en git, con la ayuda de un script "externo".

Aquí hay uno bastante malo; dependerá de usted arreglar la salida de la manera que le gustaría.

#! /bin/sh
#
# run this with:
#    GIT_EXTERNAL_DIFF=<name of script> git diff ...
#
case $# in
1) "unmerged file $@, can't show you line numbers"; exit 1;;
7) ;;
*) echo "I don't know what to do, help!"; exit 1;;
esac

path=$1
old_file=$2
old_hex=$3
old_mode=$4
new_file=$5
new_hex=$6
new_mode=$7

printf '%s: ' $path
diff $old_file $new_file | grep -v '^[<>-]'

Para obtener detalles sobre "diff externo", consulte la descripción GIT_EXTERNAL_DIFFen la página del manual de git (alrededor de la línea 700, muy cerca del final).


1
Gracias. De hecho, he escrito un guión similar, después de haber confirmado que no hay opciones integradas para esto, :)
wei

La canalización a | grep -o '^[0-9]*'le da solo números, suponiendo que no le importe el lado derecho.
GKFX

1
@DylanYoung sí; para limitar los archivos que se muestran, agregue --diff-filter=...donde la ...parte es el tipo de cambios que desea ver: Mpara modificado, Apara agregado, Dpara eliminado y otros según la git diffdocumentación.
torek

@Sventies: eso no es lo que solicitó el OP, como señalo en la parte superior de mi respuesta. No quiere solo los nombres de los archivos. Quiere los nombres con números de línea .
torek

Bastante justo @torek :)
Sventies

833

Tan fácil:

git diff --name-only

¡Sal y difunde!


88
Esta es la respuesta que la mayoría de las personas buscan cuando ven esta página (fue para mí). Sin embargo, no responde la pregunta original, que menciona específicamente los números de línea.
Pieter Müller

12
Esta NO debería ser la respuesta aceptada, ya que solo resuelve la mitad del problema: aún debe generar las líneas (para cada archivo) que se modificaron.
adamwong246

¡Eso es! ¡Estaba buscando este interruptor exactamente!
Adam Arold

¿Por qué no usar "git status"? También te dice los archivos no rastreados.
Naveen Paul

1
@JimmyPaul porque a veces ya te has comprometido. Por ejemplo, debe enumerar el archivo modificado entre el maestro y su sucursal avanzada actualgit diff --name-only master..HEAD
Hettomei

68

¿Números de línea como el número de líneas cambiadas o los números de línea reales que contienen los cambios? Si desea el número de líneas cambiadas, use git diff --stat. Esto te da una pantalla como esta:

[me@somehost:~/newsite:master]> git diff --stat
 whatever/views/gallery.py |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

No hay opción para obtener los números de línea de los cambios en sí.


1
Estaba pensando en los números de línea reales. Gracias sin embargo.
wei

De alguna manera dudo que quiera una herramienta GUI para esto.
ThiefMaster

31

git diff master --compact-summary

Salida es:

 src/app/components/common/sidebar/toolbar/toolbar.component.html   |  2 +-
 src/app/components/common/sidebar/toolbar/toolbar.component.scss   |  2 --

Esto es exactamente lo que necesitas. Mismo formato que cuando realiza commit o extrae nuevos commits desde remoto.

PD: Eso está conectado que nadie respondió de esta manera.


1
Eso no fue especificado. Funciona desde 2.18 lanzado hace un año.
Seitbekir Seidametov

Perfecto. Esto funcionó para mí y la respuesta es perfecta.
Victor

15

1) Mi favorito:

git diff --name-status

Antecede el estado del archivo, por ejemplo:

A   new_file.txt
M   modified_file.txt 
D   deleted_file.txt

2) Si quieres estadísticas, entonces:

git diff --stat

mostrará algo como:

new_file.txt         |  50 +
modified_file.txt    | 100 +-
deleted_file         |  40 -

3) Finalmente, si realmente solo quieres los nombres de archivo:

git diff --name-only

Simplemente mostrará:

new_file.txt
modified_file.txt
deleted_file

4

Muestra los nombres de archivo y la cantidad / nubmer de líneas que cambiaron en cada archivo entre ahora y la confirmación especificada:

git diff --stat <commit-hash>

2

Sé que esta es una pregunta antigua, pero en Windows, filtra la salida de git a los archivos y cambia los números de línea:

(git diff -p --stat) | findstr "@@ --git"

diff --git a/dir1/dir2/file.cpp b/dir1/dir2/file.cpp
@@ -47,6 +47,7 @@ <some function name>
@@ -97,7 +98,7 @@ <another functon name>

Para extraer los archivos y las líneas cambiadas de eso es un poco más trabajo:

for /f "tokens=3,4* delims=-+ " %f in ('^(git diff -p --stat .^) ^| findstr ^"@@ --git^"') do @echo %f

a/dir1/dir2/file.cpp
47,7
98,7

1

La salida más limpia, es decir, solo nombres / rutas de archivo, viene con

git diff-tree --no-commit-id --name-only -r

HTH


0

Encendido git version 2.17.1, no hay una bandera incorporada para lograr este propósito.

Aquí hay un comando de ejemplo para filtrar el nombre de archivo y los números de línea de un diff unificado:

git diff --unified=0 | grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? @@@)' | paste -s -d':'

Por ejemplo, el diff unificado:

$ git diff --unified=0
diff --cc foobar
index b436f31,df63c58..0000000
--- a/foobar
+++ b/foobar
@@@ -1,2 -1,2 +1,6 @@@ Line abov
++<<<<<<< HEAD
 +bar
++=======
+ foo
++>>>>>>> Commit message

Resultará en:

❯ git diff --unified=0 | grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? @@@)' | paste -s -d':'
foobar:1

Para hacer coincidir la salida de comandos en resultados comunes de coincidencia grep:

$ git diff --unified=0 | grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? )| @@@.*' | sed -e '0~3{s/ @@@[ ]\?//}' | sed '2~3 s/$/\n1/g' | sed "N;N;N;s/\n/:/g"
foobar:1:1:Line abov
  1. grep -Po '^diff --cc \K.*|^@@@( -[0-9]+,[0-9]+){2} \+\K[0-9]+(?=(,[0-9]+)? ): Coincide con el nombre de archivo de diff --cc <filename>OR coincide con el número de línea de @@@ <from-file-range> <from-file-range> <to-file-range>OR coincide con el texto restante después @@@.
  2. sed -e '0~3{s/ @@@[ ]\?//}': Eliminar @@@[ ]\?de cada 3a línea para obtener el contexto opcional de 1 línea antes ++<<<<<<< HEAD.
  3. sed '2~3 s/$/\n1/g': Agregue \n1cada 3 líneas entre la 2da y 3ra línea para el número de columna.
  4. sed "N;N;N;s/\n/:/g": Únete cada 3 líneas con a :.

0

Lo uso grepcomo una solución ingenua.

$ git diff | grep -A2 -- '---'

un ejemplo de salida:

--- a/fileA.txt
+++ b/fileA.txt
@@ -0,0 +1,132 @@
--
--- a/B/fileC.txt
+++ b/B/fileC.txt
@@ -33663,3 +33663,68800 @@ word_38077.png,Latin
--
--- a/D/fileE.txt
+++ b/D/fileE.txt
@@ -17998,3 +17998,84465 @@ word_23979.png,Latin
--
--- a/F
+++ b/F
@@ -1 +1 @@

Tal vez puedas ver una salida en color. Le ayuda a leer las salidas fácilmente.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.