Registro Git avanzato

Lo scopo di qualsiasi sistema di controllo delle versioni รจ registrare le modifiche al tuo codice. Questo ti dร  la possibilitร  di tornare alla cronologia del tuo progetto per vedere chi ha contribuito a cosa, capire dove sono stati introdotti i bug e annullare le modifiche problematiche. Ma avere tutta questa cronologia disponibile รจ inutile se non sai come navigare. รˆ qui che entra in gioco il comando git log.

A questo punto, dovresti giร  conoscere il comando di base git log per la visualizzazione dei commit. Ma puoi modificare questo output passando molti parametri diversi a git log.

Le funzionalitร  avanzate di git log possono essere suddivise in due categorie: formattazione della modalitร  di visualizzazione di ogni commit e filtraggio dei commit inclusi nell'output. Insieme, queste due competenze ti danno il potere di tornare al tuo progetto e trovare tutte le informazioni di cui potresti aver bisogno.

Formattazione dell'output del registro

Innanzitutto, questo articolo esaminerร  i molti modi in cui l'output di git log puรฒ essere formattato. La maggior parte di questi si presenta sotto forma di flag che consentono di richiedere piรน o meno informazioni da git log.

Se non ti piace il formato predefinito di git log, puoi usare la funzionalitร  di aliasing di git config per creare una scorciatoia per una qualsiasi delle opzioni di formattazione discusse di seguito. Consulta Il comando git config per scoprire come configurare un alias.

Oneline

Il flag โ€”oneline condensa ogni commit in un'unica riga. Per impostazione predefinita, mostra solo l'ID di commit e la prima riga del messaggio di commit. Il tuo tipico output di git log โ€”oneline sarร  simile al seguente:

0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base

Questo รจ molto utile per avere una panoramica generica sul tuo progetto.

Decorazione

Spesso รจ utile sapere a quale branch o tag รจ associato ogni commit. Il flag โ€”decorate fa sรฌ che git log mostri tutti i riferimenti (ad esempio, branch, tag, ecc.) che puntano a ciascun commit.

Questo puรฒ essere combinato con altre opzioni di configurazione. Ad esempio, l'esecuzione di git log โ€”oneline โ€”decorate formatterร  la cronologia dei commit in questo modo:

0e25143 (HEAD, main) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base

Questo ti fa sapere che anche il primo commit รจ stato sottoposto a checkout (indicato con HEAD) e che รจ anche la punta del branchย principale. Un altro branch chiamato feature punta al secondo commit, e infine il quarto commit รจ etichettato come v0.9.

I branch, i tag, l'HEAD e la cronologia dei commit sono quasi tutte le informazioni contenute nel tuo repository Git, quindi questo ti offre una visione piรน completa della struttura logica del tuo repository.

Differenze

Il comando git log include molte opzioni per visualizzare le differenze relative a ogni commit. Due delle opzioni piรน comuni sono โ€”stat e -p.

L'opzione โ€”stat mostra il numero di inserimenti ed eliminazioni in ogni file modificato da ogni commit (si noti che la modifica di una riga รจ rappresentata da 1 inserimento e 1 eliminazione). Questo รจ utile quando desideri avere un breve riepilogo delle modifiche introdotte da ogni commit. Ad esempio, il seguente commit ha aggiunto 67 righe al file hello.py e rimosso 38 righe:

commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date:   Fri Jun 25 17:30:28 2014 -0500

    Add a new feature

 hello.py | 105 ++++++++++++++++++++++++-----------------
 1 file changed, 67 insertion(+), 38 deletions(-)

La quantitร  di segni + e - accanto al nome del file mostra il numero relativo di modifiche apportate a ciascun file modificato dal commit. Questo ti dร  un'idea di dove si possono trovare le modifiche per ogni commit.

Se vuoi vedere le modifiche effettive introdotte da ogni commit, puoi passare l'opzione -p a git log. Questo restituisce l'intera patch che rappresenta quel commit:

commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date:   Fri Jun 25 17:31:57 2014 -0500

    Fix a bug in the feature

diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")

Per i commit con molte modifiche, l'output risultante puรฒ diventare piuttosto lungo e ingombrante. Il piรน delle volte, se stai visualizzando una patch completa, probabilmente stai cercando una modifica specifica. Per questo, รจ utile usare l'opzione piccone.

Lo Shortlog

Il comando git shortlog รจ una versione speciale di git log destinata alla creazione di annunci di rilascio. Raggruppa ogni commit per autore e visualizza la prima riga di ogni messaggio di commit. Questo รจ un modo semplice per vedere chi sta lavorando su cosa.

Ad esempio, se due sviluppatori hanno contribuito con 5 commit a un progetto, l'output di git shortlog potrebbe essere il seguente:

