Git Squash forklart

Hva er Git Squash?

En av tingene som utviklere hører ganske ofte angående deres pull-forespørsler, er noe som "Det ser bra ut for meg, vær så snill og slå sammen". Den morsomme delen er at det ikke er noen slik kommando som git squash(med mindre du oppretter et alias til den).

Å squashtrekke forespørsel betyr ofte å komprimere alle forpliktelsene i denne forespørselen til ett (sjelden til et annet nummer) for å gjøre den mer kortfattet, lesbar og ikke forurense hovedgrenens historie. For å oppnå dette må en utvikler bruke interaktiv modus for Git Rebase-kommandoen.

Ofte når du utvikler noen nye funksjoner, ender du opp med flere intermitterende forpliktelser i historien din - du utvikler deg tross alt. Det kan bare være noen skrivefeil eller trinn til endelig løsning. Det meste av tiden nytter det ikke å ha alle disse forpliktelsene i den endelige offentlige versjonen av koden din, så det er mer fordelaktig å ha dem alle komprimert til en, enkelt og endelig versjon.

Så la oss anta at du har følgende forpliktelseslogg i grenen du vil slå sammen som en del av pull-forespørsel:

$ git log --pretty=oneline --abbrev-commit 30374054 Add Jupyter Notebook stub to Data Science Tools 8490f5fc Minor formatting and Punctuation changes 3233cb21 Prototype for Notebook page

Det er klart at vi foretrekker å bare ha en forpliktelse her, siden det ikke er noen fordel med å vite hva vi startet med å skrive og hvilke skrivefeil vi fikset der senere. Bare det endelige resultatet er viktig.

Så det vi gjør er å starte en interaktiv rebase-økt fra gjeldende HEAD (commit 30374054 ) for å begå 3233cb21 , med den hensikt å kombinere de tre siste forpliktelsene til en:

$ git rebase -i HEAD~3

Det vil åpne en redaktør med noe sånt som følgende:

pick 3233cb21 Prototype for Notebook page pick 8490f5fc Minor formatting and Punctuation changes pick 30374054 Add Jupyter Notebook to Data Science Tools # Rebase # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

Som alltid gir Git oss en veldig fin hjelpemelding der du kan se squashalternativet vi leter etter.

For øyeblikket sier instruksjonene for interaktiv rebase til pickhver spesifiserte forpliktelse og bevarer den tilsvarende forpliktelsesmeldingen. Det vil si - ikke endre noe. Men vi vil bare ha en forpliktelse til slutt.

Så du kan ganske enkelt redigere teksten i redigeringsprogrammet og erstatte det pickmed squash(eller bare s) neste gang hver forpliktelse vi vil bli kvitt og lagre / avslutte redigereren. Det kan se slik ut:

s 3233cb21 Prototype for Notebook page s 8490f5fc Minor formatting and Punctuation changes pick 30374054 Add Jupyter Notebook to Data Science Tools

Når du lukker redaktøren din etter at du har lagret denne endringen, åpnes den med en gang og vil foreslå at du velger og omformulerer disse forpliktende meldingene. Noe sånt som dette:

# This is a combination of 3 commits. # The first commit's message is: Prototype for Notebook page # This is the 2nd commit message: Minor formatting and Punctuation changes # This is the 3rd commit message: Add Jupyter Notebook to Data Science Tools # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit.

På dette punktet kan du slette alle meldingene du ikke vil inkludere i den endelige forpliktelsesversjonen. Du kan også omformulere dem eller bare skrive forpliktende meldinger fra bunnen av.

Bare husk at den nye versjonen vil inneholde alle linjene som ikke starter med #tegnet. Nok en gang, lagre og avslutt redaktøren.

Terminalen din skal nå vise en suksessmelding, inkludert Successfully rebased and updated og git-loggen skal vise en fin og komprimert historie med bare en forpliktelse. Alle mellomliggende forpliktelser er borte, og vi er klare til å slå sammen!

Advarsel om misforhold mellom lokale og eksterne begivenheter

Denne operasjonen er litt farlig hvis du har filialen din allerede publisert i et eksternt arkiv - du endrer allikevel forpliktelseshistorikk. Så det er best å gjøre squashoperasjonen på en lokal avdeling før du presser .

Noen ganger blir det allerede presset - hvordan vil du tross alt opprette en pull-forespørsel? I dette tilfellet må du tvinge endringene på den eksterne grenen etter å ha gjort squashing, siden din lokale historie og grenhistorie i det eksterne depotet er forskjellige:

$ git push origin +my-branch-name

Gjør ditt beste for å være sikker på at du er den eneste som bruker denne eksterne grenen på dette tidspunktet, ellers vil du gjøre den andre utviklerens liv vanskeligere når de har et historisk misforhold. Men siden squashing vanligvis blir gjort som den endelige operasjonen på en gren før du blir kvitt den, er det vanligvis ikke så bekymringsfullt.