Förstå förenkling av Git-historik
Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019
Git-historikförenkling kan vara ett förvirrande odjur. 99% av tiden vet du inte ens att det finns, men ibland kommer det att hoppa ut ur de mörka hörnen av Git och bita dig. I den här artikeln ska vi utforska vad historikförenkling är och hur det kan orsaka förvirring när du tittar på filhistorik.
Vi börjar med ett vanligt scenario:
- Du skickar en ändring till en fil och sammanfogar sedan ändringen till main.
- Några av dina kollegor sammanfogar också sina grenar till main.
- Du kommer tillbaka en stund senare och märker att ändringarna saknas.
- Letar du efter den skyldige går du och tittar på filhistoriken och märker... dina ändringar visas inte ens!?
Git-incheckningshistorik är ett träd. Ibland är kronologisk historik inte samma som den faktiska filträdshistoriken. Den här situationen inträffar oftast när en sammanslagningscheckning återställer en fil till sitt ursprungliga tillstånd. I så fall visar standardhistorikvyn inte alla ändringar, eftersom filen tekniskt sett inte ändrades. I det här scenariot inser Git att det kan förenkla historiken och att de "ändringar" som du troligtvis letar efter tas bort från loggen.
Om du inte har stött på det förut, kan du bli frustrerad och undra vart sjutton gick mina ändringar?
Historikförenkling: På som standard
Som standard förenklar körningen av loggkommandot på en fil automatiskt git log file.txt
historiken, vilket möjligen döljer vissa incheckningar från dess utdata. Mer information finns på sidan git log man.
Det som ökar förvirringen är att historikförenkling inte sker om du bara kör git log
, eftersom du tittar på alla ändringar finns det inget att förenkla.
För att inaktivera historikförenkling måste du använda kommandoradsväxeln --full-history
.
Ett exempel på historikförenkling
För att bättre förstå hur förenkling fungerar skapar vi ett eget exempel på förenkling av historien. Först ska vi titta på ett diagram över den historik som vi ska skapa:
Som du ser kommer vi att:
- Skapa filen .
- Lägg till en rad i filen i en gren (djur).
- Lägg till en annan rad i filen i en annan gren (frukt).
- Slå samman grendjur tillbaka till huvuddjuren.
- Sammanfoga grenfrukten tillbaka till main och välj hela kopian av filen från fruktgrenen.
- Kontrollera filens historik.
Git kommer att förenkla historiken för oss. Steg 5 är nyckeln här. Vi ignorerade alla ändringar från djurgrenen. Git kommer att märka att filen i princip inte ändrades mellan steg 1 och steg 5, så den visar bara två historikposter.
Först skapar vi filen och lägger till den i vår lagringsplats:
> cd sample
> git init
> echo "some content" > test.txt
> git add test.txt
> git commit -m "Initial commit"
Nu bestämmer vi oss för att lägga till texten "åsnor" i filen i en djurgren:
> git checkout -b animals
> echo "donkeys" >> test.txt
> git commit -am "We have added an animal"
Medan vi experimenterar bestämmer vi oss för att vi kanske vill gå med frukt i filen i stället, så vi skapar en annan gren och lägger till texten "bananas" i slutet av filen i stället:
> git checkout main -b fruit
> echo "bananas" >> test.txt
> git commit -am "We have added a fruit"
När vi känner oss nöjda med våra förändringar bestämmer vi oss för att slå samman vår djurgren till huvudgrenen:
> git checkout main
> git merge animals
Nu ska vi titta på loggen för vår test.txt
fil:
> git log test.txt
commit 6b33d99b996c430a60c9552b79245d1aa8320339
Date: Mon Feb 15 10:45:33 2016 -0500
We have added an animal
commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
Date: Mon Feb 15 10:44:18 2016 -0500
Initial commit
Så långt så bra, eller hur? Ingenting ser ovanligt ut i våra loggutdata. Nu ska vi säga att vi ändrade oss och bestämde oss för att slå samman vår fruktgren:
>git merge fruit
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
En sammanslagningskonflikt. Efter lite övervägande bestämmer vi oss för att använda hela test.txt
filen från vår fruktgren. Vanligtvis använder du någon form av textredigerare eller kopplingsverktyg, men vi återskapar bara hela filen eftersom det bara är två rader:
> echo "some content" > test.txt
> echo "bananas" >> test.txt
> git commit -am "Fixed merge conflict"
Nu ska vi ta en titt på historiken för filen test.txt
:
> git log test.txt
commit fdd4dfd816c4efebc5bdb240f49e934e299db581
Date: Mon Feb 15 10:51:06 2016 -0500
We have added a fruit
commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
Date: Mon Feb 15 10:44:18 2016 -0500
Initial commit
Visst, vi ser inga ändringar från vårt första experiment i loggen, och vi ser inte heller vår sammanslagning! Är de kvar? Har Git helt eliminerat ändringarna?
> git log --full-history test.txt
Som du ser, även om det förenklade loggen full-history
utan flaggan, har Git sparat alla våra ändringar:
> commit 5d0bb77a24e265dc154654fb3b5be331b53bf977
Merge: 6b33d99 fdd4dfd
Date: Mon Feb 15 10:59:34 2016 -0500
Fixed merge conflict
commit fdd4dfd816c4efebc5bdb240f49e934e299db581
Date: Mon Feb 15 10:51:06 2016 -0500
We have added a fruit
commit 6b33d99b996c430a60c9552b79245d1aa8320339
Date: Mon Feb 15 10:45:33 2016 -0500
We have added an animal
commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
Date: Mon Feb 15 10:44:18 2016 -0500
Initial commit
Sammanfattning av git-historikförenkling
Saken med historieförenkling är att du för det mesta aldrig kommer att märka det. Men när en sammanslagningskonflikt går fel och du vill veta vad som hände kanske du tittar på git-logghistoriken och undrar vart dina ändringar har gått.
Istället för att få panik vet du att:
- Historikförenkling för filer aktiveras som standard
- Flaggan
--full-history
ger dig en mer omfattande filhistorik
Uppdatering: Sedan jag skrev den här artikeln har Azure DevOps Services introducerat ett antal fantastiska visningsalternativ för historik på webben. Det innebär att om du inte vill logga via kommandoraden kan du helt enkelt hämta filen som du vill visa historik för i utforskaren och du får nedanstående historikfilter där du kan ange enkla eller icke-enkla historikvyer:
(c) 2016 Microsoft Corporation. Med ensamrätt. Det här dokumentet tillhandahålls "i den mån det är". Information och vyer som uttrycks i det här dokumentet, inklusive URL och andra webbplatsreferenser, kan ändras utan föregående meddelande. Användande sker på egen risk.
Det här dokumentet ger dig inga juridiska rättigheter till någon immateriell rättighet i någon Microsoft-produkt. Du får kopiera och använda det här dokumentet som referens för interna syften.