Vytvoření opravy v GIT je skvělý způsob, jak sdílet změny, které ještě nejste připraveni předat veřejnosti větev projektu.
Abychom lépe porozuměli tomu, jak vytvoříme opravu, pojďme nejprve trochu probrat, jak GIT ukládá změny.
Pokud jste v GITu nováčkem, nainstalujte si git a získejte skokový start z tohoto úvodního článku GIT.
Při prvním odevzdání souboru do projektu v GIT se uloží kopie. Pro všechny revize poté GIT v podstatě ukládá instrukce, které mu říkají, jak transformovat předchozí verzi projektu na nově potvrzenou verzi.
V GITu se tyto instrukce nazývají „diffs“ . Kdykoli zakoupíte větev, GIT v podstatě začne na původním stavu projektu a použije všechny tyto rozdíly v pořadí, aby se dostal do požadovaného stavu.
Když nyní víme, jak GIT ukládá commity, je snadné vidět, že soubor opravy bude jednoduše zřetězením rozdílů pro každý z commitů, které bude patch zahrnovat.
Pro náš příklad předpokládejme následující situaci:Máme jednoduchý projekt se 2 větvemi:hlavní a experimentální.
$ git log --oneline --all * b36f227 (experimental) third commit -- added file3 * f39ebe8 second commit -- added file2 * 04a26e5 (HEAD, master) first commit -- committed file1
Master je momentálně u prvního odevzdání, zatímco experimentální je o 2 odevzdání před ním. V každém odevzdání jsem přidal soubor s názvem soubor1, soubor2 a soubor3. Zde je aktuální stav každé větve:
Na hlavním serveru máme pouze soubor1:
$ git status On branch master nothing to commit, working directory clean $ ls file1
Během experimentu máme všechny 3 soubory:
$ git status On branch experimental nothing to commit, working directory clean $ ls file1 file2 file3
V tomto tutoriálu vysvětlíme, jak vytvořit opravu změn v experimentální větvi a aplikovat je na hlavní.
Vytvoření opravy GIT
K vytvoření výstupu diff použijeme příkaz git diff a poté jej přesměrujeme do souboru. Tvar příkazu diff, který použijeme, je následující:
git diff from-commit to-commit > output-file
kde:
- from-commit – bod, ve kterém chceme, aby patch začal. (V našem případě bod, ve kterém se experimentální liší od předlohy)
- to-commit – oprava bude zahrnovat změny až do tohoto bodu včetně. (V našem případě nejnovější commit experimentálního)
- output-file – oprava bude napsána zde
Poznámka:Pokud jsou vynechány položky from-commit nebo to-commit, budou považovány za HEAD
Tyto dva commity specifikujeme jejich jedinečným hashem. Obecně stačí zadat dostatek hash odevzdání, aby byla zajištěna jeho jedinečnost (pravděpodobně to udělají 4 znaky).
$ git diff 04a2 b36f > patch.diff $ ls patch.diff file1 file2 file3
Jak vidíte z výše uvedeného výstupu, soubor opravy byl vytvořen.
V tomto speciálním případě, kdy chceme vytvořit patch celé větve, můžeme nechat GIT, aby část práce udělal za nás. Můžeme nechat GIT určit bod, ve kterém se naše experimentální větev odchýlila od hlavní větve pomocí příkazu git merge-base:
git diff $(git merge-base <public branch> <experimental branch>) > <output file>
git merge-base určí nejnovější společné potvrzení mezi 2 větvemi. Všimněte si také, jak jsme tentokrát vynechali . Ve výchozím nastavení bude HEAD a protože experimentální větev byla odhlášena, HEAD bude nejnovější odevzdání experimentální větve.
$ git diff $(git merge-base master experimental) > anotherPatch.diff $ ls anotherPatch.diff patch.diff file1 file2 file3
Znovu byl vytvořen soubor opravy. Tyto záplatové soubory jsou identické.
Použití opravy GIT
Jakmile je soubor opravy vytvořen, je jeho použití snadné. Ujistěte se, že větev, kterou jste odhlásili, je ta, na kterou chcete použít opravu (v našem případě hlavní). Poté můžete použít opravu pomocí příkazu git apply:git apply
$ git status On branch master ... (rest of output omitted) ... $ ls anotherPatch.diff patch.diff file1 $ git apply patch.diff $ ls anotherPatch.diff patch.diff file1 file2 file3
Změny z experimentální větve byly nyní replikovány na master.
Varování:Přestože použití opravy tímto způsobem přesně replikuje obsah, nebude replikována žádná historie odevzdání. To znamená, že i když záplata, kterou vytvoříte, zahrnuje několik odevzdání, při použití se zobrazí jako jediná sada změn. Ztratíte jak znalosti o tom, jak byly odevzdány, tak i zprávy pro každý odevzdání. Porovnejme historii odevzdání pro obě větve:
V experimentálním režimu jsme měli 3 odevzdání, každé se smysluplnou zprávou o odevzdání.
$ git branch * experimental master $ git log --oneline b36f227 third commit -- added file3 f39ebe8 second commit -- added file2 04a26e5 first commit -- committed file1
Náš patch však jednoduše aplikoval skutečné změny na hlavní větev.
$ git branch experimental * master $ git log --oneline 04a26e5 first commit -- committed file1
Použití opravy nezpůsobilo potvrzení změn ani nepřineslo žádnou historii potvrzení související s těmito změnami. Při používání oprav v GIT buďte opatrní.