Visualizza la cronologia delle modifiche di un file utilizzando il controllo delle versioni di Git


3090

Come posso visualizzare la cronologia delle modifiche di un singolo file in Git, i dettagli completi con ciò che è cambiato?

Sono arrivato a:

git log -- [filename]

che mi mostra la cronologia di commit del file, ma come posso accedere al contenuto di ciascuna delle modifiche al file?

Sto cercando di fare il passaggio da MS SourceSafe e quello era un semplice right-clickshow history.


41
Il link sopra non è più valido. Questo link funziona oggi: Git Community Book
chris,

1
Il link sopra (pubblicato da Chris) non è più valido. Questo link funziona oggi: git-scm.com/book/en/v2
Cog

Risposte:


2370

Per questo vorrei usare:

gitk [filename]

o per seguire i nomi precedenti del nome file

gitk --follow [filename]

28
Ma ho anche uno strumento che combina quanto sopra con 'git blame' che mi permette di sfogliare la fonte di un file mentre cambia nel tempo ...
Egon Willighagen,

26
Sfortunatamente, questo non segue la cronologia dei nomi precedenti del file.
Dan Molding,

146
Stavo anche cercando la cronologia dei file precedentemente rinominati e ho trovato prima questo thread. La soluzione è usare "git log --follow <nomefile>" come Phil ha indicato qui .
Florian Gutmann,

115
L'autore stava cercando uno strumento da riga di comando. Mentre gitk viene fornito con GIT, non è né un'app della riga di comando né una GUI particolarmente buona.
mikemaccana,

72
Stava cercando uno strumento da riga di comando? "tasto destro -> mostra cronologia" certamente non lo implica.
hdgarrood,

2235

Puoi usare

git log -p filename

per consentire a git di generare le patch per ciascuna voce del registro.

Vedere

git help log

per più opzioni - può effettivamente fare molte cose carine :) Per ottenere solo il diff per un impegno specifico che puoi

git show HEAD 

o qualsiasi altra revisione per identificatore. Oppure usa

gitk

per esaminare visivamente le modifiche.


8
git show HEAD mostra tutti i file, sai come tracciare un singolo file (come Richard stava chiedendo)?
Jonas Byström,

5
tu usi: git show <revision> - nome file, che mostrerà le differenze per quella revisione, nel caso ce ne fosse una.
Marcos Oliveira,

4
--stat è anche utile. Puoi usarlo insieme a -p.
Raffi Khatchadourian,

5
Questo è fantastico gitk non si comporta bene quando si specificano percorsi che non esistono più. Ho usato git log -p - path.
Paulo Casaretto,

6
Inoltre gitk sembra che sia stato costruito dal mostro boogie. Questa è un'ottima risposta ed è adattata al meglio alla domanda originale.
Ghayes,

1499

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

Questo mostrerà l' intero cronologia del file (inclusa la cronologia oltre i nomi e le differenze per ogni modifica).

