Ver el historial de cambios de un archivo usando versiones de Git

3091

¿Cómo puedo ver el historial de cambios de un archivo individual en Git, detalles completos con lo que ha cambiado?

He llegado tan lejos como:

git log -- [filename]

que me muestra el historial de confirmación del archivo, pero ¿cómo obtengo el contenido de cada uno de los cambios del archivo?

Estoy tratando de hacer la transición desde MS SourceSafe y eso solía ser un simple right-clickshow history.

Ricardo
fuente
41
El enlace de arriba ya no es válido. Este enlace funciona hoy: Git Community Book
chris
1
El enlace de arriba (publicado por Chris) ya no es válido. Este enlace funciona hoy: git-scm.com/book/en/v2
Cog

Respuestas:

2369

Para esto usaría:

gitk [filename]

o para seguir el nombre del archivo renombrados anteriores

gitk --follow [filename]
Claudio Acciaresi
fuente
28
Pero incluso prefiero tener una herramienta que combina lo anterior con 'git blame' que me permite explorar la fuente de un archivo a medida que cambia a tiempo ...
Egon Willighagen
26
Desafortunadamente, esto no sigue el historial de los renombrados anteriores del archivo.
Dan Molding
146
También estaba buscando el historial de los archivos que anteriormente fueron renombrados y encontré este hilo primero. La solución es usar "git log --follow <filename>" como Phil señaló aquí .
Florian Gutmann
115
El autor estaba buscando una herramienta de línea de comando. Si bien gitk viene con GIT, no es una aplicación de línea de comandos ni una GUI particularmente buena.
mikemaccana
72
¿Estaba buscando una herramienta de línea de comandos? "clic derecho -> mostrar historial" ciertamente no lo implica.
hdgarrood
2236

Puedes usar

git log -p filename

para permitir que git genere los parches para cada entrada de registro.

Ver

git help log

para obtener más opciones, en realidad puede hacer muchas cosas buenas :) Para obtener solo la diferencia para un compromiso específico, puede

git show HEAD 

o cualquier otra revisión por identificador. O usar

gitk

para navegar los cambios visualmente.

VolkA
fuente
8
git show HEAD muestra todos los archivos, ¿sabe cómo rastrear un archivo individual (como Richard estaba pidiendo)?
Jonas Byström
55
usted usa: git show <revision> - nombre de archivo, que mostrará las diferencias para esa revisión, en caso de que exista una.
Marcos Oliveira
44
--stat también es útil. Puedes usarlo junto con -p.
Raffi Khatchadourian
55
Esto es genial. gitk no se comporta bien al especificar rutas que ya no existen. Usé git log -p - ruta.
Paulo Casaretto
66
Además, parece que Gitk fue construido por el monstruo del boogie. Esta es una gran respuesta y se adapta mejor a la pregunta original.
ghayes
1499

git log --follow -p -- path-to-file

Esto mostrará el historial completo del archivo (incluido el historial más allá de los cambios de nombre y con diferencias para cada cambio).

En otras palabras, si el archivo nombrado baralguna vez fue nombrado foo, entonces git log -p bar(sin la --followopción) solo mostrará el historial del archivo hasta el punto en el que fue renombrado; no mostrará el historial del archivo cuando se conocía como foo. El uso git log --follow -p barmostrará el historial completo del archivo, incluidos los cambios en el archivo cuando se conocía como foo. La -popción garantiza que se incluyan diferencias para cada cambio.

Dan Molding
fuente
18
--stat también es útil. Puedes usarlo junto con -p.
Raffi Khatchadourian
23
Estoy de acuerdo en que esta es la respuesta REAL. (1.) --followasegura que veas el cambio de nombre de los archivos (2.) -pasegura que veas cómo se cambia el archivo (3.) es solo la línea de comandos.
Trevor Boyd Smith
3
@NHDaly Noto que --se agregó, pero no sé por qué esto lo hace mejor. ¿Qué es lo que hace?
Benjohn
40
@Benjohn La --opción le dice a Git que ha llegado al final de las opciones y que todo lo que sigue --debe tratarse como un argumento. Para git logesto sólo se hace ninguna diferencia si usted tiene un nombre de ruta que comienza con un guión . Digamos que quiere saber la historia de un archivo que tiene el desafortunado nombre "--follow":git log --follow -p -- --follow
Dan Molding
10
@Benjohn: Normalmente, --es útil porque también puede proteger contra cualquier revisionnombre que coincida con el nombre de archivo que ha ingresado, lo que en realidad puede dar miedo. Por ejemplo: si tuviera una rama y un archivo con nombre foo, git log -p foomostraría el historial de registro de git hasta foo, no el historial del archivo foo . Pero @DanMoulding tiene razón en que, dado que el --followcomando solo toma un solo nombre de archivo como argumento, esto es menos necesario ya que no puede ser un revision. Acabo de enterarme de eso. Tal vez tenías razón al dejarlo fuera de tu respuesta entonces; No estoy seguro.
NHDaly
172

