V jednej z mojich vývojových vetiev som vykonal niekoľko zmien v základni kódu. Skôr ako som mohol dokončiť funkcie, na ktorých som pracoval, musel som prepnúť svoju aktuálnu vetvu na master, aby som mohol demonštrovať niektoré funkcie. Ale práve použitie príkazu "git checkout master" zachovalo zmeny, ktoré som vykonal aj vo svojej vývojovej vetve, čím sa rozbili niektoré funkcie vo vetve master. Urobil som teda to, že som zmeny vo svojej vývojovej vetve commitoval so správou "temporary commit" a potom som checkoutoval master pre demo.
Teraz, keď som dokončil demo a vrátil som sa k práci na svojej vývojovej vetve, chcel by som odstrániť "dočasnú revíziu", ktorú som vykonal, pričom by som zachoval vykonané zmeny. Je to možné?
Je to také jednoduché:
git reset HEAD^
git reset
bez --hard
alebo --soft
presunie váš HEAD
tak, aby ukazoval na zadanú revíziu, bez toho, aby sa zmenili akékoľvek súbory. HEAD^
odkazuje na (prvú) nadradenú revíziu vašej aktuálnej revízie, čo je vo vašom prípade revízia pred dočasnou revíziou.
Všimnite si, že ďalšou možnosťou je pokračovať normálne a potom pri ďalšom bode revízie namiesto toho spustiť:
git commit --amend [-m … etc]
ktorý namiesto toho upraví poslednú revíziu, čo bude mať rovnaký účinok ako vyššie uvedené.
Všimnite si, že toto (ako takmer každá odpoveď systému git) môže spôsobiť problémy, ak ste zlé revízie už odoslali na miesto, odkiaľ ich mohol stiahnuť niekto iný. Snažte sa tomu vyhnúť
Existujú dva spôsoby, ako to riešiť. Ktorý je jednoduchší, závisí od vašej situácie
Obnovenie
Ak bola revízia, ktorej sa chcete zbaviť, poslednou revíziou a nevykonali ste žiadnu ďalšiu prácu, môžete jednoducho použiť git-reset
git reset HEAD^
Vráti vašu vetvu späť na revíziu tesne pred aktuálnu revíziu HEAD. V skutočnosti však nezmení súbory vo vašom pracovnom strome. V dôsledku toho sa zmeny, ktoré boli v tejto revízii, zobrazia ako zmenené - je to ako príkaz 'uncommit'. V skutočnosti mám alias, ktorý robí práve toto.
git config --global alias.uncommit 'reset HEAD^'
Potom stačí v budúcnosti použiť git uncommit
na zálohovanie jednej revízie.
Squashing
Squashovanie revízie znamená spojenie dvoch alebo viacerých revízií do jednej. Ja to robím pomerne často. Vo vašom prípade máte odovzdanú polovicu hotovej funkcie, potom by ste ju dokončili a odovzdali znova s riadnou, trvalou správou o odovzdaní.
git rebase -i <ref>
Pred každou revíziou bude slovo pick
. Nájdite revíziu, ktorej sa chcete zbaviť, a zmeňte ju z pick
na fixup
alebo squash
. Použitím fixup
sa táto správa o revízii jednoducho zahodí a zmeny sa zlúčia do jej bezprostredného predchodcu v zozname. Kľúčové slovo squash
robí to isté, ale umožňuje upraviť správu o novom zlúčenom odovzdaní.
Všimnite si, že revízie budú opätovne odovzdané v poradí, v akom sa zobrazujú v zozname po ukončení editora. Ak ste teda urobili dočasnú revíziu, potom ste na tej istej vetve vykonali inú prácu a funkciu ste dokončili v neskoršej revízii, potom vám použitie funkcie rebase umožní reorganizovať revízie a zmazať ich.
POZOR:
Rebase upravuje históriu - nerobte to so žiadnymi revíziami, ktoré ste už zdieľali s inými vývojármi.
Stashing
Ak sa chcete v budúcnosti vyhnúť tomuto problému, zvážte použitie git stash
na dočasné uloženie neodovzdanej práce.
git stash save 'some message'
Týmto spôsobom sa aktuálne zmeny uložia bokom v zozname stash. Vyššie uvedená verzia príkazu stash je najvýstižnejšia a umožňuje vložiť komentár, ktorý opisuje, čo ukladáte. Môžete tiež jednoducho spustiť git stash
a nič iné, ale žiadna správa sa neuloží.
Zoznam stash môžete prehľadávať pomocou...
git stash list
Zobrazia sa vám všetky vaše schránky, na ktorých vetvách boli vykonané, správa a na začiatku každého riadku identifikátor danej schránky, ktorý vyzerá takto stash@{#}
, kde # je jej pozícia v poli schránok.
Ak chcete obnoviť schránku (čo možno vykonať na ľubovoľnej vetve bez ohľadu na to, kde bola pôvodne vytvorená), jednoducho spustite...
git stash apply stash@{#}
Opäť je tu # pozícia v poli zásobníkov. Ak sa schránka, ktorú chcete obnoviť, nachádza na pozícii 0
- to znamená, ak bola poslednou schránkou. Potom môžete jednoducho spustiť príkaz bez uvedenia pozície schránky, git bude predpokladať, že máte na mysli poslednú: git stash apply
.
Ak teda napríklad zistím, že pracujem na nesprávnej vetve - môžem spustiť nasledujúcu postupnosť príkazov.
git stash
git checkout <correct_branch>
git stash apply
Vo vašom prípade ste sa po vetvách pohybovali trochu viac, ale stále platí rovnaká myšlienka.
Dúfam, že to pomôže.