In altre parole, se il nome del file è barstato chiamato una volta foo, allora git log -p bar(senza l' --followopzione) mostrerà la cronologia del file solo fino al punto in cui è stato rinominato - non mostrerà la cronologia del file quando era conosciuto come foo. L'utilizzo git log --follow -p barmostrerà l'intera cronologia del file, comprese eventuali modifiche al file quando era noto come foo. L' -popzione garantisce che le differenze siano incluse per ogni modifica.


18
--stat è anche utile. Puoi usarlo insieme a -p.
Raffi Khatchadourian,

23
Sono d'accordo che questa è la vera risposta. (1.) ti --followassicura di vedere i nomi dei file (2.) ti -passicura come il file viene cambiato (3.) è solo riga di comando.
Trevor Boyd Smith,

3
@NHDaly Ho notato che è --stato aggiunto, ma non so perché questo lo rende migliore? Che cosa fa?
Benjohn,

40
@Benjohn L' --opzione dice a Git che ha raggiunto la fine delle opzioni e che tutto ciò che segue --dovrebbe essere trattato come un argomento. Per git logquesto fa la differenza solo se hai un nome percorso che inizia con un trattino . Supponiamo che tu voglia conoscere la storia di un file che ha lo sfortunato nome "--follow":git log --follow -p -- --follow
Dan Molding,

10
@Benjohn: Normalmente, --è utile perché può anche proteggersi da qualsiasi revisionnome che corrisponda al nome del file che hai inserito, che in realtà può essere spaventoso. Ad esempio: se avessi sia un ramo che un file denominato foo, git log -p foomostreresti la cronologia del registro git fino a foo, non la cronologia del file foo . Ma @DanMoulding ha ragione sul fatto che dal momento che il --followcomando accetta solo un singolo nome file come argomento, questo è meno necessario poiché non può essere un revision. L'ho appena imparato. Forse allora avevi ragione a lasciarlo fuori dalla tua risposta; Non ne sono sicuro.
NHDaly,

172

Se preferisci rimanere basato sul testo, potresti voler usare tig .

Installazione rapida:

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

Usalo per visualizzare la cronologia su un singolo file: tig [filename]
oppure sfoglia la cronologia dettagliata dei repository:tig

Simile a gitkma basato sul testo. Supporta i colori nel terminale!


23
Ottimo strumento basato su testo, ottima risposta. Ho dato di matto quando ho visto le dipendenze per l'installazione di Gitk sul mio server senza testa. Voterebbe ancora A +++
Tom McKenzie il

Puoi anche guardare file specifici con tig, ad es.tig -- path/to/specific/file
glorifobia,

110

git whatchanged -p filename è anche equivalente a git log -p filename in questo caso.

Puoi anche vedere quando è stata modificata una specifica riga di codice all'interno di un file git blame filename. Questo stamperà un breve ID di commit, l'autore, il timestamp e la riga di codice completa per ogni riga del file. Questo è molto utile dopo che hai trovato un bug e vuoi sapere quando è stato introdotto (o chi è il difetto).


4
+1, ma filenamenon è facoltativo al comando git blame filename.
rockXrock

7
"I nuovi utenti sono incoraggiati a usare git-log invece. (...) Il comando è mantenuto principalmente per ragioni storiche;"
ciastek,

105

Utenti SourceTree

Se usi SourceTree per visualizzare il tuo repository (è gratuito e abbastanza buono) puoi fare clic con il tasto destro su un file e selezionare Log Selected

inserisci qui la descrizione dell'immagine

Il display (sotto) è molto più amichevole di gitk e della maggior parte delle altre opzioni elencate. Sfortunatamente (in questo momento) non esiste un modo semplice per avviare questa vista dalla riga di comando: la CLI di SourceTree attualmente apre solo repository.

inserisci qui la descrizione dell'immagine


1
Mi piace in particolare l'opzione "Segui i file rinominati", che consente di vedere se un file è stato rinominato o spostato.
Chris,

ma se non sbaglio (per favore fatemi sapere!), si possono confrontare solo due versioni alla volta nella GUI? Esistono client che dispongono di un'interfaccia elegante per diffondere diverse versioni contemporaneamente? Forse con una vista zoom indietro come in Sublime Text? Sarebbe davvero utile, penso.
Sam Lewallen,

@SamLewallen Se ho capito bene vuoi confrontare tre diversi commit? Sembra simile a un'unione a tre (la mia, la tua, la base) - di solito questa strategia viene utilizzata per risolvere i conflitti di unione non necessariamente confrontando tre commit arbitrari. Esistono molti strumenti che supportano le fusioni a tre vie stackoverflow.com/questions/10998728/… ma il trucco sta fornendo a questi strumenti le revisioni specifiche gitready.com/intermediate/2009/02/27/…
Mark Fox,

Grazie Mark Fox, ecco cosa intendo. Sei a conoscenza di eventuali applicazioni che lo faranno?
Sam Lewallen,

1
@ MarnenLaibow-Koser Non riesco a ricordare il motivo per cui ho bisogno dello SHA in quel momento. Ahaha.
AechoLiu,

63

Per mostrare quale revisione e autore hanno modificato l'ultima riga di ogni riga di un file:

git blame filename

o se si desidera utilizzare la potente GUI della colpa:

git gui blame filename

49

Riepilogo di altre risposte dopo averle leggere e aver giocato un po ':

Il solito comando da riga di comando sarebbe

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

Ma puoi anche usare gitk (gui) o tig (text-ui) per dare modi molto più leggibili dall'uomo di guardarlo.

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

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

Sotto debian / ubuntu, il comando di installazione per questi adorabili strumenti è come previsto:

sudo apt-get install gitk tig

E attualmente sto usando:

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

così posso solo digitare gdf dirper ottenere una cronologia focalizzata di tutto nella sottodirectory dir.


2
Penso che questa sia un'ottima risposta. Forse non sarai votato anche perché rispondi ad altri modi (meglio IMHO) per vedere i cambiamenti, ad esempio tramite gitk e tig oltre a git.
PopcornKing

Solo per aggiungere per rispondere. Individua il percorso (nello spazio git, fino al quale esiste ancora nel repository). Quindi utilizzare il comando indicato sopra "git log --follow --all -p <percorso_cartella / percorso_file>". È possibile che la cartella / filde sia stata rimossa nella cronologia, quindi individua il percorso massimo che esiste ancora e prova a recuperarne la cronologia. lavori !
Parassita

2
--allè per tutti i rami, il resto è spiegato nella risposta di @ Dan
cregox

1
Oh amico, dopo così tanto tempo alla ricerca di una buona soluzione per tenere traccia dei file oltre i nomi, finalmente l'ho trovato qui. Funziona come il fascino! Grazie!
xZero

25

Aggiungi questo alias al tuo .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

E usa il comando in questo modo:

> git lg
> git lg -- filename

L'output avrà lo stesso aspetto dell'output gitk. Godere.


Dopo aver eseguito quella scorciatoia LG, ho detto (e cito) "Bellissimo!". Tuttavia, notare che "\ n" dopo "--graph" è un errore.
jmbeck,

3
Può anche essere usato git lg -p filename: restituisce una bellissima diff del file cercato.
Egel,

22

Ultimamente ho scoperto tig e l' trovato molto utile. Ci sono alcuni casi in cui vorrei che fosse A o B, ma il più delle volte è piuttosto pulito.

Per il tuo caso, tig <filename>potrebbe essere quello che stai cercando.

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


on centos yum install tig
zzapper

18

Puoi usare vscode con GitLens , è uno strumento molto potente. Dopo aver installato GitLens, vai alla scheda GitLens, seleziona FILE HISTORYe puoi sfogliarlo.

inserisci qui la descrizione dell'immagine


15

Ho scritto git-playback per questo preciso scopo

pip install git-playback
git playback [filename]

Questo ha il vantaggio sia di visualizzare i risultati nella riga di comando (come git log -p) sia di passare attraverso ciascun commit usando i tasti freccia (come gitk).



10

Puoi anche provare questo che elenca i commit che hanno cambiato una parte specifica di un file (Implementato in Git 1.8.4).

Il risultato restituito sarebbe l'elenco di commit che ha modificato questa particolare parte. Comando:

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

dove upperLimit è il start_line_number e lowerLimit è il finale_line_number del file.

Maggiori dettagli su https://www.techpurohit.com/list-some-useful-git-commands


9

Se vuoi vedere l'intera cronologia di un file, incluso su tutti gli altri rami usa:

gitk --all <filename>

7

Con le eccellenti estensioni di Git , vai a un punto della cronologia in cui il file esisteva ancora (se è stato eliminato, altrimenti vai a HEAD), passa alla File treescheda, fai clic con il pulsante destro del mouse sul file e scegli File history.

Per impostazione predefinita, segue il file attraverso i nomi e la Blamescheda consente di vedere il nome in una data revisione.

Ha alcuni gotcha minori, come mostrare fatal: Not a valid object namenella Viewscheda quando si fa clic sulla revisione della cancellazione, ma posso conviverci. :-)