Si prefiere permanecer basado en texto, puede usar tig .

Instalación rápida:

  • apt-get :# apt-get install tig
  • Homebrew (OS X) :$ brew install tig

Úselo para ver el historial en un solo archivo: tig [filename]
O explore el historial detallado de repositorios:tig

Similar a gitkpero basado en texto. Soporta colores en terminal!

Falken
fuente
23
Excelente herramienta basada en texto, excelente respuesta. Me asusté cuando vi las dependencias para la instalación de gitk en mi servidor sin cabeza. Votaría de nuevo A +++
Tom McKenzie
También puede ver archivos específicos con tig, es decirtig -- path/to/specific/file
glorifobia
110

git whatchanged -p filenameTambién es equivalente a git log -p filenameen este caso.

También puede ver cuándo se cambió una línea de código específica dentro de un archivo git blame filename. Esto imprimirá un ID de confirmación breve, el autor, la marca de tiempo y la línea de código completa para cada línea del archivo. Esto es muy útil después de que hayas encontrado un error y quieras saber cuándo se introdujo (o quién tiene la culpa).

farktronix
fuente
44
+1, pero filenameno es opcional en el comando git blame filename.
rockXrock
77
"Se alienta a los nuevos usuarios a usar git-log en su lugar. (...) El comando se mantiene principalmente por razones históricas".
ciastek
105

Usuarios de SourceTree

Si usa SourceTree para visualizar su repositorio (es gratis y bastante bueno) puede hacer clic derecho en un archivo y seleccionar Log Selected

ingrese la descripción de la imagen aquí

La pantalla (a continuación) es mucho más amigable que gitk y la mayoría de las otras opciones enumeradas. Desafortunadamente (en este momento) no hay una manera fácil de iniciar esta vista desde la línea de comandos: la CLI de SourceTree actualmente solo abre repositorios.

ingrese la descripción de la imagen aquí

Mark Fox
fuente
1
Me gusta especialmente la opción "Seguir archivos renombrados", que le permite ver si un archivo fue renombrado o movido.
Chris
pero a menos que me equivoque (¡hágamelo saber!), ¿solo se pueden comparar dos versiones a la vez en la interfaz gráfica de usuario? ¿Hay clientes que tengan una interfaz elegante para diferenciar varias versiones diferentes a la vez? Posiblemente con una vista de alejamiento como en Sublime Text? Eso sería realmente útil, creo.
Sam Lewallen
@SamLewallen Si entiendo correctamente, ¿quieres comparar tres confirmaciones diferentes? Esto suena similar a una fusión de tres vías (mía, tuya, base): por lo general, esta estrategia se utiliza para resolver conflictos de fusión que no necesariamente comparan tres confirmaciones arbitrarias. Hay muchas herramientas que admiten combinaciones de tres vías stackoverflow.com/questions/10998728/…, pero el truco consiste en proporcionar a estas herramientas las revisiones específicas gitready.com/intermediate/2009/02/27/…
Mark Fox
Gracias Mark Fox, a eso me refiero. ¿Conoces alguna aplicación que haga eso?
Sam Lewallen
1
@ MarnenLaibow-Koser No recuerdo por qué necesito el SHA en ese momento. Jajaja
AechoLiu
63

Para mostrar qué revisión y autor modificaron por última vez cada línea de un archivo:

git blame filename

o si quieres usar la poderosa GUI de culpa:

git gui blame filename
yllohy
fuente
49

Resumen de otras respuestas después de leerlas y jugar un poco:

El comando de línea de comando habitual sería

git log --follow --all -p dir/file.c

Pero también puede usar gitk (gui) o tig (text-ui) para obtener formas mucho más legibles para los humanos de verlo.

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

En debian / ubuntu, el comando de instalación para estas herramientas encantadoras es el esperado:

sudo apt-get install gitk tig

Y actualmente estoy usando:

alias gdf='gitk --follow --all -p'

para que pueda escribir gdf dirpara obtener un historial enfocado de todo en el subdirectorio dir.

