Dela via


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:

  1. Du skickar en ändring till en fil och sammanfogar sedan ändringen till main.
  2. Några av dina kollegor sammanfogar också sina grenar till main.
  3. Du kommer tillbaka en stund senare och märker att ändringarna saknas.
  4. 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:

Git-grenar

Som du ser kommer vi att:

  1. Skapa filen .
  2. Lägg till en rad i filen i en gren (djur).
  3. Lägg till en annan rad i filen i en annan gren (frukt).
  4. Slå samman grendjur tillbaka till huvuddjuren.
  5. Sammanfoga grenfrukten tillbaka till main och välj hela kopian av filen från fruktgrenen.
  6. 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:

Git-filter

(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.