Hoppa till innehåll

Merge commit, squash eller rebase?

↑

Vad betyder “Choose a branch to merge into XXX”?

Section titled “Vad betyder “Choose a branch to merge into XXX”?”

XXX är destinationen, vanligtvis din nuvarande lokala gren. Grenen du väljer är källan. Om du står på feature/inventory och väljer main tar du in mains ändringar i feature-grenen. För att leverera funktionen till main måste destinationen i stället vara main.

Kontrollera destination, källa, förhandsvisning och metod innan du bekräftar. En lokal operation ändrar ditt lokala repository. Den pushar inte automatiskt, skapar ingen PR/MR, ger inga godkännanden och driftsätter inget. En senare push kan utlösa driftsättning om projektet är konfigurerat så.

Menyns Create a merge commit, Squash and merge och Rebase väljer hur historiken kombineras. Rebase-dialoger skiljer sig: GitHub Desktops separata Rebase Current Branch flyttar den nuvarande grenens commits till en vald bas. Läs förhandsvisningen i stället för att anta att alla rebase-knappar arbetar i samma riktning.

main är ett exempel; använd master eller projektets verkliga målgren. Se Git-begrepp.

Metod Vad händer? Fördelar Nackdelar / när bör du undvika den?
Create a merge commit Förenar historikerna med en commit med två föräldrar Bevarar ursprungliga commit-ID:n och en tydlig integrationspunkt; bra för delade eller långlivade grenar Fler merge-commits och en mer förgrenad graf; konflikter måste fortfarande lösas
Squash and merge Sparar källans samlade ändringar som en ny commit på destinationen En logisk funktion/fix blir enkel att läsa och vanligtvis att återställa Destinationen saknar de individuella stegen och ursprunglig härstamning; olämpligt för återkommande synkning av långlivade grenar
Rebase / rebase and merge Applicerar commits på en ny bas, vanligtvis med nya ID:n; integration kan sedan ske med fast-forward Linjär historik med separata meningsfulla steg Skriver om de flyttade committens historik; konflikter kan återkomma per commit; kräver samordning när andra använder dem

Praktisk utgångspunkt: välj en granskad PR/MR med squash för en funktion med många tillfälliga WIP-commits. Behåll merge-commits när gemensam härstamning eller integrationspunkter behövs. Välj rebase för en genomtänkt serie när teamet accepterar omskrivningen. Projektets regler går före personliga grafpreferenser.

Detta är alternativ, inte tre operationer som ska köras efter varandra. Bokstäverna står för commit-ID:n; D' och E' är ersättningscommits.

Before: both branches changed since A
A---B---C main (destination)
\
D---E feature/inventory (source)
After: M has parents C and E
A---B---C---M main
\ /
D------E feature/inventory

Båda utvecklingsspåren syns. M sparar det sammanslagna resultatet, inklusive eventuella konfliktlösningar. D och E behåller sina ID:n och blir förfäder till main.

Välj när: flera delar källgrenen, långlivade grenar regelbundet integreras eller du vill se när funktionen kom in i målgrenen. Det bevarar också en användbar serie commits utan omskrivning.

Avvägningar: täta sammanslagningar kan göra grafen rörig. Att återställa en merge kräver val av huvudförälder och fungerar inte som en vanlig commit med en förälder. En merge-commit visar en integrationspunkt men bevisar inte kodgranskning.

Vanlig git merge kan göra fast-forward när destinationen saknar eget arbete: bara grenpekaren flyttas. --no-ff begär en uttrycklig merge-punkt när det finns ändringar att integrera. Redan integrerat arbete behöver inte skapa någon ny commit.

After: S contains the combined feature change
A---B---C---S main
\
D---E feature/inventory (original source)

S är en ny commit med de integrerade ändringarna. D och E finns kvar på källgrenen men läggs inte till som förfäder till main genom S. Squash raderar inte dessa commits överallt och tar inte automatiskt bort grenen.

Välj när: en färdig funktion innehåller commits som “lägg till UI”, “rätta stavfel” och “åtgärda granskning”. Beskriv den färdiga ändringen, orsaken och tillhörande PR/MR i S:s meddelande.

Avvägningar: målgrenens historik förlorar delstegen, vilket ger mindre detalj vid felsökning commit för commit. Var noga med medverkandes attribution i slutmeddelandet. Att återställa S tar tillbaka hela ändringen, men senare redigeringar kan fortfarande ge konflikter.

Utgå från uppdaterad målgren för nytt arbete. Upprepade squash-merges från samma källgren kan visa gamla commits igen och ge upprepade konflikter eftersom historikerna inte förenades. Undvik att squasha main in i en långlivad feature-gren bara för att uppdatera den.

After replaying D/E onto C and fast-forwarding main
A---B---C---D'---E' main

D’ och E’ återger ändringarna med en annan föräldrahistorik. I detta förgrenade exempel får de nya ID:n; mains befintliga A/B/C ligger kvar. Exakt var källgrenen pekar efteråt beror på lokal rebase respektive värdtjänstens merge-funktion.

Välj när: varje commit är begriplig och användbar, du vill ha linjär historik och du kontrollerar grenen som skrivs om. Att uppdatera en egen opublicerad feature-gren före granskning är ett vanligt exempel.