John Lawrence Aspden
fuente
2
Creo que esta es una gran respuesta. Tal vez no lo voten también porque responde de otras maneras (en mi humilde opinión, mejor) para ver los cambios, es decir, a través de gitk y tig, además de git.
PopcornKing
Solo para agregar a la respuesta. Localice la ruta (en el espacio git, hasta el que todavía existe en el repositorio). Luego use el comando indicado anteriormente "git log --follow --all -p <folder_path / file_path>". Puede darse el caso de que la carpeta / filde se haya eliminado durante el historial, por lo tanto, ubique la ruta máxima que todavía existe e intente recuperar su historial. trabajos !
parasrish
2
--alles para todas las ramas, el resto se explica en la respuesta de @ Dan
cregox
1
Oh hombre, después de tanto tiempo buscando una buena solución para rastrear el archivo más allá de los renombrados, finalmente, lo encontré aquí. Funciona como encanto! ¡Gracias!
xZero
25

Agregue este alias a su .gitconfig:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

Y usa el comando así:

> git lg
> git lg -- filename

La salida se verá casi exactamente igual a la salida de gitk. Disfrutar.

Palesz
fuente
Después de ejecutar ese atajo lg, dije (y cito) "¡Hermoso!". Sin embargo, tenga en cuenta que "\ n" después de "--graph" es un error.
jmbeck
3
También se puede usar git lg -p filename: devuelve una hermosa diferencia de archivo buscado.
Egel
22

Últimamente descubrí tig y lo encontré muy útil. Hay algunos casos que desearía que hiciera A o B, pero la mayoría de las veces es bastante ordenado.

Para su caso, tig <filename>podría ser lo que está buscando.

http://jonas.nitro.dk/tig/

lang2
fuente
en centos yum install tig
zzapper
18

Puedes usar vscode con GitLens , es una herramienta muy poderosa. Después de instalar GitLens, vaya a la pestaña GitLens, seleccione FILE HISTORYy podrá explorarlo.

ingrese la descripción de la imagen aquí

Foxiris
fuente
15

Escribí git-play para este propósito exacto

pip install git-playback
git playback [filename]

Esto tiene la ventaja de que ambos muestran los resultados en la línea de comando (me gusta git log -p) y al mismo tiempo le permiten recorrer cada confirmación utilizando las teclas de flecha (me gusta gitk).

Jian
fuente
13

O:

gitx -- <path/to/filename>

si estás usando gitx

George Anderson
fuente
1
Por alguna razón, mi gitx se abre en blanco.
IgorGanapolsky
@IgorGanapolsky debes asegurarte de estar en la raíz de tu repositorio git
zdsbs
10

También puede probar esto, que enumera las confirmaciones que han cambiado una parte específica de un archivo (Implementado en Git 1.8.4).

El resultado devuelto sería la lista de confirmaciones que modificaron esta parte en particular. Comando:

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

donde upperLimit es el número_línea_inicial y el Límite inferior es el número_línea_final del archivo.

Más detalles en https://www.techpurohit.com/list-some-useful-git-commands

jitendrapurohit
fuente
9

Si desea ver el historial completo de un archivo, incluso en todas las demás ramas, use:

gitk --all <filename>
Adi Shavit
fuente
7

Con las excelentes extensiones de Git , vas a un punto en el historial donde el archivo todavía existía (si se ha eliminado, de lo contrario solo ve a HEAD), cambia a la File treepestaña, haz clic derecho en el archivo y elige File history.

Por defecto, sigue el archivo a través de los cambios de nombre, y la Blamepestaña permite ver el nombre en una revisión dada.

Tiene algunos problemas menores, como mostrar fatal: Not a valid object nameen la Viewpestaña al hacer clic en la revisión de eliminación, pero puedo vivir con eso. :-)

PhiLho
fuente
Vale la pena señalar que esto es solo para Windows.
Evan Hahn
3
@EvanHahn no es exacto, a través de mono uno puede usar GitExtension también en Linux, lo usamos en ubuntu y muy contento con él. ver git-extensions-documentation.readthedocs.org/en/latest/…
Shmil The Cat
7

Si está utilizando la GUI de git (en Windows) en el menú Repositorio, puede usar "Visualizar el historial del maestro". Resalte una confirmación en el panel superior y un archivo en la esquina inferior derecha y verá la diferencia de esa confirmación en la esquina inferior izquierda.

cori
fuente
¿Cómo responde esto a la pregunta?
jmbeck
3
Bueno, OP no especificó la línea de comando, y al pasar de SourceSafe (que es una GUI) me pareció relevante señalar que podría hacer casi lo mismo que puede hacer en VSS en la GUI de Git en Windows.
cori
6

