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.