Vale la pena notare che questo è solo per Windows.
Evan Hahn,

3
@EvanHahn non è preciso, tramite mono si può usare GitExtension anche su Linux, lo usiamo su Ubuntu e siamo abbastanza contenti. vedi git-extensions-documentation.readthedocs.org/en/latest/…
Shmil The Cat

7

Se stai usando la GUI di Git (su Windows) nel menu Repository puoi usare "Visualizza la cronologia del master". Evidenzia un commit nel riquadro in alto e un file in basso a destra e vedrai il diff per quel commit in basso a sinistra.


Come risponde alla domanda?
jmbeck,

3
Bene, OP non ha specificato la riga di comando e, passando da SourceSafe (che è una GUI), è sembrato rilevante sottolineare che si potrebbe fare praticamente la stessa cosa che si può fare in VSS nella Git GUI su Windows.
cori,

6

SmartGit :

  1. Nel menu abilita la visualizzazione di file invariati: Visualizza / Mostra file invariati
  2. Fare clic con il tasto destro del mouse sul file e selezionare "Registro" o premere "Ctrl-L"

4

La risposta che stavo cercando che non era in questo thread è vedere i cambiamenti nei file che avevo messo in scena per il commit. vale a dire

git diff --cached

1
Se vuoi includere modifiche locali (non in scena), corro spesso git diff origin/masterper mostrare le differenze complete tra la tua filiale locale e la filiale principale (che può essere aggiornata da remoto tramite git fetch)
ghayes

