W3docs

git blame

Informazioni utili sul comando git blame, come funziona con esempi e un elenco delle opzioni più comuni.

Descrizione

Il comando git blame annota ogni riga di un file con informazioni sull'ultimo commit che l'ha modificata — l'hash del commit, l'autore e il timestamp. In altre parole, per ogni riga risponde alla domanda "chi l'ha scritta, e quando?".

Si tratta di un comando di ispezione in sola lettura. Non modifica la cronologia né i file; visualizza soltanto i metadati già presenti nel repository. Gli sviluppatori usano git blame per:

  • Trovare l'autore di una riga confusa o difettosa per poter chiedere spiegazioni sull'intento originale.
  • Individuare il commit che ha introdotto una modifica e leggerne il messaggio completo con git show.
  • Capire come si è evoluto un file quando la cronologia dei commit da sola non è abbastanza precisa da indicare una singola riga.

git blame

Informazione

git blame mostra solo il commit più recente che ha toccato ciascuna riga. Se una riga è stata modificata più volte, gli autori precedenti risultano nascosti. Per risalire a una riga indietro nel tempo, rieseguire blame su una revisione precedente (vedi Seguire una riga nella cronologia di seguito).

Come funziona

Per illustrare chiaramente il funzionamento di git blame, consideriamo un esempio con un file README.md e alcuni commit di autori diversi.

Nell'esempio seguente utilizziamo git blame. Lo stato del repository di esempio può essere esplorato con git log. La cronologia dei commit è la seguente:

git log e git blame

