När en buggfix behövs i en releasegren men resten av featuregrenen ska stanna kvar kan git cherry-pick flytta just den ändringen. Det skapar vanligtvis ett nytt commit på målgrenen, men resultatet beror på om ändringen redan finns där eller om den kommer från ett merge-commit.
Välj commit med omsorg och kontrollera målgrenen
- Ett commit: byt till målgrenen och kör
git cherry-pick. - Synlig spårning: använd
-xnär du flyttar en ändring mellan offentliga grenar. - Merge-commit: välj huvudlinje med
-m, annars kan Git inte avgöra vilken förälders ändringar som ska tillämpas. - Konflikt: lös filerna, stage:a dem och fortsätt med
--continue, eller avbryt med--abort.
Cherry-pick passar när bara en avgränsad ändring ska med
En hel featuregren kan innehålla halvfärdiga funktioner, medan releasegrenen bara behöver en säkerhetsfix. Med cherry-pick tillämpar Git ändringarna från ett valt commit på grenen du står på och skapar normalt ett nytt commit där. Övriga commits från källgrenen följer inte med.
Jag tycker att det här är ett bra precisionsverktyg för en tydlig backport eller en isolerad korrigering. Om målet däremot är att föra över grenens samlade utveckling är en merge oftast lättare att följa i historiken, eftersom cherry-pick inte i sig visar att det nya committet härstammar från källgrenens commit.
Byt gren först och kontrollera sedan det nya committet
Det går snabbt att rikta ändringen fel om terminalen står på fel gren. Börja med att kontrollera arbetskatalogen och branchens namn, och plocka sedan commit-hashen från loggen eller pull requesten.
git status
git switch release/2.x
git log --oneline feature/login
git cherry-pick -x abc1234git status hjälper dig att upptäcka lokala ändringar som kan störa operationen; Git kräver normalt en ren arbetskatalog. Flaggan -x lägger till ursprunglig commit-information i meddelandet när cherry-picken går igenom utan konflikt, vilket underlättar spårning mellan offentliga grenar. Kontrollera resultatet innan du pushar:
git show --stat --oneline HEAD
git statusOm du behöver ta flera commits kan du ange dem i önskad ordning. En vanlig miss är att anta att en intervallnotation alltid betyder varje commit mellan två punkter; syntaxen har Git-specifika regler, så granska först urvalet med git log --oneline. Git-dokumentationen för git-cherry-pick beskriver hur argument och intervall behandlas.
En releasefix kan bli ett nytt commit med egen identitet
Anta att main innehåller en fix i commit F, och release/2.x behöver samma kodändring. Efter cherry-pick på releasegrenen skapas normalt ett nytt commit, här kallat F′, med samma avsedda ändring men med releasegrenens tidigare commit som förälder. Det är alltså ändringens innehåll som kopieras, inte dess plats i historiken.
Den skillnaden märks senare om grenarna ska mergas: Git kan se den cherry-pickade fixen som ett separat commit i historiken, även om motsvarande kod redan finns. Därför skulle jag välja cherry-pick för en separat releasebackport, men merge om avsikten är att förena grenarnas fortsatta utveckling. Det valet minskar risken för förvirring när nästa releaseförgrening ska hanteras.
Merge-commits kräver att du väljer rätt förälder
Ett merge-commit har mer än en förälder, så Git kan inte veta vilken jämförelse som motsvarar ändringen du vill kopiera. Flaggan -m anger huvudlinjen, alltså vilken förälder Git ska jämföra merge-resultatet mot.
git show --no-patch --pretty=raw
git cherry-pick -m 1 Numret 1 är inte en allmän garanti för att rätt ändring följer med. Kontrollera föräldrarna och diffen först; väljer du fel huvudlinje kan resultatet innehålla motsatsen till det du avsåg. GitLabs guide till cherry-pick visar samma princip och beskriver hur du fortsätter efter en konflikt.
Konflikt eller tomt resultat pekar på olika problem
En konflikt betyder att Git inte kunde tillämpa ändringen automatiskt, ofta för att målgrenen har ändrat samma kodrader. Ett tomt resultat betyder i stället ofta att ändringen redan finns på målgrenen eller inte skulle ändra den. De två fallen kräver olika beslut.
| Situation | Trolig förklaring | Gör så här |
|---|---|---|
| Filer visar konfliktmarkörer | Ändringarna överlappar på målgrenen. | Redigera filerna, ta bort markörerna, kör git add och sedan git cherry-pick --continue. |
| Du vill avbryta en pågående cherry-pick | Ändringen passar inte längre eller konflikten bör hanteras på annat sätt. | Kör git cherry-pick --abort för att återgå till läget före operationen. |
| Git säger att inget finns att cherry-picka | Ändringen kan redan vara integrerad eller committet saknar ny effekt. | Granska historiken och jämför filinnehållet innan du försöker igen. |
| Du vill slå ihop flera ändringar till ett enda commit | Automatisk commit-skapning passar inte arbetsflödet. | Använd git cherry-pick -n , granska indexet och skapa sedan ett eget commit. |
När en konflikt uppstår stannar Git och lämnar operationen pågående tills du fortsätter, hoppar över det aktuella committet eller avbryter. Kör git status för att se vilka filer som behöver hanteras. Hoppa inte över ett commit av bara farten: senare commits i samma serie kan förutsätta att dess ändring redan finns.
Låt commit-historiken visa varför ändringen flyttades
En cherry-pick är som mest lättskött när commitet är litet, syftet är tydligt och målgrenen kontrolleras efteråt. Vid en backport mellan publika grenar ger -x en spårbar ledtråd; vid privat utveckling kan den raden vara onödig. Välj verktyg efter vad grenarna ska representera: en enskild korrigering lämpar sig ofta för cherry-pick, medan sammanhängande utveckling normalt hör hemma i en merge.
När kopieringen är klar, kör testerna som täcker ändringen och läs det nya commitets diff. Då blir den lilla, riktade flytten också begriplig för nästa person som öppnar releasehistoriken.