Avvägningar: samma område kan ge konflikter flera gånger under serien. Befintliga länkar, signaturer och kollegors grenar kan hänvisa till gamla ID:n. Vanlig rebase bevarar inte heller merge-topologin som standard. Den kör inga tester och garanterar inte att det omskrivna resultatet fungerar.

Lokal git rebase skriver om grenen som rebaseras; den slår inte automatiskt ihop den med målgrenen. Fast-forward-integration är ett separat steg. GitHubs Rebase and merge gör även integrationen och skapar alltid nya commit-ID:n, även när en lokal rebase kunde ha varit verkningslös. Rebase:a inte delad main enbart för en snyggare graf.

En pull request (PR) på GitHub eller merge request (MR) på GitLab är samarbetsprocessen kring en föreslagen integration. Du kan godkänna en PR/MR och sedan använda merge-commit, squash eller linjär integration enligt projektets inställningar.

Arbetsflöde Vad får du? Vad måste du hantera?
Lokal integration Snabba offlineförsök; uppdatera egen feature-gren; prova samverkan före granskning Köra tester själv; den lokala operationen skapar varken granskningshistorik eller serverbaserade merge-krav
Integration via PR/MR Föreslagen diff, diskussion, granskning, ärendelänkar och CI-resultat; konfigurerade regler kan kräva kontroller Publicera grenen, invänta krav på tester/granskning och välja tillåten integrationsmetod

Använd PR/MR för gemensamma integrationsgrenar när granskning, samordning, spårbarhet eller obligatoriska tester behövs. Även ensamprojekt kan vinna på en draft som samlar diff, motivering och CI-resultat.

Använd lokal merge/rebase för att uppdatera din gren, kombinera opublicerade experiment eller testa integration på en tillfällig gren. Direkt integration och push kan passa ett litet ensamprojekt när policyn tillåter det och du själv utför kontrollerna. Du avstår från PR/MR-processens granskningspunkt; operationen blir inte tekniskt säkrare och testar inte sig själv.

Grenskydd kan stoppa direktpush, kräva en viss historik eller kräva PR/MR. En lyckad lokal merge kringgår inte reglerna. Även en PR/MR behöver verkliga konfigurerade kontroller och granskare; att enbart öppna den säkerställer ingen kvalitet.

GitLab: merge-metod och squash är separata projektinställningar. En MR kan ge både en squash-commit och en merge-commit. GitLabs merge-commit, semi-linjära och fast-forward-policyer motsvarar inte varje GitHub/Desktop-knapp direkt. Kontrollera projektinställningar och resultatets historik.

Ditt mål Destination / nuvarande gren Källa / bas Vanligt arbetssätt
Uppdatera min feature med senaste main Din feature-gren Uppdaterad main Merge av main till delad feature-gren, eller rebase av privat feature på main
Leverera min färdiga funktion main eller release-grenen Din feature Öppna PR/MR och välj en tillåten integrationsmetod
Prova två funktioner utan publicering Tillfällig integrationsgren Respektive feature-gren Lokala merges, tester och ett medvetet beslut att behålla eller ta bort testgrenen

Merge av main till en delad feature-gren behåller befintliga commit-ID:n. Rebase av en redan publicerad feature kan kräva en forcerad uppdatering av just den grenen. Samordna först; force-pusha inte skyddad main. En lease kan stoppa en oväntad fjärrspets men ersätter inte kommunikation.

Git-kommandona fungerar i PowerShell eller Git Bash på Windows 10/11 samt Bash på Linux, med Git installerat. Ingen kommandotolksspecifik variabeltilldelning används. Officiella GitHub Desktop stöder Windows/macOS; Linuxanvändare kan följa CLI-exemplen.

Använd ett separat övningsrepository med befintlig destination integration-demo och källa feature/inventory enligt startgrafen. Välj ett alternativ från samma utgångsläge. Exemplen pushar inget.

Preserve the feature's ancestry
git switch integration-demo
git merge --no-ff feature/inventory
Combine the feature into one commit
git switch integration-demo
git merge --squash feature/inventory
git diff --cached
git commit -m "Add inventory filtering"
Replay a private feature, then integrate it
git switch feature/inventory
git rebase integration-demo
git switch integration-demo
git merge --ff-only feature/inventory

För squash granskar du staged diff och kör projektets kontroller före commit. Testa slutresultatet före delning oavsett metod. Kontrollera sedan git log --graph --oneline --decorate --all och git status.

Om vanlig merge stannar med konflikter löser och stage:ar du filerna före slutförandet, eller kör git merge --abort medan merge-operationen pågår. Vid rebase löser/stage:ar du och kör git rebase --continue, alternativt git rebase --abort. Squash skapar inte samma merge-tillstånd: anta inte att merge-abort återställer dess staged ändringar. Se konflikter och återställning och kontrollera läget innan något kastas bort.

Åtta “WIP/fix”-commits hör till en buggfix som behöver granskning före main. Vad väljer du?

  1. Lokal merge för att hoppa över granskningen.
  2. PR/MR och därefter squash om projektets regler tillåter det.
  3. Rebase av delad main på feature-grenen.

Svar: 2. Förfrågan ger granskningsprocessen och squash sparar en färdig fix. Om de åtta committarna i stället är en meningsfull serie vars härstamning ska bevaras väljer du merge-commit. Behövs serien i linjär historik och omskrivning är acceptabel kan rebase passa.