SmartGit :

  1. En el menú, habilite mostrar archivos sin cambios: Ver / Mostrar archivos sin cambios
  2. Haga clic derecho en el archivo y seleccione 'Log' o presione 'Ctrl-L'
Antonín Slejška
fuente
4

La respuesta que estaba buscando que no estaba en este hilo es ver cambios en los archivos que había preparado para confirmar. es decir

git diff --cached
Malks
fuente
1
Si desea incluir cambios locales (sin etapas), a menudo corro git diff origin/masterpara mostrar las diferencias completas entre su sucursal local y la sucursal maestra (que se puede actualizar desde la remota git fetch)
ghayes
4

Si usa TortoiseGit, debería poder hacer clic derecho en el archivo y hacerlo TortoiseGit --> Show Log. En la ventana que aparece, asegúrese de:

  • ' Show Whole Project' la opción no está marcada.

  • ' All Branches' la opción está marcada.

usuario3885927
fuente
TortoiseGit (y Eclipse Git también) de alguna manera pierde las revisiones del archivo seleccionado, ¡no cuente con ello!
Noam Manos
@NoamManos, no he encontrado ese problema, por lo que no puedo verificar si su declaración es correcta.
user3885927
Mi error, solo ocurre en Eclipse, pero en TortoiseGit puede ver todas las revisiones de un archivo si desmarca "mostrar todo el proyecto" + marcar "todas las ramas" (en caso de que el archivo se confirmara en otra rama, antes de fusionarse con main rama). Actualizaré tu respuesta.
Noam Manos
3

git diff -U <filename> darte una diferencia unificada.

Debe ser de color rojo y verde. Si no es así, ejecute: git config color.ui autoprimero.

Lukasz Czerwinski
fuente
2

Si está utilizando eclipse con el complemento git, tiene una excelente vista de comparación con el historial. Haga clic derecho en el archivo y seleccione "comparar con" => "historial"

AhHatem
fuente
Sin embargo, eso no le permitirá encontrar un archivo eliminado.
avgvstvs
Comparar dos versiones de un archivo es diferente a Ver el historial de cambios de un archivo
golimar
0

Probablemente esté sobre dónde estaba el OP cuando esto comenzó, buscando algo simple que me permitiera usar git difftool con vimdiff para revisar los cambios en los archivos en mi repositorio a partir de una confirmación específica. No estaba muy contento con las respuestas que estaba encontrando, así que elaboré este script de git inc remental rep orter (gitincrep) y me ha sido útil:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

Llamado sin argumentos, esto comenzará desde el comienzo del historial de repositorios, de lo contrario comenzará con cualquier hash abreviado de confirmación que proporcione y proceda al presente: puede presionar Ctrl-C en cualquier momento para salir. Cualquier argumento después del primero limitará los informes de diferencias para incluir solo los archivos enumerados entre esos argumentos (lo que creo que es lo que quería el OP, y lo recomendaría para todos menos los proyectos pequeños). Si está verificando cambios en archivos específicos y desea comenzar desde el principio, deberá proporcionar una cadena vacía para arg1. Si no eres un usuario de vim, puedes reemplazar vimdiff con tu herramienta de diferencias favorita.

El comportamiento es generar los comentarios de confirmación cuando se encuentran cambios relevantes y comenzar a ofrecer ejecuciones de vimdiff para cada archivo modificado (ese es el comportamiento de git difftool , pero funciona aquí).

Este enfoque es probablemente bastante ingenuo, pero al examinar muchas de las soluciones aquí y en una publicación relacionada, muchas implicaron instalar nuevas herramientas en un sistema donde no tengo acceso de administrador, con interfaces que tenían su propia curva de aprendizaje. El script anterior hizo lo que quería sin tener que lidiar con nada de eso. Examinaré las muchas sugerencias excelentes aquí cuando necesite algo más sofisticado, pero creo que esto responde directamente al OP.

oracleif
fuente
0

He encontrado una solución muy simple para encontrar rápidamente el historial del archivo.

  1. Hacer un cambio aleatorio en el archivo
  2. Se mostrará como cambios no confirmados en su árbol de origen
  3. Haga clic derecho en el archivo y seleccione 'Log Selected'

ingrese la descripción de la imagen aquí

Mostraría la historia de todos los commits.

savvyBrar
fuente
¿De dónde viene esta GUI?
colidyre
Sourcetree UI. Gracias
savvyBrar