Chapters ▾ 2nd Edition

2.3 Grunderna i Git - Visa incheckningshistoriken

Visa incheckningshistoriken

Du vill ofta se vad som har hänt efter att du har gjort flera incheckningar, eller om du har klonat ett kodförråd med befintlig historik. Det mest grundläggande och kraftfulla verktyget för detta är git log.

Exemplen använder ett mycket enkelt projekt som heter “simplegit”. Hämta projektet med:

$ git clone https://github.com/schacon/simplegit-progit

När du kör git log i projektet får du en utskrift som ser ut ungefär så här:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    Initial commit

Som standard, utan argument, listar git log incheckningarna i omvänd kronologisk ordning – de senaste först. Kommandot visar varje incheckning med dess SHA-1-kontrollsumma, författarens namn och e-post, datumet och meddelandet.

git log har en mängd olika flaggor för att visa exakt det du letar efter. Här visar vi några av de vanligaste.

Ett av de mest användbara valen är -p eller --patch, som visar skillnaden (ändringsmängden) som varje incheckning introducerar. Du kan också begränsa antalet loggposter, till exempel -2 för att bara visa de två senaste.

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end

Detta visar samma information, men med en diff direkt efter varje post. Det är väldigt användbart för kodgranskning eller för att snabbt se vad som hänt i en serie incheckningar som en medarbetare har lagt till.

Du kan också använda sammanfattande alternativ till git log. Om du till exempel vill se kort statistik för varje incheckning kan du använda --stat:

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    Initial commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

Som du ser visar --stat under varje incheckning en lista med ändrade filer, hur många filer som ändrats och hur många rader som lagts till och tagits bort. Den sammanfattar dessutom informationen i slutet.

Ett annat riktigt användbart val är --pretty. Det ändrar formatet på loggutskriften. Det finns flera förvalda varianter. oneline skriver varje incheckning på en rad, vilket är praktiskt om du tittar på många incheckningar. Valen short, full och fuller visar ungefär samma format men med mindre respektive mer information:

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 Change version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Remove unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 Initial commit

Det mest intressanta värdet är format, som låter dig ange ditt eget loggformat. Det är särskilt användbart om du genererar utdata för maskinell tolkning – eftersom du anger formatet explicit vet du att det inte förändras när Git uppdateras:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : Change version number
085bb3b - Scott Chacon, 6 years ago : Remove unnecessary test
a11bef0 - Scott Chacon, 6 years ago : Initial commit

Användbara formattecken för git log --pretty=format listar några av de mest användbara formattecknen som format accepterar.

Tabell 1. Användbara formattecken för git log --pretty=format
Format Beskrivning av utskrift

%H

Incheckningshash

%h

Förkortad incheckningshash

%T

Trädhash

%t

Förkortad trädhash

%P

Föräldrahashar

%p

Förkortade föräldrahashar

%an

Författarnamn

%ae

Författarens e-post

%ad

Författardatum (formatet styrs av --date)

%ar

Författardatum, relativt

%cn

Incheckarens namn

%ce

Incheckarens e-post

%cd

Incheckningsdatum

%cr

Incheckningsdatum, relativt

%s

Ämne

Du undrar kanske vad skillnaden är mellan författare och incheckare (author och committer). Författaren är den som ursprungligen gjorde arbetet, medan incheckaren är den som senast applicerade det. Om du skickar en korrigeringsfil till ett projekt och någon i kärnteamet applicerar den får ni båda erkännande – du som författare och kärnmedlemmen som incheckare. Vi tar upp detta lite mer i Distribuerat Git.

oneline och format är särskilt användbara tillsammans med ett annat log-val: --graph. Det lägger till en liten ASCII-graf som visar gren- och sammanslagningshistorik:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 Ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of https://github.com/dustin/grit.git
|\
| * 420eac9 Add method for getting the current branch
* | 30e367c Timeout code and tests
* | 5a09431 Add timeout protection to grit
* | e1193f8 Support for heads with slashes in them
|/
* d6016bc Require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

Den här typen av utskrift blir mer intressant när vi går igenom att grenaa och sammanfoga i nästa kapitel.

Det här är bara några av de enklare formateringsvalen för git log – det finns många fler. Vanliga val till git log listar valen vi har gått igenom hittills och några andra vanliga alternativ som kan vara användbara, samt hur de förändrar utskriften.

