¿Hay un comando rápido de Git para ver una versión anterior de un archivo?

1511

¿Hay un comando en Git para ver (ya sea volcado a stdout, o en $PAGERo $EDITOR) una versión particular de un archivo en particular?

Miguel
fuente
Si llegaste a esta pregunta porque quieres verificar una versión anterior de un archivo binario (por ejemplo, una imagen), entonces es mejor hacer un pago al antiguo commit, ver lo que necesitas ver y luego volver al HEAD. Para eso, haz git checkout <sha1-of-the-commit-you-need>, después,git checkout HEAD
Homero Esmeraldo

Respuestas:

1732

Puede usar git showcon una ruta desde la raíz del repositorio ( ./o ../para una ruta relativa):

$ git show REVISION:path/to/file

Reemplace REVISIONcon su revisión real (podría ser un SHA de confirmación de Git, un nombre de etiqueta, un nombre de sucursal, un nombre de confirmación relativo o cualquier otra forma de identificar una confirmación en Git)

Por ejemplo, para ver la versión del archivo <repository-root>/src/main.cde hace 4 commits, use:

$ git show HEAD~4:src/main.c

Git para Windows requiere barras diagonales incluso en las rutas relativas al directorio actual. Para obtener más información, consulte la página de manual de git-show.

mipadi
fuente
55
Eso en realidad no parece funcionar, ¿lo intentaste? Para "git show HEAD: path / to / file.c", aparece un error de "argumento ambiguo".
Mike
2
Tiene que ser el camino completo, desde la parte superior del repositorio de git
richq
20
Si está en Windows, podría ser un separador de ruta; si hago git show HEAD: dir \ subdir \ file, obtengo el argumento aniguo. Si hago git show HEAD: dir / subdir / file, funciona como se esperaba.
Matt McMinn
12
La ruta que debe proporcionar después de: es desde la raíz del repositorio git. (esto se dio a continuación como respuesta, pero creo que fue un comentario sobre esta respuesta)
MatrixFrog
99
Si desea verlo en una división de Vim para que se desplacen juntos, escribí una breve publicación de blog que muestra cómo hacerlo.
Flaviu
257

Hacer esto por fecha se ve así:

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt

Tenga en cuenta que HEAD@{2013-02-25}significa "dónde estaba HEAD el 25/02/2013" en este repositorio (usando el registro ), no "la última confirmación antes del 25/02/2013 en esta rama en la historia".

Jim Hunziker
fuente
55
Increíble. Ahorro mucho tiempo en lugar de ir a github y mirar el commit.
Fizer Khan
El "punto" en la ruta del archivo fue mi problema. ¡Gracias!
tomascharad
55
Este comando es útil en masterlugar de HEAD@{2013-02-25}, si estás en una rama
funroll el
1
¿Puedes incluir el tiempo, à la git log --since='2016-04-28 23:59:59 +0100'?
dumbledad
77
El hecho de que esta sintaxis use el registro de referencias es importante y debe resaltarse fuertemente, porque el registro de registros no contiene todas las confirmaciones . Ver blog.endpoint.com/2014/05/git-checkout-at-specific-date.html
Alice Heaton
113

Si te gustan las GUI, puedes usar gitk:

  1. comenzar gitk con:

    gitk /path/to/file
    
  2. Elija la revisión en la parte superior de la pantalla, por ejemplo, por descripción o fecha. Por defecto, la parte inferior de la pantalla muestra la diferencia para esa revisión (correspondiente al botón de opción "parche").

  3. Para ver el archivo de la revisión seleccionada:

    • Haga clic en el botón de radio "árbol". Esto mostrará la raíz del árbol de archivos en esa revisión.
    • Profundice en su archivo.
Trausti Kristjansson
fuente
77
Esto también funciona con tig , que es un visor de git repo curses.
Matthew G
1
@Paul Slocum: Puede ser porque este comando no es un comando convencional, no el git incorporado. Creo que este comando solo funciona para Windows.
Envil
Tenga en cuenta que esto solo parece funcionar si comienza desde la raíz de su repositorio git.
Marc
Si desea comprobar en contra de un determinado número de revisión con gitk también se podría utilizar este atajo: gitk REVISION /path/to/file. Esto puede ser útil cuando desee verificar una versión determinada, por ejemplo.
Christian.D
89

También puede especificar un commit hash(a menudo también llamado commit ID) con el git showcomando .


En una palabra

git show <commitHash>:/path/to/file


Paso a paso

  1. Mostrar el registro de todos los cambios para un archivo determinado con git log /path/to/file
  2. En la lista de cambios que se muestra, muestra commit hashcomo commit 06c98...(06c98 ... siendo el hash de confirmación)
  3. Copia el commit hash
  4. Ejecute el comando git show <commitHash>:/path/to/fileusando el commit hashpaso 3 y el path/to/filepaso 1.

