Kezdők útmutatója az interaktív újraszabályozáshoz

Eredetileg megjelent a Stride által 2018. január 16-án 52,731 olvasott

Az év elején csináltam először interaktív rebase-t és lenyűgözött, hogy mit lehet vele csinálni. Eleinte kicsit bonyolultnak is találtam. Remélhetőleg ez az útmutató segít eloszlatni némi bizonytalanságot körülötte.

Amellett, mivel ez olyan erős, és lényegében újraírhatod a történelmet, egy kis figyelmeztetés, mielőtt elkezdjük: Sokféle nézet létezik a Gitről és arról, hogy az újraalapozás jó ötlet-e vagy sem. Ez a bejegyzés nem fog belemerülni ezekbe a vitákba, és pusztán az interaktív rebasing használatának alapjait kívánja végigjárni.

TL;DR

  • Az interaktív rebasing sokféleképpen használható a commitok módosítására, például szerkesztésre, törlésre és squashelésre.
  • Hogy megmondja a Gitnek, hol kezdje az interaktív újraalapozást, használja a módosítandó commitot közvetlenül megelőző commit SHA-1-jét vagy indexét.
  • Az interaktív újraalapozás során, amikor a Git szünetet tart a szerkesztésre megjelölt commitnál, a munkafolyamat nem különbözik a normál commit folyamatától – a fájlokat szakaszolja, majd commitolja. Az egyetlen különbség, hogy a git commit helyett a git commit --amend parancsot használod.
  • Az interaktív újraszerkesztés új SHA-1-eket hoz létre, ezért a legjobb, ha az interaktív újraszerkesztést olyan commitoknál használod, amelyeket nem toltál el egy távoli ágba.

A probléma

Ebben a példában egy olyan helyzetet dolgozunk fel, amikor egy feature branchben dolgozunk, és van néhány commit, amit szeretnénk módosítani vagy törölni. Így néz ki a git naplónk:

A fenti git naplóból itt van a két commit, amit módosítani szeretnénk:
4a4d705 – Ebben a commitban véletlenül elkövettünk egy összeolvadási konfliktust
6c01350 – Ebben a commitban eltávolítottuk az összeolvadási konfliktust

Azt szeretnénk tenni, hogy visszamegyünk az időben az 4a4d705-be, eltávolítjuk az összeolvadási konfliktust a commitban, majd töröljük az 6c01350-t, mivel az összeolvadási konfliktus megoldódott, és már nincs szükségünk erre a commitra. Ez két okból is javulást jelent majd a commit-előzményekben:

  1. Nem lesznek törött commitjaink (egyesítési konfliktusok)
  2. Kizárólag értelmes commitjaink lesznek, nem lesznek olyan commitjaink, amelyek kizárólag egy kihagyott egyesítési konfliktus javításához kapcsolódnak

A megoldás

Ez a helyzet jó jelölt az interaktív újraszerkesztésre. Scott Chacon a Pro Git című könyvében az interaktív újraszerkesztést a következőképpen írja le: “Néha a javított dolgot … nem lehet módosítani az általa javított nem egészen tökéletes commithoz, mert az a commit mélyen el van temetve egy patch-sorozatban. Pontosan erre való az interaktív rebase: használd a rengeteg , commitok átrendezésével és szerkesztésével, valamint több commit egybe gyömöszölésével.”

Milyen commitokat akarunk módosítani?

Az interaktív rebase elindításához meg kell mondanunk a Gitnek, hogy mely commitokat akarjuk módosítani. Ezt úgy tesszük meg, hogy hivatkozunk a legkorábbi commitot közvetlenül megelőző commitra, amelyet módosítani szeretnénk. Vagy egyszerűen fogalmazva, Scott Chacon szerint “az utolsó commitra hivatkozunk, amelyet úgy akarunk megtartani, ahogy van”.

Nézzük meg a példánkat, hogy jobban megértsük. Kétféleképpen hivatkozhatunk erre a commitra:
Az SHA-1 alapján – Az utolsó commit, amelyet úgy akarunk megtartani, ahogy van, SHA-1 értéke 528f82e így ezt átadhatjuk az interaktív rebase parancsunknak.
By Index – Az utolsó commit, amit meg akarunk tartani as-is, index pozíciója 3 (a Git nulla alapú indexelést használ), így átadhatjuk a HEAD~3-ot az interaktív rebase parancsunknak.