4

Se usi TortoiseGit dovresti essere in grado di fare clic con il tasto destro del mouse sul file e farlo TortoiseGit --> Show Log. Nella finestra che si apre, assicurati di:

  • ' Show Whole Project' opzione non selezionata.

  • ' All Branches' opzione è selezionata.


TortoiseGit (e anche Eclipse Git) in qualche modo manca le revisioni del file selezionato, non contare su di esso!
Noam Manos,

@NoamManos, non ho riscontrato questo problema, quindi non posso verificare se la tua affermazione è corretta.
user3885927

Errore mio, succede solo in Eclipse, ma in TortoiseGit puoi vedere tutte le revisioni di un file se deselezioni "mostra tutto il progetto" + spuntando "tutti i rami" (nel caso in cui il file fosse stato eseguito su un altro ramo, prima che fosse unito a main ramo). Aggiornerò la tua risposta.
Noam Manos,

3

git diff -U <filename> darti un diff unificato.

Dovrebbe essere colorato in rosso e verde. In caso contrario, eseguire: git config color.ui autoprima.


2

Se stai usando eclipse con il plugin git, ha un'eccellente vista di confronto con la cronologia. Fai clic con il pulsante destro del mouse sul file e seleziona "confronta con" => "cronologia"


Ciò non ti consentirà comunque di trovare un file eliminato.
avgvstvs,

Il confronto tra due versioni di un file è diverso dalla Visualizzazione della cronologia delle modifiche di un file
golimar

0

Probabilmente sto parlando di dove si trovava l'OP quando è iniziato, cercando qualcosa di semplice che mi permettesse di usare git difftool con vimdiff per rivedere le modifiche ai file nel mio repository a partire da un commit specifico. Non ero troppo contento delle risposte che stavo trovando, quindi ho gettato insieme questo script git inc remental rep orter (gitincrep) ed è stato utile per me:

#!/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

Chiamato senza argomenti, questo inizierà dall'inizio della cronologia dei repository, altrimenti inizierà con qualsiasi hash di commit abbreviato che fornisci e procedi al presente - puoi ctrl-C in qualsiasi momento per uscire. Qualsiasi argomento dopo il primo limiterà i rapporti sulle differenze per includere solo i file elencati tra quegli argomenti (che penso sia quello che voleva l'OP, e lo consiglierei per tutti tranne che per i piccoli progetti). Se stai controllando le modifiche a file specifici e vuoi iniziare dall'inizio, dovrai fornire una stringa vuota per arg1. Se non sei un utente vim, puoi sostituire vimdiff con il tuo strumento diff preferito.

Il comportamento consiste nell'emettere i commenti di commit quando vengono rilevate modifiche rilevanti e iniziare a offrire esecuzioni vimdiff per ogni file modificato (questo è il comportamento git difftool , ma funziona qui).

Questo approccio è probabilmente piuttosto ingenuo, ma guardando molte delle soluzioni qui e in un post correlato, molti hanno coinvolto l'installazione di nuovi strumenti su un sistema in cui non ho accesso come amministratore, con interfacce che avevano la loro curva di apprendimento. La sceneggiatura sopra ha fatto quello che volevo senza occuparmene. Esaminerò qui molti eccellenti suggerimenti quando avrò bisogno di qualcosa di più sofisticato, ma penso che questo sia direttamente rispondente al PO.


0

Ho trovato una soluzione molto semplice per trovare rapidamente la cronologia del file.

  1. Apporta una modifica casuale al file
  2. Mostrerà come modifiche non confermate sul tuo sourcetree
  3. Fare clic con il tasto destro sul file e selezionare 'Log Selected'

inserisci qui la descrizione dell'immagine

Mostrerebbe la storia di tutti gli impegni.


Da dove viene questa GUI?
Colidyre

UI Sourcetree. Grazie
savvyBrar il
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.