git log
commit 745a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a
Author: Bob Smith <[email protected]m>
Date: Fri Apr 1 19:55:15 2019 +0000
Another commit to help git blame track the who, the what, and the when
commit eb06faedb1fdd159d62e4438fc8dbe9c9fe0728b
Author: Bob Smith <[email protected]m>
Date: Fri Apr 1 19:53:23 2019 +0000
Creating the third commit, along with Nick and Robert, so that Nick can get git blame docs.
commit 990c2b6a84464fee153253dbf02e845a4db372bb
Merge: 82496ea 89feb84
Author: Tom Brown <[email protected]m>
Date: Fri Apr 1 05:33:01 2019 +0000
Merged in tom-brown/git-blame-example/albert-so/readmemd-edited-online-with-bitbucket-1519865641474 (pull request #2)
README.md edited online with Bitbucket
commit 73a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8
Author: Tom Brown <[email protected]m>
Date: Fri Apr 1 00:54:03 +0000
README.md edited online with Bitbucket

Il comando git blame opera su singoli file. L'esecuzione predefinita di git blame mostra le informazioni di blame per il file specificato.

Il seguente output è un sottoinsieme dell'output completo di blame per il file README:

git blame

git blame README.md
83253a1b (marioswift 2019-02-28 13:37:02 -0800 1) # Git Blame example
83253a1b (marioswift 2019-02-28 13:37:02 -0800 2)
73a0b1c2 (Tom Brown 2019-04-01 00:54:03 +0000 3) Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.
83253a1b (marioswift 2019-02-28 13:37:02 -0800 4)
83253a1b (marioswift 2019-02-28 13:37:02 -0800 5) There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.
83253a1b (marioswift 2019-02-28 13:37:02 -0800 6)
73a0b1c2 (Tom Brown 2019-04-01 00:54:03 +0000 7) Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod TEMPOR incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laborum nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Leggere l'output

Ogni riga di blame è composta da quattro parti:

83253a1b (marioswift 2019-02-28 13:37:02 -0800 1) # Git Blame example
└──┬───┘  └───┬────┘ └────────┬─────────────┘  └──────────┬──────────┘
             └─ the line's content
   │          │               │               └─ line number in the file
   │          │               └─ commit timestamp
   │          └─ author of that commit
   └─ abbreviated commit hash

Le righe che condividono lo stesso hash di commit sono state modificate insieme per l'ultima volta. Per esaminare cosa ha fatto effettivamente quel commit, copiare l'hash ed eseguire git show 83253a1b.

Opzioni comuni

git blame accetta diverse opzioni che limitano l'output o modificano l'attribuzione dell'autore. Le più utili sono riepilogate di seguito.

ComandoCosa fa
git blame -L 1,3 README.mdLimita l'output all'intervallo di righe richiesto — in questo caso, dalla riga 1 alla 3. Si può usare anche -L 5,+10 per iniziare dalla riga 5 e mostrare 10 righe.
git blame -e README.mdMostra l'indirizzo email di ciascun autore invece del nome utente.
git blame -w README.mdIgnora le modifiche costituite solo da spazi bianchi. Se un autore precedente ha solo re-indentato una riga (ad esempio da tabulazioni a spazi), git blame gliene attribuirebbe la paternità; -w va oltre e guarda la reale modifica al contenuto.
git blame -M README.mdRileva le righe spostate o copiate all'interno dello stesso file e riporta l'autore originale invece di chi le ha spostate.
git blame -C README.mdRileva le righe spostate o copiate da altri file e riporta l'autore originale. Passare -C due o tre volte per una ricerca più aggressiva.
git blame -L :functionName README.mdLimita blame a una singola funzione per nome (utilizza la regex funcname di Git), invece di un intervallo numerico di righe.

Seguire una riga nella cronologia

Poiché blame si ferma al commit più recente per ogni riga, a volte è necessario scavare un livello più in profondità. Una volta ottenuto l'hash del commit dall'output di blame, è possibile rieseguire blame sul commit precedente per vedere come appariva la riga — e chi l'aveva scritta — in un momento antecedente.

# Blame the file as it was just before commit 73a0b1c2 touched it
git blame 73a0b1c2^ -- README.md

Il ^ (accento circonflesso) significa "il genitore di questo commit". Ripetendo l'operazione è possibile percorrere a ritroso la cronologia di una riga, una revisione alla volta.

È anche possibile limitare blame a un intervallo di revisioni per vedere l'attribuzione solo per una determinata porzione della cronologia:

# Blame README.md considering only commits between v1.0 and v2.0
git blame v1.0..v2.0 -- README.md

Git Blame vs Git Log

Il comando git blame mostra l'ultimo autore che ha modificato una riga, ma a volte può essere necessario vedere quando una riga è stata inizialmente aggiunta. Con git blame da solo questo è scomodo — anche combinando le opzioni -w, -C e -M. Per tracciare quando un testo è comparso per la prima volta (o è stato rimosso), git log è lo strumento più adatto.

Usare git log con l'opzione -S (il "piccone") per visualizzare i commit in cui una stringa specifica è stata aggiunta o rimossa.

Esempio: trovare quando una stringa è cambiata

git log -S esempio

git log -S "CSS3D and WebGL renderers." --pretty=format:'%h %an %ad %s'
e339d3c85a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d John Carter Fri Jun 13 16:51:06 2015 +0200 reverted README.md to original content
509c2cc35a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d Max Fri Jul 8 13:56:14 2015 +0200 Updated README
cb20237cc1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6 Leo Sat Aug 31 00:22:36 2012 +0100 Removed DOMRenderer. Now with the CSS3DRenderer it has become irrelevant.

L'output mostra che il file README.md è stato aggiunto e modificato 3 volte da tre autori. L'opzione --pretty=format:'...' personalizza l'output di git log per visualizzare campi specifici come hash del commit, autore, data e oggetto.

Comandi correlati

git blame è più utile se affiancato ad altri comandi di ispezione:

  • git log — sfoglia la cronologia completa dei commit e cercavi con -S/-G.
  • git show — mostra il messaggio completo e il diff di un commit trovato tramite blame.
  • git diff — confronta lo stato attuale di una riga con una revisione precedente.

Esercitazione

Pratica
Quali sono le funzioni e le opzioni del comando 'git blame' in Git?
Quali sono le funzioni e le opzioni del comando 'git blame' in Git?
Was this page helpful?