Megjegyzés – Ha csak néhány commit van, amire interaktív rebase-t akarsz csinálni, az index használata valószínűleg egyszerűbb a legtöbb ember számára. Ha azonban sok commitod van, az SHA-1 használata valószínűleg egyszerűbb, így nem kell végigszámolnod a git naplót.

Interaktív rebasing indítása

Példánk alapján vagy:

$ git rebase -i 528f82e

Or

$ git rebase -i HEAD~3

futtatjuk, ami megnyitja ezt az ablakot a Vimben:

Figyeljük meg, hogy a commitok a git loggal ellentétes sorrendben vannak. A git logban a legfrissebb commit van felül. Ebben a nézetben a legfrissebb commit alul van. Figyeld meg azt is, hogy az alábbi megjegyzések hasznos listát adnak az egyes commitokhoz használható érvényes parancsokról.

Ha nem ismered a Vim-et, csak kattints minden egyes szóra pick, amit szerkeszteni szeretnél, majd nyomd meg a <i> billentyűt (a beszúrási módhoz). Ha végzett a gépeléssel, nyomja meg a <esc> billentyűt a beszúrási módból való kilépéshez.

Példánkban a módosítani kívánt commithoz a edit parancsot, a törölni kívánt commithoz pedig a drop parancsot módosítottuk. Ezután a :wq parancsot futtatjuk a mentéshez és kilépünk a Vim ablakból.

A commit módosítása

A terminálban a következő üzenetet látjuk:

Ez érthető, hogy a 4a4d705-nél megálltunk. Ez a legrégebbi commit abban a commit-sorozatban, amelyet módosítani szeretnénk. Ezzel a commit-tal kezdünk, és végigmegyünk az egyes commitokon a legutóbbiig.

Emlékeztetőül: 4a4d705 volt az a commit, amelyikben az egyesítési konfliktus volt, amit véletlenül lekötöttünk. Amikor megnyitjuk a szerkesztőnket, ott látjuk az egyesítési konfliktust:

Az egyesítési konfliktust tehát kijavítjuk a fájlban, de most mit tegyünk? Ha kétségeink vannak, git status:

Cool! Ez valóban hasznos. Látjuk, hogy jelenleg a 4a4d705-t szerkesztjük, és látjuk a következő két commitot, amelyekkel ez után a következő után kell cselekednünk.

Az üzenet többi része egy ismerős munkafolyamatot magyaráz el nekünk. A Git közli velünk, hogy ha módosítani akarjuk a git commit --amend commitot, akkor futtassuk a git commit --amend-et. Ez lényegében úgy fog működni, mint a tipikus git commit, amit egy normál munkafolyamatban használunk. Ennek az üzenetnek az alján látjuk, hogy a fájlunk módosult, tükrözve a módosításokat, amelyeket az imént végeztünk az egyesítési konfliktus megszüntetése érdekében. Át kell rendeznünk a fájlt, mielőtt commitolnánk. Ez nem különbözik a normál munkafolyamatoktól.

Mindössze annyit kell tennünk, hogy git add tempChanger.js a szerkesztett fájlt színpadra állítjuk, majd git commit --amend a színpadra állított fájlt rögzítjük! Ezután ismét megnyílik egy Vim ablak a commit üzenettel:

Módosíthatjuk a commit üzenetet, vagy hagyhatjuk úgy, ahogy van. Válasszuk azt, hogy a commit üzenetet változatlanul hagyjuk, és írjuk be a :wq billentyűt a mentéshez és az ablakból való kilépéshez.

Már megszerkesztettük a régi commitunkat. És most mi lesz? Futtassuk a git status:

Interaktív újraindítás folytatása

Nincs más változtatnivalónk a commitban, tehát folytassuk!

Futtassuk a git rebase --continue és a következő üzenetet látjuk:

