Esiste un comando Git rapido per visualizzare una versione precedente di un file?


1511

Esiste un comando in Git per vedere (scaricato in stdout, o in $PAGERo $EDITOR) una versione particolare di un determinato file?



Se sei arrivato a questa domanda perché vuoi controllare una versione precedente di un file binario (ad esempio un'immagine), allora è meglio fare un checkout al vecchio commit, vedere cosa devi vedere e poi tornare a HEAD. Per questo, git checkout <sha1-of-the-commit-you-need>dopo,git checkout HEAD
Homero Esmeraldo

Risposte:


1732

Puoi usare git show con un percorso dalla radice del repository ( ./o ../per il percorso relativo):

$ git show REVISION:path/to/file

Sostituisci REVISIONcon la tua revisione effettiva (potrebbe essere un SHA di commit Git, un nome tag, un nome di ramo, un nome di commit relativo o qualsiasi altro modo di identificare un commit in Git)

Ad esempio, per visualizzare la versione del file <repository-root>/src/main.c da 4 commit fa, usare:

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

Git per Windows richiede barre rovesciate anche nei percorsi relativi alla directory corrente. Per maggiori informazioni, controlla la pagina man di git-show.


5
In realtà non sembra funzionare - l'hai provato? Per "git show HEAD: path / to / file.c", ottengo un errore "argomento ambiguo".
mike,

2
Deve

20
Se sei su Windows, potrebbe essere un separatore di percorsi; se faccio git show HEAD: dir \ subdir \ file, ottengo l'argomento ambiguo. Se faccio git show HEAD: dir / subdir / file, funziona come previsto.
Matt McMinn,

12
Il percorso che è necessario fornire dopo: è dalla radice del repository git. (questo è stato dato di seguito come risposta, ma penso che sia stato inteso come un commento su questa risposta)
MatrixFrog,

9
Se vuoi vederlo in una divisione di Vim in modo che scorrano insieme, ho scritto un breve post sul blog che mostra come farlo.
Flaviu,

257

Farlo per data è simile al seguente:

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

Si noti che HEAD@{2013-02-25}significa "dove si trovava HEAD il 25-02-2013" in questo repository (usando il reflog ), non "l'ultimo commit prima del 25-02-2013 in questo ramo nella storia".


5
Eccezionale. Mi risparmia molto tempo invece di andare su Github e guardare il commit.
Fizer Khan,

Il "punto" sul percorso del file era il mio problema. Grazie!
tomascharad,

5
Questo comando è utile con masterinvece di HEAD@{2013-02-25}, se sei su un ramo
funroll

1
Puoi includere l'ora, à la git log --since='2016-04-28 23:59:59 +0100'?
stupido

7
Il fatto che questa sintassi utilizzi il reflog è importante e deve essere evidenziato in modo forte, poiché il reflog non contiene tutti i commit . Vedi blog.endpoint.com/2014/05/git-checkout-at-specific-date.html
Alice Heaton,

113

Se ti piacciono le GUI, puoi usare gitk:

  1. inizia gitk con:

    gitk /path/to/file
    
  2. Scegli la revisione nella parte superiore dello schermo, ad es. Per descrizione o data. Per impostazione predefinita, la parte inferiore dello schermo mostra il diff per quella revisione, (corrispondente al pulsante di opzione "patch").

  3. Per vedere il file per la revisione selezionata:

    • Fare clic sul pulsante di opzione "albero". Questo mostrerà la radice dell'albero dei file in quella revisione.
    • Drill down al tuo file.

7
Questo funziona anche con tig , che è un visualizzatore di maledizioni repository git.
Matthew G,

1
@Paul Slocum: può essere perché questo comando non è un comando convenzionale, non è incorporato in git. Penso che questo comando funzioni solo per Windows.
Envil

Nota che questo sembra funzionare solo se inizi dalla radice del tuo repository git.
Marc

Se si desidera controllare contro una certa revisione con gitk si potrebbe anche usare questa scorciatoia: gitk REVISION /path/to/file. Questo può tornare utile quando si desidera verificare, ad esempio, con una determinata versione.
Christian.D,

89

Puoi anche specificare un commit hash(spesso chiamato anche commit ID) con il git showcomando .


In poche parole

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


Passo dopo passo

  1. Mostra il registro di tutte le modifiche per un determinato file con git log /path/to/file
  2. Nell'elenco delle modifiche mostrate, mostra commit hashcome commit 06c98...(06c98 ... essendo l'hash di commit)
  3. Copia il commit hash
  4. Eseguire il comando git show <commitHash>:/path/to/fileutilizzando il commit hashpassaggio 3 e il path/to/filepassaggio 1.

