Suponiendo que tengo un archivo de texto
alex
bob
matrix
will be removed
git repo
y lo he actualizado para que sea
alex
new line here
another new line
bob
matrix
git
Aquí, agregué el número de línea (2,3) y el número de línea actualizado (6)
¿Cómo puedo obtener la información de estos números de línea usando git diff o cualquier otro comando git?
Aquí hay una función bash para calcular los números de línea resultantes de una diferencia:
diff-lines() { local path= local line= while read; do esc=$'\033' if [[ $REPLY =~ ---\ (a/)?.* ]]; then continue elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then path=${BASH_REMATCH[2]} elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then line=${BASH_REMATCH[2]} elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then echo "$path:$line:$REPLY" if [[ ${BASH_REMATCH[2]} != - ]]; then ((line++)) fi fi done }
Puede producir resultados como:
de una diferencia como esta:
Si solo desea mostrar líneas agregadas / eliminadas / modificadas, y no el contexto circundante, puede pasar
-U0
a git diff:Es robusto contra los códigos de color ANSI, por lo que puede pasar
--color=always
a git diff para obtener la codificación de color habitual para las líneas agregadas / eliminadas.La salida se puede grep fácilmente:
En tu caso
git diff -U0
daría:Si solo desea los números de línea, cambie
echo "$path:$line:$REPLY"
a justecho "$line"
y canalice la salidauniq
.fuente
git diff --color
no se transmiten. ¿O cree que sería mejor simplemente agregar los escapes de color al retorno de esta función?git diff --color | diff-lines
ahora funciona como se esperaba :)zsh: parse error near `]+m'
Alguna idea? El error proviene de esta línea:elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
Utilizo la
--unified=0
opción degit diff
.Por ejemplo,
git diff --unified=0 commit1 commit2
genera el diff:Debido a la
--unified=0
opción, la salida diff muestra 0 líneas de contexto; en otras palabras, muestra exactamente las líneas cambiadas .Ahora, puede identificar las líneas que comienzan con '@@' y analizarlas según el patrón:
@@ -startline1,count1 +startline2,count2 @@
Volviendo al ejemplo anterior, para el archivo WildcardBinding.java, comience desde la línea 910, se eliminan 0 líneas. Comience desde la línea 911, se agregan 4 líneas.
fuente
@@ -910,10,+911,15@@
Tuve este mismo problema, así que escribí un script gawk que cambia la salida de git diff para anteponer el número de línea para cada línea. A veces lo encuentro útil cuando necesito diferenciar el árbol de trabajo, aunque no se limita a eso. ¿Quizás sea útil para alguien aquí?
Puede descargarlo desde aquí:
https://github.com/jay/showlinenum
fuente
git diffn
para hacer esto también, y retiene completamente los colores de la terminal y muestra los números de línea tanto del archivo antiguo a la izquierda como del nuevo archivo a la derecha.Números de línea de todas las líneas no comprometidas (agregadas / modificadas):
Salida de ejemplo:
fuente
Configure una herramienta de diferenciación externa que le mostrará los números de línea. Por ejemplo, esto es lo que tengo en mi configuración global de git:
Consulte esta respuesta para obtener más detalles: https://stackoverflow.com/q/949242/526535
fuente
Aquí hay una función de bash que improvisé:
Y termina luciendo así:
fuente
Este es probablemente un recuento bastante preciso de líneas cambiadas:
Además, aquí hay una solución para los números de línea en su diff: https://github.com/jay/showlinenum
fuente
No es exactamente lo que estaba pidiendo, pero
git blame TEXTFILE
puede ayudar.fuente
Puede usar
git diff
junto con elshortstat
parámetro para mostrar simplemente el número de líneas cambiadas.Para el número de líneas cambiado (en un archivo que ya está en el repositorio) desde su última confirmación
Producirá algo similar a
fuente
Estaba buscando una forma de generar solo las líneas cambiadas para cada archivo usando git diff. Mi idea era enviar esta salida a un linter para la verificación de tipos. Esto es lo que me ayudó
fuente
Aquí hay algo de copia de Python para obtener los números de línea de las líneas modificadas / eliminadas, en caso de que se encuentre con esta pregunta buscando eso.
Debería ser bastante fácil modificarlo en algo que también obtenga los números de línea modificados y agregados.
Solo lo he probado en Windows, pero también debería ser multiplataforma.
import re import subprocess def main(file1: str, file2: str): diff = get_git_diff(file1, file2) print(edited_lines(diff)) def edited_lines(git_diff: str): ans = [] diff_lines = git_diff.split("\n") found_first = False # adjust for added lines adjust = 0 # how many lines since the start count = 0 for line in diff_lines: if found_first: count += 1 if line.startswith('-'): # minus one because count is 1 when we're looking at the start line ans.append(start + count - adjust - 1) continue if line.startswith('+'): adjust += 1 continue # get the start line match = re.fullmatch(r'@@ \-(\d+),\d+ \+\d+,\d+ @@', line) if match: start = int(match.group(1)) count = 0 adjust = 0 found_first = True return ans def get_git_diff(file1: str, file2: str): try: diff_process: subprocess.CompletedProcess = subprocess.run(['git', 'diff', '--no-index', '-u', file1, file2], shell=True, check=True, stdout=subprocess.PIPE) ans = diff_process.stdout # git may exit with 1 even though it worked except subprocess.CalledProcessError as e: if e.stdout and e.stderr is None: ans = e.stdout else: raise # remove carriage at the end of lines from Windows ans = ans.decode() ans.replace('\r', '') return ans if __name__ == "__main__": main("file1.txt", "file2.txt")
fuente