Woah, kész vagyunk? De mi van azzal a másik két commit-al? Nos, a következő commit, amire cselekedni kellett, az 6c01350 volt. Ezt a commitot törlésre jelöltük (drop), amikor elindítottuk az interaktív újraindítást. A Git automatikusan törölte, és áttért a következő commitra, 41aa9d2-re. Ezt a commitot nem módosítottuk a kezdeti interaktív újraindítás során. Az alapértelmezett parancsa pick volt, ami azt jelenti, hogy a commitot használni fogjuk. A Git alkalmazta ezt a commitot, és mivel ez volt az utolsó commit, az interaktív újraindítás befejeződött.

Megjegyezzük, ha több commitunk lett volna, amit szerkeszteni kell, akkor egyszerűen áttértünk volna a következő commitra, és elkezdtük volna a módosítási folyamatot, ahogy fentebb tettük. A ciklus addig folytatódik, amíg nincs több commit.

A kilökés gomb

Azt érdemes megjegyezni, hogy ha az interaktív újraindításunk bármelyik pontján elrontunk valamit, és nem tudjuk, hogyan javítsuk ki, bármikor megszakíthatjuk. Bármelyik ponton lefuttathatjuk a git rebase --abort parancsot a terminálban, és az interaktív rebase megszakad a változtatások mentése nélkül. Ekkor újra kell kezdenünk az interaktív újraindítást.

Az interaktív újraindítás után

A git naplónk most így néz ki:

Láthatod, hogy néhány dolog megváltozott az interaktív újraindítás megkezdése előttihez képest:

  • Már nincs meg a 6c01350 commitunk a “Remove merge conflict” commit üzenettel. Ez az a commit, amelyet az interaktív újraalapozás során töröltünk.
  • Az általunk szerkesztett 4a4d705 commitunknak más SHA-1-je van, 2b7443d.
  • Az eredeti git naplóban szereplő legfrissebb commitunknak, 41aa9d2-nek szintén új SHA-1-je van, 2b95e92. Ez a commit nem változott, hanem egyszerűen az előtte lévő 2b7443d.

Az interaktív újraszerkesztés mellékhatásai

A git naplónk két legfrissebb commitja esetében, mivel új SHA-1-ek vannak, a Git teljesen új commitoknak tekinti őket. Ez még az utolsó commitunkra, 2b95e92 is igaz, ahol sem a commit üzenet, sem a fájlok nem változtak egyáltalán. Ez felvet egy fontos pontot az interaktív újraszerkesztéssel kapcsolatban: Ha módosítunk egy commitot, annak a commitnak és az azt követő commitoknak új SHA-1-ek lesznek.

Ez nem befolyásol semmit, ha az általunk módosított commitok nem kerültek át egy távoli ágba. Ha azonban valóban elvégeztél egy interaktív rebase-t olyan commitokon, amelyeket már egy távoli ágba toltál, majd újra toltad az ágadat, akkor azt fogod látni:

Technikailag megkerülheted ezt a git push --force használatával, de ez nagyon veszélyes. Ha a távoli ágon vannak commitok másoktól, de a helyi ágadon még nincsenek ilyen commitok, akkor gyakorlatilag törlöd az ő commitjaikat.

Egy másik megoldás a git push --force-with-lease használata, ami csak a te commitjaidat módosítja, de a másokéit nem, bár ez is problémás lehet. Például, ha egy másik fejlesztő már rendelkezik azokkal a commitokkal, amelyek új SHA-1-eket kaptak a helyi ágán, akkor amikor a távoli ágat húzza, összeolvadási konfliktusai lesznek ezekkel a commitokkal.

Az, hogy mikor érdemes használni az --force-with-lease-t, meghaladja ennek a blogbejegyzésnek a kereteit, de a legjobb lenne, ha konzultálnál a csapatod többi tagjával, mielőtt ezt tennéd. A git push --force-with-lease-ról bővebben itt olvashatsz.

A legfontosabb tanulság ebből a szakaszból az, hogy sokkal egyszerűbb és biztonságosabb az interaktív újraszerkesztést használni olyan commitokon, amelyeket még nem tettek át egy távoli ágba.

Az írás szerzője Blake DeBoer. Eredetileg a Dev.to

Senior, Lead, or Principal developer in NYC? A Stride felvételt hirdet! Szeretnéd szintre emelni a tech csapatodat? Nézze meg, hogyan csináljuk! www.stridenyc.com

Tags

Join Hacker Noon

Létrehozza ingyenes fiókját, hogy feloldja az egyéni olvasási élményt.

Leave a Reply