Nota: agregar el ./al especificar una ruta relativa parece importante, es decir git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html.

Adrien Be
fuente
1
en caso de que no conozca la ruta al archivo, úselo git show <SHA1> --name-onlypara obtenerlo.
Tiina
este comando op - ultima automóviles incluso de la memoria - probado en un directorio borrado ... no puede conseguir más que eso op gg
treyBake
43

Además de la respuesta de Jim Hunziker ,

puedes exportar el archivo desde la revisión como,

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt

Espero que esto ayude :)

Ijas Ameenudeen
fuente
23

Para ver rápidamente las diferencias con las revisiones anteriores de un archivo:

git show -1 filename.txt > para comparar con la última revisión del archivo

git show -2 filename.txt > comparar con la 2da última revisión

git show -3 fielname.txt > para comparar con la última 3ra última revisión

sachin_ur
fuente
18
Esos comandos muestran las diferencias con la versión actual para mí, pero no muestran el archivo completo.
Jean Paul
18

git log -ple mostrará no solo los registros de confirmación, sino también la diferencia de cada confirmación (excepto las confirmaciones de fusión). Luego puede presionar /, ingresar el nombre del archivo y presionar enter. Presione no ppara ir a la ocurrencia siguiente / anterior. De esta manera, no solo verá los cambios en el archivo, sino también la información de confirmación.

sanbor
fuente
3
Parece git log -pmque también mostraría commits de fusión.
sanbor
2
También puede ejecutar git log -p -- filename.txtpara restringir el historial solo al archivo deseado.
Jean Paul
3

Puede usar un script como este para volcar todas las versiones de un archivo para separar archivos:

p.ej

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

Obtenga el script aquí como respuesta a otra pregunta similar

Brad Parks
fuente
1
git_root, git_log_shortY git_log_message_for_commitestán desaparecidos.
mogsie
¡Buena atrapada! Publiqué esta respuesta en dos puntos diferentes, y simplemente eliminé esta y la vinculé a la otra, donde la gente me habló de esto antes ... ¡gracias @mogsie!
Brad Parks el
¡Este script es muy útil!
XMAN
3

CAMINO 1: (prefiero de esta manera)

  1. Encuentra commit id con:git reflog
  2. Listar archivos de commit git diff-tree --no-commit-id --name-only -r <commitHash>

ejemplo: git diff-tree --no-commit-id --name-only -r d2f9ba4// "d2f9ba4" es commit id de "1."

  1. Abra el archivo necesario con el comando:

git show <commitHash>:/path/to/file

ejemplo: git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift// "Src / ..." es la ruta del archivo desde "2".

CAMINO 2:

  1. Encuentra commit id con:git reflog
  2. restablecer completamente este commit: git reset --hard %commit ID%

git reset --hard c14809fa

  1. realice cambios innecesarios y realice una nueva confirmación en la rama necesaria :)
Andrés
fuente
0

Ayudante para recuperar múltiples archivos de una revisión dada

Al intentar resolver conflictos de fusión, este ayudante es muy útil:

#!/usr/bin/env python3

import argparse
import os
import subprocess

parser = argparse.ArgumentParser()
parser.add_argument('revision')
parser.add_argument('files', nargs='+')
args = parser.parse_args()
toplevel = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).rstrip().decode()
for path in args.files:
    file_relative = os.path.relpath(os.path.abspath(path), toplevel)
    base, ext = os.path.splitext(path)
    new_path = base + '.old' + ext
    with open(new_path, 'w') as f:
        subprocess.call(['git', 'show', '{}:./{}'.format(args.revision, path)], stdout=f)

GitHub aguas arriba .

Uso:

git-show-save other-branch file1.c path/to/file2.cpp

Resultado: lo siguiente contiene las versiones alternativas de los archivos:

file1.old.c
path/to/file2.old.cpp

De esta manera, conserva la extensión del archivo para que su editor no se queje y pueda encontrar fácilmente el archivo antiguo justo al lado del más nuevo.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
@MickeyPerlstein si puedes lograr lograr la misma interfaz con una mejor implementación, soy todo oídos.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
tal vez no entiendo (y si es así, mis disculpas) pero ¿no es solo: "git show version: ./ path> new_path"?
Mickey Perlstein
@MickeyPerlstein hola, sí, mi comando genera esa CLI, pero recorre múltiples archivos y produce el nombre de salida de la entrada, por lo que no tiene que escribir demasiado. Nada revolucionario, por supuesto, pero conveniente.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功