Chapters ▾ 2nd Edition

8.1 Anpassa Git - Git‑konfiguration

Hittills har vi gått igenom grunderna i hur Git fungerar och hur man använder det, och vi har introducerat flera verktyg som Git erbjuder för att hjälpa dig använda det enkelt och effektivt. I det här kapitlet ser vi hur du kan få Git att arbeta mer skräddarsytt genom att introducera ett antal viktiga konfigurationsinställningar och krokssystemet. Med dessa verktyg är det lätt att få Git att fungera precis som du, din organisation eller ditt team behöver.

Git‑konfiguration

Som du kort läste i Kom igång kan du ange Git‑konfigurationsinställningar med kommandot git config. En av de första sakerna du gjorde var att ställa in ditt namn och din e‑postadress:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

Nu får du lära dig några av de mer intressanta alternativen som du kan ställa in på detta sätt för att anpassa din Git‑användning.

Först en snabb sammanfattning: Git använder en serie konfigurationsfiler för att avgöra icke‑standardbeteenden du kan vilja ha. Det första stället Git tittar på är den systemomfattande filen [sökväg]/etc/gitconfig, som innehåller inställningar som gäller för alla användare på systemet och alla deras kodförråd. Om du skickar flaggan --system till git config läser och skriver den specifikt i den filen.

Nästa ställe Git tittar på är filen ~/.gitconfig (eller ~/.config/git/config), som är specifik för varje användare. Du kan få Git att läsa och skriva i den här filen genom att skicka flaggan --global.

Till sist letar Git efter konfigurationsvärden i konfigurationsfilen i Git‑katalogen (.git/config) för det kodförråd du använder just nu. Dessa värden är specifika för just det kodförrådet, och motsvarar flaggan --local till git config. Om du inte anger vilken nivå du vill arbeta med är detta standard.

Var och en av dessa "nivåer" (system, global, lokal) skriver över värden i föregående nivå, så värden i .git/config trumfar till exempel de i [sökväg]/etc/gitconfig.

Notera

Gits konfigurationsfiler är klartext, så du kan också ställa in dessa värden genom att redigera filen manuellt och lägga in rätt syntax. Det är dock oftast enklare att köra kommandot git config.

Grundläggande klientkonfiguration

Konfigurationsalternativen som Git känner igen delas in i två kategorier: klientsidan och serversidan. Majoriteten av alternativen är på klientsidan – konfiguration av dina personliga arbetsvanor. Många, många konfigurationsalternativ stöds, men en stor del av dem är bara användbara i vissa kantfall; här går vi igenom de vanligaste och mest användbara alternativen. Om du vill se en lista över alla alternativ som din version av Git känner igen kan du köra:

$ man git-config

Det här kommandot listar alla tillgängliga alternativ i ganska stor detalj. Du hittar också referensmaterialet på https://git-scm.com/docs/git-config.

Notera

För avancerade användningsfall kan du leta upp "Conditional includes" i dokumentationen ovan.

core.editor

Som standard använder Git den textredigerare du har satt som standard via någon av skalets miljövariabler VISUAL eller EDITOR, eller faller tillbaka på vi för att skapa och redigera inchecknings- och taggmeddelanden. För att byta till något annat kan du använda inställningen core.editor:

$ git config --global core.editor emacs

Nu, oavsett vad som är satt som standardredigerare i ditt skal, kommer Git att starta Emacs för att redigera meddelanden.

commit.template

Om du sätter detta till sökvägen för en fil på ditt system använder Git den filen som standardinledande meddelande när du checkar in. Poängen med en egen incheckningsmall är att du kan använda den för att påminna dig själv (eller andra) om rätt format och stil när du skapar ett incheckningsmeddelande.

Till exempel, tänk dig en mallfil på ~/.gitmessage.txt som ser ut så här:

Subject line (try to keep under 50 characters)

Multi-line description of commit,
feel free to be detailed.

[Ticket: X]