Mary (2):
      Fix a bug in the feature
      Fix a serious security hole in our framework

John (3):
      Add the initial code base
      Add a new feature
      Merge branch 'feature'

Per impostazione predefinita, git shortlog ordina l'output in base al nome dell'autore, ma puoi anche passare l'opzione -n per ordinare in base al numero di commit per autore.

grafici

L'opzione โ€”graph disegna un grafico ASCII che rappresenta la struttura ramificata della cronologia dei commit. Questo รจ comunemente usato insieme ai comandi โ€”oneline e โ€”decorate per rendere piรน facile vedere quale commit appartiene a quale branch:

git log --graph --oneline --decorate

Per un semplice repository con solo 2 branch, il risultato sarร  il seguente:

*   0e25143 (HEAD, main) Merge branch 'feature'
|\  
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/  
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base

L'asterisco mostra in quale branch si trovava il commit, quindi il grafico sopra indica che i commit 23ad9ad e 16b36c6 si trovano su un branch tematico e il resto sul branchย principale.

Sebbene questa sia una buona opzione per i repository semplici, probabilmente sarร  piรน utile usare uno strumento di visualizzazione piรน completo come gitk o Sourcetreeย per progetti molto ramificati.

Formattazione personalizzata

Per tutte le altre tue esigenze di formattazione di git log, puoi usare l'opzione --pretty=format:"<string>". Questo ti consente di visualizzare ogni commit come preferisci utilizzando segnaposti in stile printf.

Ad esempio, i caratteri %cn, %h e %cd nel seguente comando sono sostituiti rispettivamente dal nome di chi ha eseguito il commit, dall'hash abbreviato del commit e dalla data dell'autore del commit.

git log --pretty=format:"%cn committed %h on %cd"

Il risultato รจ il seguente formato per ogni commit:

John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500 John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500 Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500 John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500

L'elenco completo dei segnaposti รจ disponibile nella sezione Pretty Formats della pagina del manuale di git log.

Oltre a consentirti di visualizzare solo le informazioni che ti interessano, l'opzione --pretty=format:"<string>" รจ particolarmente utile quando stai cercando di reindirizzare l'output di git log a un altro comando.

Filtrare la cronologia dei commit

La formattazione del modo in cui ogni commit viene visualizzato รจ solo metร  dell'impegno per imparare Git Log. L'altra metร  รจ capire come navigare nella cronologia dei commit. Il resto di questo articolo introduce alcuni dei modi avanzati per selezionare commit specifici nella cronologia del progetto utilizzando git log. Tutti questi possono essere combinati con una qualsiasi delle opzioni di formattazione discusse sopra.

Per quantitร 

L'opzione di filtro piรน semplice per git log รจ limitare il numero di commit visualizzati. Quando sei interessato solo agli ultimi commit, questo ti evita la fatica di visualizzare tutti i commit in una pagina.

Puoi limitare l'output di git log includendo l'opzione -<n>. Ad esempio, il comando seguente mostrerร  solo i 3 commit piรน recenti.

git log -3

Per data

Se stai cercando un commit per un periodo di tempo specifico, puoi utilizzare i contrassegni โ€”after o โ€”before per filtrare i commit per data. Entrambi accettano una varietร  di formati di data come parametri. Ad esempio, il comando seguente mostra solo i commit creati dopo il 1ยฐ luglio 2014 (incluso):

git log --after="2014-7-1"

Puoi anche inserire riferimenti relativi come "1 settimana fa" e "ieri":

git log --after="yesterday"

Per cercare un commit creato tra due date, puoi fornire sia una data โ€”prima che una dopo. Ad esempio, per visualizzare tutti i commit aggiunti tra il 1 luglio 2014 e il 4 luglio 2014, userai quanto segue:

git log --after="2014-7-1" --before="2014-7-4"

Per i commit con molte modifiche, l'output risultante puรฒ diventare piuttosto lungo e ingombrante. Il piรน delle volte, se stai visualizzando una patch completa, probabilmente stai cercando una modifica specifica. Per questo, รจ utile usare l'opzione piccone.

Per autore

Quando cerchi solo i commit creati da un determinato utente, usa il flag โ€”author. Questa opzione accetta un'espressione regolare e restituisce tutti i commit il cui autore corrisponde a quel modello. Se sai esattamente chi stai cercando, puoi usare una semplice vecchia stringa invece di un'espressione regolare:

git log --author="John"

Mostra tutti i commit il cui autore include il nome John. Il nome dell'autore non deve necessariamente corrispondere esattamente, deve solo contenere la frase specificata.

Puoi anche usare espressioni regolari per creare ricerche piรน complesse. Ad esempio, il comando seguente cerca i commit di Mary o John.

git log --author="John\|Mary"

