Åtaganden är en av de viktigaste delarna i ett Git-arkiv, och mer så är engagemangsmeddelandet en livslogg för förvaret. När projektet / förvaret utvecklas över tiden (nya funktioner läggs till, buggar fixas, arkitektur refaktoreras), är kommuniceringsmeddelanden den plats där man kan se vad som har ändrats och hur. Så det är viktigt att dessa meddelanden återspeglar den underliggande förändringen på ett kort, exakt sätt.
Varför en meningsfull Git-engagemangshistorik är viktig
Vad gör Git-kommittén gör? är fingeravtrycken som du lämnar på koden du rör vid. Alla koder som du gör idag, ett år från och med nu när du tittar på samma förändring. Du skulle vara tacksam för ett tydligt, meningsfullt meddelande som du skrev, och det kommer också gör livet för dina medutvecklare enklare. När åtaganden isoleras baserat på sammanhang blir ett fel som introducerades av ett visst engagemang snabbare att hitta, och desto lättare är det att återställa det åtagande som orsakade felet i första hand. / p>
Medan vi arbetar med ett stort projekt, hanterar vi ofta många rörliga delar som uppdateras, läggs till eller tas bort. Att säkerställa att kommunicera meddelanden upprätthålls i sådana fall kan vara svårt, särskilt när utvecklingen sträcker sig över dagar, veckor eller till och med månader. Så för att förenkla ansträngningen att behålla koncis e commit-historia, den här artikeln kommer att använda några av de vanliga situationerna som en utvecklare kan möta när han arbetar med ett Git-arkiv.
- Situation 1: Jag måste ändra det senaste engagemanget
- Situation 2: Jag måste ändra ett specifikt engagemang
- Situation 3: Jag måste lägga till, ta bort eller kombinera åtaganden
- Situation 4: Min åtagandeshistorik gör inte känsla, jag behöver en ny start!
Men innan vi dyker in, låt oss snabbt gå igenom hur ett typiskt utvecklingsarbetsflöde ser ut i en vår hypotetiska Ruby-applikation.
Obs! Den här artikeln förutsätter att du är medveten om grunderna i Git, hur filialer fungerar, hur man lägger till obundna ändringar av en gren till scenen och hur man gör ändringarna. Om du är osäker på dessa flöden är vår dokumentation en bra utgångspunkt.
En dag i livet
Här arbetar vi med ett litet Ruby on Rails-projekt där vi måste lägga till en navigeringsvy på hemsidan och det innebär att uppdatera och lägga till flera filer. Nedan följer en stegvis uppdelning av hela flödet:
- Du börjar arbeta med en funktion med att uppdatera en fil ; låt oss kalla det
application_controller.rb
- Denna funktion kräver att du också uppdaterar en vy:
index.html.haml
- Du har lagt till en del som används på indexsidan:
_navigation.html.haml
- Stilar för sidan måste också uppdateras för att återspegla den partiella som vi lagt till:
styles.css.scss
- Funktionen är nu redo med önskade ändringar, det är dags att också uppdatera tester; filer som ska uppdateras är följande:
-
application_controller_spec.rb
-
navigation_spec.rb
-
- Tester uppdateras och passerar som förväntat, nu är det dags att göra ändringarna!
Eftersom alla filer tillhör olika arkitekturområden, åtar vi oss förändringarna isolerade från varandra för att säkerställa att varje åtagande representerar ett visst sammanhang och görs i en viss ordning. Jag brukar föredra backend – > frontend-ordning där de flesta backend-centrerade förändringar görs först, följt av mellanlagret och sedan av frontend-centrerade ändringar i Git-listan.
Nu när vi har gjort våra ändringar skapar vi en sammanslagningsförfrågan med filialen. När du har en sammanslagningsbegäran öppen granskas den vanligtvis av din kollega innan ändringarna slås samman till repo ”s master
gren. Låt oss nu lära oss vilka olika situationer vi kan hamna i under kodgranskning.
Situation 1: Jag måste ändra det senaste åtagandet
Föreställ dig ett fall där granskaren tittade på styles.css.scss
och föreslog en förändring. I ett sådant fall är det väldigt enkelt att göra ändringen, eftersom ändringar av formatmallen är en del av den senaste förpliktelsen på din gren. Så här kan vi hantera detta;
- Du gör direkt de nödvändiga ändringarna av
styles.css.scss
i din gren. - En gång du är klar med ändringarna, lägg till dessa ändringar i scenen; kör
git add styles.css.scss
. - När ändringarna är iscensatta måste vi lägga till dessa ändringar i vårt senaste engagemang; kör
git commit --amend
.- Uppdelning av kommando: Här ber vi kommandot
git commit
att ändra de ändringar som finns i steg till det senaste engagemanget.
- Uppdelning av kommando: Här ber vi kommandot
- Detta öppnar ditt senaste engagemang i din Git-definierade textredigerare som har kommuniceringsmeddelandet Lägg till stilar för navigering.
- Eftersom vi bara uppdaterade CSS-deklarationen behöver vi inte ändra meddelandet.Nu kan du bara spara och avsluta textredigeraren som Git öppnade för dig och dina ändringar kommer att återspeglas i engagemanget.
Eftersom du ändrade ett befintligt engagemang krävs dessa ändringar. för att tvingas pressas till din fjärranslutning med git push --force-with-lease <remote_name> <branch_name>
. Det här kommandot åsidosätter kommittén Add styles for navigation
på fjärrrepo med uppdaterad kommission som vi just gjorde i vårt lokala repo.
En sak att tänka på medan du tvingar på grenar är att om du arbetar på samma gren med flera personer, kan krafttryckning orsaka problem för andra användare när de normalt försöker trycka på sina ändringar på en avlägsen gren som har fått nytt kraft. Använd därför den här funktionen klokt. Du kan lära dig mer om Git force push-alternativ här.
Situation 2: Jag måste ändra ett specifikt engagemang
I den tidigare situationen var fixen ganska enkel eftersom vi var tvungna att ändra bara vårt senaste Git-åtagande, men tänk dig om granskaren föreslog att ändra något i _navigation.html.haml
. I det här fallet är det andra åtagandet uppifrån, så att ändra det kommer inte att vara lika direkt som det var i den första situationen. Låt oss se hur vi kan hantera detta:
När ett engagemang är tillverkad i en gren identifieras den av en unik SHA1-hashsträng. Tänk på det som ett unikt ID som skiljer ett åtagande från ett annat. Du kan se alla åtaganden tillsammans med deras SHA1-hash i en gren genom att köra git log
. Med detta skulle du se en utdata som ser ungefär så ut, där de senaste åtagandena är högst upp;
Det är här git rebase
kommandot spelar in. Närhelst vi vill redigera ett specifikt engagemang med git rebase
, måste vi först basera vår gren igen genom att flytta tillbaka HEAD till punkten precis före det engagemang vi vill redigera. I vårt fall måste vi ändra åtagandet som läser Page Navigation View
.
Här, märk hash of commit som ligger precis före det commit vi vill ändra; kopiera hash och utför följande steg:
- Förgrena filialen för att flytta att begå innan vårt målplikt; kör
git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
- Kommandouppdelning: Här kör vi Git ”s
rebase
kommando med interaktivt läge med tillhandahållen SHA1-hash som åtagande att rebase till.
- Kommandouppdelning: Här kör vi Git ”s
- Detta kommer att köra rebase-kommandot för Git i interaktivt läge och öppnar din textredigerare som visar alla dina åtaganden som kom efter det åtagande du satsade på . Det kommer att se ut så här:
Lägg märke till hur varje engagemang har ett ord pick
framför det och i innehållet nedan finns alla möjliga nyckelord vi kan använda. Eftersom vi vill redigera ett engagemang måste vi ändra pick 4155df1cdc7 Page Navigation View
till edit 4155df1cdc7 Page Navigation View
. Spara ändringarna och avsluta redigeraren.
Nu baseras din filial till tidpunkten precis före det åtagande du gjorde som innehöll _navigation.html.haml
. Öppna filen och utför önskade ändringar enligt recensionens feedback. När du är klar med ändringarna, stegvisa dem genom att köra git add _navigation.html.haml
.
Eftersom vi har iscensatt ändringarna är det dags att flytta gren HEAD tillbaka till commit som vi ursprungligen hade (samtidigt som vi inkluderade de nya ändringarna som vi lagt till), kör git rebase --continue
, detta öppnar din standardredigerare i terminalen och visar dig kommuniceringsmeddelandet som vi redigerade under rebase; Page Navigation View
. Du kan ändra detta meddelande om du vill, men vi skulle lämna det som det är för tillfället, så spara och avsluta redigeraren. Vid den här tiden spelar Git upp alla åtaganden som följde efter att du just redigerat och nu är grenen HEAD
tillbaka till det bästa engagemanget som vi ursprungligen hade, och det inkluderar också de nya ändringarna du gjorde i ett av åtagandena.
Eftersom vi återigen modifierade ett engagemang som ”redan finns i fjärranslutning, behöver vi kraft trycka på den här grenen igen med git push --force-with-lease <remote_name> <branch_name>
.
Situation 3 : Jag måste lägga till, ta bort eller kombinera åtaganden
En vanlig situation är när du har gjort flera åtaganden bara för att fixa något som begåtts tidigare. Låt oss nu minska dem så mycket vi kan och kombinera dem med de ursprungliga åtagandena.
Allt du behöver göra är att starta den interaktiva rebasen som du skulle göra i de andra scenarierna.
Tänk dig nu att du vill kombinera alla dessa korrigeringar i c22a3fa0c5c Render navigation partial
. Du behöver bara:
- Flytta korrigeringarna uppåt så att de ligger precis under det engagemang du vill behålla till slut.
- Ändra
pick
tillsquash
ellerfixup
för var och en av korrigeringarna.
Obs: squash
behåller kommit-meddelandena i beskrivningen. fixup
kommer att glömma fix-meddelandets meddelanden och behålla originalet.
Du kommer att sluta med något så här:
Spara ändringarna, avsluta redigeraren , och du är klar! Detta är den resulterande historiken:
Som tidigare är allt du behöver göra nu git push --force-with-lease <remote_name> <branch_name>
och ändringarna är uppe.
Om du vill ta bort engagemang från filialen helt, istället för squash
eller fixup
, skriv bara drop
eller radera bara den raden.
Undvik konflikter
För att undvika konflikter, se till att åtagandena ”flyttar upp på tidslinjen är inte vidrör samma filer som berörs av de åtaganden som finns kvar efter dem.
Pro-tip : Snabbkorrigeringar
Om du vet exakt vilket engagemang du vill fixa, behöver du inte slösa hjärncykler när du begår att tänka på bra tillfälliga namn för ”Fix 1”, ”Fix 2”, …, ”Fix 42”.
Steg 1: Möt --fixup
När du har iscensatt ändringarna för att fixa vad som än behöver fixas, bara Git gör alla ändringar så här:
(Observera att detta är hash för kommittén c22a3fa0c5c Render navigation partial
)
Detta kommer att generera detta meddelande: fixup! Render navigation partial
.
Steg 2: Och sidokick --autosquash
Enkel interaktiv rebase. Du kan få git
placera fixup
s på rätt plats.
git rebase -i 4155df1cdc7 --autosquash
Historiken visas så:
Redo för dig att bara granska och fortsätt.
Om du känner dig äventyrlig kan du göra en icke-interaktiv rebase git rebase --autosquash
, men bara om du gillar att leva farligt, som du ” har ingen möjlighet att granska de squashar som görs innan de ”tillämpas igen.
Situation 4: My Git commit history betyder inte meningsfullt, jag behöver en ny start!
Om vi ”arbetar med en stor funktion, det är vanligt att ha flera fixup- och recension-feedback-förändringar som görs ofta. I stället för att ständigt omgränsa filialen kan vi lämna rensningen av åtaganden till slutet av utvecklingen.
Det är här det är extremt praktiskt att skapa patchfiler. I själva verket var patchfiler det primära sättet att dela kod via e-post medan man samarbetade på stora open source-projekt innan Git-baserade tjänster som GitLab var tillgängliga för utvecklare. Tänk dig att du har en sådan gren (t.ex.; add-page-navigation
) där det finns massor av åtaganden som inte förmedlar de underliggande förändringarna tydligt. Så här kan du skapa en korrigeringsfil för alla ändringarna du gjorde i den här grenen:
- Det första steget för att skapa korrigeringsfilen är att se till att din filial har alla ändringar från
master
filial och har inga konflikter med samma. - Du kan köra
git rebase master
ellergit merge master
medan du kontrollerar ute iadd-page-navigation
gren för att få alla ändringar frånmaster
till din gren. - Skapa nu korrigeringsfilen ; kör
git diff master add-page-navigation > ~/add_page_navigation.patch
.- Uppdelning av kommando: Här använder vi Gits diff-funktion och ber om en skillnad mellan
master
gren ochadd-page-navigation
gren och omdirigerar utdata (via>
symbol) till en fil med namnetadd_page_navigation.patch
i vår oss hemkatalog (vanligtvis~/
i * nix-operativsystem).
- Uppdelning av kommando: Här använder vi Gits diff-funktion och ber om en skillnad mellan
- Du kan ange vilken sökväg du vill behålla den här filen in och filnamnet och tillägget kan vara vad du vill.
- När kommandot har körts och du inte ser några fel genereras korrigeringsfilen.
- Kassa nu
master
gren; körgit checkout master
. - Ta bort grenen
add-page-navigation
från lokal repo; körgit branch -D add-page-navigation
. Kom ihåg att vi redan har ändringar av den här grenen i en skapad korrigeringsfil. - Skapa nu en ny gren med samma namn (medan
master
är utcheckad); körgit checkout -b add-page-navigation
. - Vid denna tidpunkt är det här en ny gren och har inga av dina ändringar.
- Slutligen, använd dina ändringar från korrigeringsfilen;
git apply ~/add_page_navigation.patch
. - Här tillämpas alla dina ändringar i en gren och de kommer att se ut som obundna, som om alla dina ändringar där gjort, men ingen av ändringarna gjordes faktiskt i grenen.
- Nu kan du fortsätta och begå enskilda filer eller filer grupperade efter påverkningsområde i den ordning du vill ha med kortfattade meddelanden.
Som med tidigare situationer ändrade vi i princip hela grenen, så det är dags att tvinga push!
Slutsats
Även om vi har täckt över de vanligaste och grundläggande situationerna som uppstår i ett dagligt arbetsflöde med Git, är omskrivning av Git-historia ett stort ämne och som du blir bekant med ovanstående tips kan du lära dig mer avancerade begrepp kring ämnet i Git Official Documentation. Happy git ”ing!
Foto av pan xiaozhen på Unsplash