Notera hur denna incheckningsmall påminner om att hålla ämnesraden kort (för git log --oneline‑utdata), att lägga till mer detaljer under den, och att hänvisa till ett ärende- eller felspårningsnummer om ett sådant finns.

För att tala om för Git att använda den som standardmeddelande som visas i din redigerare när du kör git commit, sätter du konfigurationsvärdet commit.template:

$ git config --global commit.template ~/.gitmessage.txt
$ git commit

Då kommer din redigerare att öppnas med något i stil med detta när du checkar in:

Subject line (try to keep under 50 characters)

Multi-line description of commit,
feel free to be detailed.

[Ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C

Om ditt team har en policy för incheckningsmeddelanden kan en mall för den policyn på ditt system, och att konfigurera Git att använda den som standard, öka chansen att policyn följs regelbundet.

core.pager

Den här inställningen avgör vilken sidvisare som används när Git sidvisar utdata som log och diff. Du kan sätta den till more eller din favorit‑sidvisare (som standard är det less), eller stänga av den genom att sätta den till en tom sträng:

$ git config --global core.pager ''

Om du kör det kommer Git att skriva ut hela utdata från alla kommandon, oavsett hur långa de är.

user.signingkey

Om du skapar signerade annoterade taggar (som vi diskuterade i Signera ditt arbete) gör det saker enklare att ha din GPG‑signeringsnyckel i konfigurationen. Sätt ditt nyckel‑ID så här:

$ git config --global user.signingkey <gpg-key-id>

Nu kan du signera taggar utan att behöva ange nyckeln varje gång med git tag:

$ git tag -s <tag-name>

core.excludesfile

Du kan lägga mönster i projektets .gitignore‑fil så att Git inte ser dem som ospårade filer eller försöker köa dem när du kör git add, som diskuterats i Ignorera filer.

Men ibland vill du ignorera vissa filer i alla kodförråd du arbetar med. Om din dator kör macOS känner du säkert till .DS_Store‑filer. Om din föredragna redigerare är Emacs eller Vim känner du till filnamn som slutar med ~ eller .swp.

Den här inställningen låter dig skriva en sorts global .gitignore‑fil. Om du skapar en fil ~/.gitignore_global med följande innehåll:

*~
.*.swp
.DS_Store

…och kör git config --global core.excludesfile ~/.gitignore_global, kommer Git aldrig mer att störa dig om dessa filer.

help.autocorrect

Om du skriver fel på ett kommando visar det något i stil med detta:

$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.

The most similar command is
    checkout

Git försöker hjälpsamt lista ut vad du menade, men vägrar ändå att göra det. Om du sätter help.autocorrect till 1 kommer Git faktiskt köra kommandot åt dig:

$ git chekcout master
WARNING: You called a Git command named 'chekcout', which does not exist.
Continuing under the assumption that you meant 'checkout'
in 0.1 seconds automatically...

Notera delen “0.1 seconds”. help.autocorrect är faktiskt ett heltal som representerar tiondelar av en sekund. Så om du sätter den till 50 ger Git dig 5 sekunder att ändra dig innan det kör det autokorrigerade kommandot.

Färger i Git

Git har fullt stöd för färgat terminalutdata, vilket gör det lättare att snabbt tolka kommandoutdata visuellt. Ett antal alternativ kan hjälpa dig att ställa in färgerna efter dina preferenser.

color.ui

Git färglägger automatiskt det mesta av sin utdata, men det finns en huvudströmbrytare om du inte gillar beteendet. För att stänga av all färgad terminalutdata gör du så här:

$ git config --global color.ui false

Standardinställningen är auto, vilket färglägger utdata när den går direkt till en terminal, men utelämnar färgstyrkoder när utdata omdirigeras till en pipe eller en fil.

Du kan också sätta den till always för att ignorera skillnaden mellan terminaler och pipelines. Det vill du sällan; i de flesta fall, om du vill ha färgkoder i omdirigerad utdata, kan du i stället skicka flaggan --color till Git‑kommandot för att tvinga färgkoder. Standardinställningen är nästan alltid det du vill ha.

color.*

Om du vill vara mer specifik kring vilka kommandon som färgsätts och hur, erbjuder Git verb‑specifika färginställningar. Var och en av dessa kan sättas till true, false eller always:

color.gren
color.diff
color.interactive
color.status

Dessutom har var och en av dessa delinställningar som du kan använda för att ange specifika färger för delar av utdata, om du vill skriva över varje färg. Till exempel, för att sätta metainformationen i din diffutdata till blå förgrund, svart bakgrund och fet text kan du köra:

$ git config --global color.diff.meta "blue black bold"

Du kan sätta färgen till någon av följande värden: normal, black, red, green, yellow, blue, magenta, cyan eller white. Om du vill ange ett attribut som fet stil i exemplet ovan kan du välja mellan bold, dim, ul (understrykning), blink och reverse (växlar förgrund och bakgrund).

Externa sammanslagnings- och diffverktyg

Även om Git har en intern diff‑implementation, vilket är det vi har visat i den här boken, kan du sätta upp ett externt verktyg i stället. Du kan också sätta upp ett grafiskt verktyg för att lösa sammanslagningskonflikter i stället för att lösa konflikter manuellt. Vi demonstrerar hur man ställer in Perforce Visual Sammanslagning Tool (P4Merge) för att göra dina diffar och sammanslagningslösningar, eftersom det är ett trevligt grafiskt verktyg och det är gratis.

Om du vill prova detta fungerar P4Merge på alla större plattformar, så du bör kunna göra det. Vi använder sökvägar i exemplen som fungerar på macOS och Linux; för Windows behöver du ändra /usr/local/bin till en körbar sökväg i din miljö.

Till att börja med: ladda ner P4Merge från Perforce. Sedan ställer du in externa omslagsskript för att köra dina kommandon. Vi använder macOS‑sökvägen för den körbara filen; i andra system kommer det vara där din p4merge‑binär är installerad. Skapa ett sammanslagningsomslagsskript med namnet extMerge som anropar din binär med alla argument som ges:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*

Diff‑omslaget kontrollerar att sju argument ges och skickar två av dem till ditt sammanslagningsskript. Som standard skickar Git följande argument till diff‑programmet:

path old-file old-hex old-mode new-file new-hex new-mode

Eftersom du bara vill ha argumenten old-file och new-file använder du omslagsskriptet för att skicka vidare det du behöver.

$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"

Du behöver också se till att dessa verktyg är körbara:

$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff

Nu kan du konfigurera din konfigurationsfil att använda din anpassade sammanslagningslösning och diffverktyg. Detta kräver ett antal egna inställningar: merge.tool för att tala om för Git vilken strategi som ska användas, mergetool.<tool>.cmd för att ange hur kommandot körs, mergetool.<tool>.trustExitCode för att tala om för Git om exit‑koden från programmet indikerar en lyckad sammanslagning eller inte, och diff.external för att tala om för Git vilket kommando som ska köras för diffar. Så du kan antingen köra fyra config‑kommandon:

$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
  'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.extMerge.trustExitCode false
$ git config --global diff.external extDiff

eller så kan du redigera din ~/.gitconfig‑fil och lägga till dessa rader:

[merge]
  tool = extMerge
[mergetool "extMerge"]
  cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
  trustExitCode = false
[diff]
  external = extDiff

Efter att allt detta är inställt kan du köra diff‑kommandon som detta:

$ git diff 32d1776b1^ 32d1776b1

I stället för att få diffutdata på kommandoraden startar Git P4Merge, som ser ut ungefär så här:

P4Merge
Figur 166. P4Merge

Om du försöker sammanfoga två grenar och därefter får sammanslagningskonflikter kan du köra kommandot git mergetool; det startar P4Merge så att du kan lösa konflikterna med det grafiska verktyget.

Det fina med denna omslagsuppsättning är att du lätt kan byta diff‑ och sammanslagningsverktyg. Till exempel, för att byta dina extDiff‑ och extMerge‑verktyg till att köra KDiff3 i stället räcker det att redigera din extMerge‑fil:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*

Nu kommer Git att använda KDiff3 för diffvisning och sammanslagningskonfliktlösning.

Git levereras förinställt med en mängd andra sammanslagningsverktyg utan att du behöver ställa in cmd‑konfiguration. För att se en lista över de verktyg den stöder kan du prova detta:

$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
        emerge
        gvimdiff
        gvimdiff2
        opendiff
        p4merge
        vimdiff
        vimdiff2

The following tools are valid, but not currently available:
        araxis
        bc3
        codecompare
        deltawalker
        diffmerge
        diffuse
        ecmerge
        kdiff3
        meld
        tkdiff
        tortoisemerge
        xxdiff

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

Om du inte är intresserad av att använda KDiff3 för diff utan bara vill använda det för sammanslagning, och kdiff3‑kommandot finns i din sökväg, kan du köra:

$ git config --global merge.tool kdiff3

Om du kör detta i stället för att ställa in extMerge och extDiff använder Git KDiff3 för sammanslagning och det vanliga Git‑diffverktyget för diffar.

Formatering och blanktecken

Formaterings- och blankteckensproblem är några av de mer frustrerande och subtila problem som många utvecklare stöter på när de samarbetar, särskilt över plattformar. Det är väldigt lätt att ändringspatchar eller annat samarbetsarbete introducerar subtila blankteckensändringar eftersom redigerare lägger in dem i tysthet, och om dina filer någon gång rör ett Windows‑system kan deras radslut ersättas. Git har några konfigurationsalternativ för att hjälpa till med dessa problem.

core.autocrlf

Om du programmerar på Windows och arbetar med personer som inte gör det (eller tvärtom) kommer du troligen att stöta på radslutsproblem någon gång. Det beror på att Windows använder både ett vagnretur‑tecken och ett radmatnings‑tecken för radslut i sina filer, medan macOS och Linux bara använder radmatning. Det här är en subtil men mycket frustrerande aspekt av plattformsöverskridande arbete: många redigerare i Windows ersätter i tysthet befintliga LF-radslut med CRLF, eller lägger in båda radslutstecknen när användaren trycker Enter.

Git kan hantera detta genom att automatiskt konvertera CRLF‑radslut till LF när du lägger en fil i indexet, och vice versa när den lägger ut kod till ditt filsystem. Du kan slå på detta med inställningen core.autocrlf. Om du är på en Windows‑maskin sätter du den till true — detta konverterar LF‑radslut till CRLF när du lägger ut kod:

$ git config --global core.autocrlf true

Om du är på ett Linux‑ eller macOS‑system som använder LF‑radslut vill du inte att Git automatiskt konverterar dem när du lägger ut filer; däremot, om en fil med CRLF‑radslut råkar smyga in kan du vilja att Git fixar det. Du kan tala om för Git att konvertera CRLF till LF vid incheckning men inte åt andra hållet genom att sätta core.autocrlf till input:

$ git config --global core.autocrlf input

Den här inställningen lämnar dig med CRLF‑radslut i Windows‑utläggningar, men LF‑radslut på macOS och Linux samt i kodförrådet.

Om du är Windows‑programmerare och gör ett Windows‑endast projekt kan du stänga av funktionen, och låta vagnreturerna lagras i kodförrådet genom att sätta konfigurationsvärdet till false:

$ git config --global core.autocrlf false

core.whitespace

Git kommer förinställt att upptäcka och fixa vissa blankteckensproblem. Det kan leta efter sex primära blankteckensproblem — tre är påslagna som standard och kan stängas av, och tre är avstängda som standard men kan aktiveras.

De tre som är påslagna som standard är blank-at-eol, som letar efter blanksteg i slutet av en rad; blank-at-eof, som upptäcker tomma rader i slutet av en fil; och space-before-tab, som letar efter mellanslag före tabbar i början av en rad.

De tre som är avstängda som standard men kan slås på är indent-with-non-tab, som letar efter rader som börjar med mellanslag i stället för tabbar (och styrs av alternativet tabwidth); tab-in-indent, som övervakar tabbar i indenteringsdelen av en rad; och cr-at-eol, som talar om för Git att vagnreturer i slutet av rader är okej.

Du kan tala om för Git vilka av dessa du vill ha aktiva genom att sätta core.whitespace till de värden du vill ha på eller av, separerade med kommatecken. Du kan stänga av ett alternativ genom att sätta ett - framför dess namn, eller använda standardvärdet genom att lämna bort det helt ur inställningssträngen. Till exempel, om du vill att allt utom space-before-tab ska vara på kan du göra så här (där trailing-space är en förkortning som täcker både blank-at-eol och blank-at-eof):

$ git config --global core.whitespace \
    trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol

Eller så kan du bara ange den anpassade delen:

$ git config --global core.whitespace \
    -space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol

Git upptäcker dessa problem när du kör git diff och försöker färglägga dem så att du kan rätta dem innan du checkar in. Den använder också dessa värden för att hjälpa dig när du applicerar ändringspatchar med git apply. När du applicerar ändringspatchar kan du be Git varna om den applicerar ändringspatchar med de angivna blankteckensproblemen:

$ git apply --whitespace=warn <patch>

Eller så kan du låta Git försöka rätta problemen automatiskt innan den applicerar ändringspatchen:

$ git apply --whitespace=fix <patch>

Dessa alternativ gäller även kommandot git rebase. Om du har checkat in blankteckensproblem men ännu inte har skickat upp kan du köra git rebase --whitespace=fix för att låta Git rätta blankteckensproblem automatiskt medan den skriver om ändringspatcharna.

Serverkonfiguration

Det finns inte i närheten lika många konfigurationsalternativ på serversidan av Git, men det finns några intressanta du kan vilja lägga märke till.

receive.fsckObjects

Git kan se till att varje objekt som tas emot under en uppskickning fortfarande matchar sin SHA‑1‑kontrollsumma och pekar på giltiga objekt. Den gör dock inte detta som standard; det är en ganska dyr operation och kan göra processen långsam, särskilt på stora kodförråd eller stora uppskickningar. Om du vill att Git ska kontrollera objektsintegritet vid varje uppskickning kan du tvinga den att göra det genom att sätta receive.fsckObjects till true:

$ git config --system receive.fsckObjects true

Nu kommer Git att kontrollera integriteten hos ditt kodförråd innan varje uppskickning accepteras för att se till att felaktiga (eller illvilliga) klienter inte introducerar korrupt data.

receive.denyNonFastForwards

Om du ombaserar incheckningar som du redan har skickat upp och sedan försöker skicka igen, eller på annat sätt försöker skicka en incheckning till en fjärrgren som inte innehåller den incheckning som fjärrgrenen för närvarande pekar på, kommer du att nekas. I allmänhet är detta en bra policy, men vid ombasering kan du anse att du vet vad du gör och tvinga en uppdatering av fjärrgrenen med flaggan -f i uppskickningskommandot.

För att tala om för Git att vägra tvångsuppskick sätter du receive.denyNonFastForwards:

$ git config --system receive.denyNonFastForwards true

Det andra sättet att göra detta är via mottagningskrokar på serversidan, som vi tar upp strax. Den metoden låter dig göra mer komplexa saker, som att neka icke‑snabbspolningar för en viss delmängd användare.

receive.denyDeletes

En av kringgåendena till denyNonFastForwards‑policyn är att användaren raderar grenen och sedan skickar upp den igen med den nya referensen. För att undvika detta sätter du receive.denyDeletes till true:

$ git config --system receive.denyDeletes true

Detta nekar all radering av grenar eller taggar — ingen användare kan göra det. För att ta bort fjärrgrenar måste du ta bort ref‑filerna på servern manuellt. Det finns också mer intressanta sätt att göra detta per användare via ACL:er, som du kommer att lära dig i Ett exempel på Git‑upprätthållen policy.