Nota che anche l'email dell'autore รจ inclusa con il nome dell'autore, quindi puoi usare questa opzione anche per cercare tramite email.

Se il tuo flusso di lavoro separa gli autori dei commit dagli autori, il flag โ€”committer funziona nello stesso modo.

Per messaggio

Per filtrare i commit in base al messaggio di commit, usa il flag โ€”grep. Questo funziona proprio come il flag โ€”author di cui si รจ parlato sopra, ma esegue la corrispondenza in base al messaggio di commit anzichรฉ all'autore.

Ad esempio, se il tuo team include i numeri dei problemi pertinenti in ogni messaggio di commit, puoi usare un'espressione come quella di seguito per estrarre tutti i commit relativi a quel problema:

git log --grep="JRA-224:"

Puoi anche passare il parametro -i a git log per fare in modo che ignori le differenze tra maiuscole e minuscole durante la corrispondenza dei modelli.

Per file

Molte volte, ti interessano solo le modifiche apportate a un determinato file. Per mostrare la cronologia relativa a un file, tutto ciรฒ che devi fare รจ inserire il percorso del file. Ad esempio, l'espressione di seguito restituisce tutti i commit che hanno influito sul file foo.py o bar.py:

git log -- foo.py bar.py

Il parametro โ€” รจ usato per indicare a git log che gli argomenti successivi sono i percorsi dei file e non i nomi dei branch. Se non c'รจ alcuna possibilitร  di confusione con un branch, puoi omettere il โ€”.

Per contenuto

รˆ anche possibile cercare commit che introducono o rimuovono una determinata riga di codice sorgente. Questo si chiama piccone e assume la forma di una -S"<string>". Ad esempio, se vuoi sapere quando รจ stata aggiunta la stringa Hello, World! a un file del progetto, devi usare il comando seguente:

git log -S"Hello, World!"

Se vuoi effettuare una ricerca utilizzando un'espressione regolare anzichรฉ una stringa, puoi invece usare il flag -G"<regex>".

Questo รจ uno strumento di debug molto potente, in quanto consente di individuare tutti i commit che influiscono su una determinata riga di codice. Puรฒ anche mostrarti quando una riga รจ stata copiata o spostata in un altro file.

Per intervallo

Puoi passare una serie di commit a git log in modo da mostrare solo i commit contenuti in quell'intervallo. L'intervallo รจ specificato nel seguente formato, dove <since> e <until> sono riferimenti di commit:

git log <since>..<until>

Questo comando รจ particolarmente utile quando si utilizzano riferimenti di branch come parametri. รˆ un modo semplice per mostrare le differenze tra 2 branch. Considera il seguente comando:

git log main..feature

L'intervallo difunzionalitร ..principale contiene tutti i commit che si trovano nel branch delle funzionalitร , ma non nel branchย principale. In altre parole, si tratta dei progressi della funzionalitร  da quando รจ stata disattivata dal principale. Puoi visualizzarlo come segue:

Rilevamento di un fork nella cronologia tramite l'utilizzo degli intervalli

Nota che se cambi l'ordine dell'intervallo (funzionalitร ..principale), otterrai tutti i commit nella sezione principale, ma non nella funzionalitร . Se git log emette dei commit per entrambe le versioni, significa che la tua cronologia รจ diversa.

Filtraggio dei commit di fusione

Per impostazione predefinita, git log include i commit di fusione nell'output. Ma se il tuo team ha una politica di fusione continua (vale a dire che unisce le modifiche a monte in sezioni tematiche invece di ribasare il branch tematico sul branch upstream), avrai numerosi commit di fusione estranei nella cronologia del tuo progetto.

Puoi impedire a git log di visualizzare questi commit di fusione passando il flag โ€”no-merges:

git log --no-merges

D'altra parte, se sei interessato solo ai commit di fusione, puoi usare il flag โ€”merges:

git log --merges

Questo restituisce tutti i commit che hanno almeno due genitori.

Riepilogo

Ora dovresti sentirti abbastanza a tuo agio nell'usare i parametri avanzati di git log per formattare l'output e selezionare i commit che desideri visualizzare. Questo ti offre la possibilitร  di ottenere esattamente ciรฒ di cui hai bisogno dalla cronologia del tuo progetto.

Queste nuove competenze sono una parte importante del tuo toolkit Git, ma ricorda che git log viene spesso usato insieme ad altri comandi Git. Una volta trovato il commit che stai cercando, di solito lo passi a git checkout, git revert o qualche altro strumento per manipolare la cronologia dei commit. Quindi, assicurati di continuare ad approfondire le funzionalitร  avanzate di Git.

Consigliata per te

Blog di Bitbucket

Percorso di apprendimento DevOps

Scopri di piรน su Git

Trova altre guide e risorse su Git in questo hub.