Nota: l' aggiunta di ./quando si specifica un percorso relativo sembra importante, ad es git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html.


1
nel caso in cui non si conosca il percorso del file, utilizzare git show <SHA1> --name-onlyper ottenerlo.
Tiina

questo comando op - anche il completamento automatico dalla memoria - testato su una directory eliminata ... non può ottenere più op di quel gg
treyBake

43

Oltre alla risposta di Jim Hunziker ,

puoi esportare il file dalla revisione come,

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

Spero che sia di aiuto :)


23

Per vedere rapidamente le differenze con le versioni precedenti di un file:

git show -1 filename.txt > per confrontare con l'ultima revisione del file

git show -2 filename.txt > per confrontare con la 2a ultima revisione

git show -3 fielname.txt > per confrontare con l'ultima 3a ultima revisione


18
Quei comandi mostrano le differenze con la versione corrente per me, ma non mostrano l'intero file.
Jean Paul,

18

git log -pti mostrerà non solo i registri di commit ma anche il diff di ogni commit (tranne i commit di unione). Quindi è possibile premere /, immettere il nome file e premere enter. Premere no pper passare all'occorrenza successiva / precedente. In questo modo non vedrai solo le modifiche nel file ma anche le informazioni di commit.


3
Sembra che git log -pmmostrerebbe anche i commit di unione.
sanbor,

2
È inoltre possibile eseguire git log -p -- filename.txtper limitare la cronologia al solo file desiderato.
Jean Paul,

3

È possibile utilizzare uno script come questo per scaricare tutte le versioni di un file per separare i file:

per esempio

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

Ottieni qui lo script come risposta a un'altra domanda simile


1
git_root, git_log_shortE git_log_message_for_commitmancano.
mogsie,

Buona pesca! Ho postato due volte questa risposta in 2 punti diversi, e l'ho appena rimosso e collegato all'altro, dove la gente me ne ha parlato prima ... grazie @mogsie!
Brad Parks,

Questo script è molto utile!
XMAN

3

MODO 1: (preferisco così)

  1. Trova ID commit con:git reflog
  2. Elenca i file da commit git diff-tree --no-commit-id --name-only -r <commitHash>

esempio: git diff-tree --no-commit-id --name-only -r d2f9ba4// "d2f9ba4" è ID commit da "1"

  1. Apri il file necessario con il comando:

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

esempio: git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift// "Src / ..." è il percorso del file da "2."

MODO 2:

  1. Trova ID commit con:git reflog
  2. resettare a questo commit: git reset --hard %commit ID%

git reset --hard c14809fa

  1. apportare qualsiasi modifica non necessaria e fare un nuovo commit nel ramo necessario :)

0

Aiuto per recuperare più file da una data revisione

Quando si cerca di risolvere i conflitti di unione, questo aiuto è molto utile:

#!/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 a monte .

Uso:

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

Risultato: quanto segue contiene le versioni alternative dei file:

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

In questo modo, mantieni l'estensione del file in modo che il tuo editor non si lamenti e possa facilmente trovare il vecchio file proprio accanto a quello più recente.


@MickeyPerlstein se riesci a ottenere la stessa interfaccia con una migliore implementazione, sono tutto a posto.
Ciro Santilli 24 冠状 病 六四 事件 法轮功

forse non capisco (e in tal caso, mi scuso) ma non è solo: "git show version: ./ path> new_path"?
Mickey Perlstein,

@MickeyPerlstein ciao, sì, il mio comando genera tale CLI, ma passa su più file e produce un nome di output dall'input, quindi non è necessario digitare troppo. Niente di rivoluzionario ovviamente, ma conveniente.
Ciro Santilli 26 冠状 病 六四 事件 法轮功
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.