Tabell 2. Vanliga val till git log
Val Beskrivning

-p

Visa ändringsmängden som introduceras av varje incheckning.

--stat

Visa statistik för filer som ändras i varje incheckning.

--shortstat

Visa endast raden med antal ändringar från --stat.

--name-only

Visa bara listan över filer som ändrats efter incheckningsinformationen.

--name-status

Visa listan över filer med tillagd/ändrad/borttagen status.

--abbrev-commit

Visa endast de första tecknen i SHA-1-kontrollsumman i stället för alla 40.

--relative-date

Visa datum relativt (till exempel "för två veckor sedan") i stället för fullständigt datum.

--graph

Visa en ASCII-graf över gren- och sammanslagningshistorik.

--pretty

Visa incheckningar i alternativt format. Valen inkluderar oneline, short, full, fuller och format.

--oneline

Kortform för --pretty=oneline --abbrev-commit.

Begränsa loggutskriften

Utöver formateringsvalen tar git log även ett antal användbara begränsningar – val som låter dig visa ett urval av incheckningar. Du har redan sett ett sådant, -2, som visar de två senaste incheckningarna. Du kan ange -<n> för att visa de n senaste incheckningarna. I praktiken använder du det inte så ofta eftersom Git normalt skickar utskriften till en paginerare så att du bara ser en sida i taget.

Tidsbegränsande val som --since och --until är däremot väldigt användbara. Till exempel ger följande kommando en lista över incheckningar från de senaste två veckorna:

$ git log --since=2.weeks

Detta fungerar med många format – du kan ange ett specifikt datum som "2008-01-15" eller ett relativt datum som "för 2 år, 1 dag och 3 minuter sedan".

Du kan också filtrera listan efter sökvillkor. --author låter dig filtrera på en specifik författare och --grep låter dig söka efter nyckelord i incheckningsmeddelanden.

Notera

Du kan ange mer än en instans av både --author och --grep, vilket begränsar utskriften till incheckningar som matchar något av mönstren för --author och något av mönstren för --grep. Du kan också lägga till --match-all för att ytterligare begränsa till incheckningar som matchar alla --grep-mönster.

Ett annat användbart filter är -S (allmänt känt som Gits "hacka"), som tar en textsträng och bara visar incheckningar som ändrade antalet förekomster av den strängen. Om du till exempel vill hitta den senaste incheckningen som lade till eller tog bort en referens till en viss funktion kan du skriva:

$ git log -S function_name

Det sista riktigt användbara filtret för git log är en sökväg. Om du anger en katalog eller ett filnamn kan du begränsa loggen till incheckningar som introducerade ändringar i just de filerna. Detta anges alltid sist och föregås vanligtvis av två bindestreck (--) för att separera sökvägarna från övriga val.

$ git log -- path/to/file

I Val för att begränsa git log listas dessa och några andra vanliga begränsningsval.

Tabell 3. Val för att begränsa git log
Val Beskrivning

-<n>

Visa bara de senaste n incheckningarna

--since, --after

Begränsa till incheckningar gjorda efter angivet datum.

--until, --before

Begränsa till incheckningar gjorda före angivet datum.

--author

Visa bara incheckningar där författarfältet matchar angiven text.

--committer

Visa bara incheckningar där incheckarfältet matchar angiven text.

--grep

Visa bara incheckningar vars meddelande innehåller angiven text.

-S

Visa bara incheckningar som lägger till eller tar bort kod som matchar strängen.

Till exempel, om du bara vill se vilka incheckningar som ändrade testfiler i Gits källkodshistorik, som sparades av Junio Hamano under oktober 2008 och som inte är sammanslagningsincheckningar, kan du köra något i stil med detta:

$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

Av de nästan 40 000 incheckningarna i Gits källkodshistorik listar detta kommando de sex incheckningar som uppfyller kriterierna.

Tips
Förhindra visning av sammanslagningsincheckningar

Beroende på arbetsflödet i ditt kodförråd kan en ansenlig andel av incheckningarna i historiken vara sammanslagningar, vilket ofta inte är särskilt informativt. För att undvika att sammanslagningsincheckningar gör historiken svårläst kan du lägga till --no-merges.