У било ком тренутку можете пожелети да нешто опозовете (undo). Овде ћемо обрадити неколико основних алата за опозив радњи. Будите опрезни, јер не можете увек да опозовете неке од ових опозива. Ово је једна од ретких области програма Гит где можете изгубити неки део вашег рада у случају ако поступите на погрешан начин.
Чест случај када је потребан опозив се јавља онда када комитујете прерано и можда заборавите да додате неке фајлове, или погрешно напишете своју комит поруку.
Ако желите да поново урадите тај комит, направите додатне измене које сте заборавили, стејџујте их и поново комитујте опцијом --amend:
$ git commit --amendОва команда узима ваш стејџ и користи га за комит. Ако од последњег комита нисте направили никакве измене (на пример, покренете ову команду одмах након последњег комита), онда ће снимак изгледати потпуно исто и све што ћете променити је комит порука.
Појављује се исти едитор за комит поруку, али се у њему већ налази укуцана порука из претходног комита. Поруку можете уредити као и увек, али тиме преписујете претходни комит.
Као пример, ако комитујете и онда схватите да сте заборавили да стејџујете промене у фајлу који сте желели да додате у овај комит, можете да урадите нешто овако:
$ git commit -m 'Initial commit'
$ git add заборављени_фајл
$ git commit --amendНа крају остаје само један комит — други комит замењује резултате првог.
|
Note
|
Важно је да разумете да када преправљате свој последњи комит, ви га уствари не поправљате већ га комплетно замењујете потпуно новим, побољшаним комитом који склања стари с пута и на његово места поставља нови комит. У суштини, исто је као да се претходни комит није ни догодио, па се неће ни приказивати у историји вашег репозиторијума. Очигледна вредност преправљања комитова је у томе што мала побољшања свог последњег комита можете да урадите без затрпавања историје вашег репозиторијума порукама као што су „Уупс, заборавио сам да додам фајл” или „Аххх, исправка грешке у куцању у последњем комиту”. |
|
Note
|
Преправљајте само комите који су још увек у локалу и нису гурнути негде. Преправљање комита који су раније гурнути и форсирано гурање гране ће правити проблеме вашим сарадницима. За више детаља о томе шта се дешава ако ово урадите, као и начин за опоравак ако се налазите на пријемном крају, прочитајте [_rebase_peril]. |
Следећа два одељка показују како да радите са променама на стејџу и радном директоријуму.
Добро је то што вас команда коју користите да би одредили стање ове две области такође подсећа и на начин за опозив промена које над њима направите.
На пример, рецимо да сте променили два фајла и да желите да их комитујете као две посебне измене, али сте случајно укуцали git add * и тако их оба додали на стејџ.
Како да један од њих склоните са стејџа?
Команда git status вас подсећа на то:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
modified: CONTRIBUTING.mdОдмах испод текста „Changes to be committed” пише да треба да употребите git reset HEAD <file>… ако фајл желите да уклоните са стејџа.
Тај савет ћемо искористити да фајл CONTRIBUTING.md уклонимо са стејџа:
$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.mdОва команда је помало чудна, али обавља посао.
Фајл CONTRIBUTING.md је измењен али поново није на стејџу.
|
Note
|
Тачно је да |
Засад је овај чаробни позив све што је потребно да знате о git reset команди.
Много детаљније ћемо испитати шта тачно ради reset у ch07-git-tools.asc када ћемо показати и како да овладате њоме и постигнете неке веома занимљиве ствари.
Шта ако одлучите да не желите да задржите измене у фајлу CONTRIBUTING.md?
Како да једноставно уклоните измене — да га вратите на стање у каквом је био када сте последњи пут начинили комит (или урадили почетно клонирање, или како год га поставили у радни директоријум)?
Срећом, git status вам говори како и то да урадите.
У прошлом примеру излаза, фајлови који нису били на стејџу били су представљени овако:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.mdКаже вам како да експлицитно одбаците промене које сте направили. Хајде да урадимо то што нам саветује:
$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> READMEМожете видети да су се промене вратиле на старо.
|
Important
|
Важно је да разумете да је |
Ако ипак желите да задржите промене које сте направили у фајлу, али за сада не желите да вам стоји на путу, у ch03-git-branching.asc ћете сазнати како да употребите скривање (stashing) и гранање (branching); обично су то бољи начини за рад.
Упамтите, у програму Гит се све што је комитовано скоро увек може опоравити.
Чак и комитови који су били на гранама које су обрисане, или комитови који су преписани --amend комитом могу да се опораве (погледајте ch10-git-internals.asc у вези опоравка података).
Ипак, све што изгубите, а никад није било комитовано, вероватно више никад нећете видети.
Верзија 2.23.0 програма Гит је увела нову команду: git restore.
У суштини је то алтернатива команди git reset коју смо управо описали.
Од верзије 2.23.0 програма Гит надаље, програм Гит ће за многе операције опозива уместо git reset користити git restore.
Хајде да поново прођемо кроз наше кораке, опозовемо ствари командом git restore уместо са git reset.
Следећа два одељка показују како да радите са изменама стејџа и радног директоријума директно помоћу команде git restore.
Згодно је што вас команда коју користите да одредите статус те две области уједно и подсећа како да опозовете промене које начините над њима.
На пример, претпоставимо да сте изменили два фајла и желите то да комитујете као две одвојене измене, али сте случајно откуцали git add * и стејџовали оба.
Како да један од њих склоните са стејџа?
Команда git status вас подсећа:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: CONTRIBUTING.md
renamed: README.md -> READMEНепосредно испод текста „Changes to be committed” пише „use git restore --staged <file>… to unstage” (употребите git restore --staged <фајл>… да уклоните са стејџа).
Дакле, хајде да искористимо овај савет и уклонимо са стејџа фајл CONTRIBUTING.md:
$ git restore --staged CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README.md -> README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: CONTRIBUTING.mdФајл CONTRIBUTING.md је измењен, али је поново ван стејџа.
Шта ако схватите да не желите задржати измене над фајлом CONTRIBUTING.md?
Како једноставно можете да уклоните измене — тј. да га вратите у стање у коме је био када сте направили последњи комит (или урадили почетно клонирање, или шта год урадили да га поставите у радни директоријум)?
Срећом, git status вам такође говори како и то да урадите.
У излазу последњег примера, област ван стејџа изгледа овако:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: CONTRIBUTING.mdОво вам говори прилично директно како да одбаците измене које сте направили. Хајде да урадимо то што каже:
$ git restore CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README.md -> README|
Important
|
Важно је да разумете да је |