Гит Ресет вс Реверт вс Ребасе

У овом чланку ћете научити о различитим начинима да се играте са урезима у Гиту.

Као програмер, наишли бисте на такве ситуације више пута у којима бисте желели да се вратите на једно од својих претходних урезивања, али нисте сигурни како то да урадите. Чак и ако знате Гит команде као што су ресетовање, враћање, ребасе, нисте свесни разлика између њих. Дакле, хајде да почнемо и разумемо шта су гит ресетовање, враћање и ребазовање.

Гит Ресет

Гит ресет је сложена команда и користи се за поништавање промена.

Можете замислити гит ресет као функцију враћања. Са гит ресетовањем, можете скакати између различитих урезивања. Постоје три начина покретања гит ресет команде: –софт, –микед и –хард. Подразумевано, гит ресет команда користи мешовити режим. У току рада за ресетовање гит-а, три интерна механизма управљања гит-ом долазе у слику: ГЛАВА, област за постављање (индекс) и радни директоријум.

Радни директоријум је место где тренутно радите, то је место где су ваше датотеке присутне. Користећи гит статус команду, можете видети који су све фајлови/фолдери присутни у радном директоријуму.

Стагинг Ареа (Индек) је место где гит прати и чува све промене у датотекама. Сачуване промене се одражавају у .гит директоријуму. Користите гит адд „име датотеке“ да додате датотеку у област за припрему. И као и раније, када покренете гит статус, видећете које датотеке су присутне у области за припрему.

Тренутна грана у Гиту се назива ХЕАД. Указује на последњу урезивање, која се десила у тренутној грани за одјаву. Третира се као показивач за било коју референцу. Када одете у другу грану, ГЛАВА се такође помера у нову грану.

Дозволите ми да објасним како гит ресет функционише у тврдом, меком и мешовитом режиму. Тврди режим се користи за прелазак на урезано урезивање, радни директоријум се попуњава датотекама тог урезивања, а област за постављање се ресетује. У меком ресетовању, само се показивач мења на наведено урезивање. Датотеке свих урезивања остају у радном директоријуму и области за постављање пре ресетовања. У мешовитом режиму (подразумевано), показивач и област за постављање се ресетују.

Гит Ресет Хард

Сврха гит хард ресетовања је да се ХЕАД помери на наведено урезивање. Уклониће сва урезивања која су се десила након наведеног урезивања. Ова команда ће променити историју урезивања и указивати на наведено урезивање.

У овом примеру ћу додати три нове датотеке, урезати их и затим извршити хард ресет.

Као што можете видети из наредбе испод, тренутно нема шта да се урезује.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.

(use "git push" to publish your local commits)

nothing to commit, working tree clean

Сада ћу направити 3 датотеке и додати им нешто садржаја.

$ vi file1.txt
$ vi file2.txt
$ vi file3.txt

Додајте ове датотеке у постојеће спремиште.

$ git add file*

Када поново покренете команду статуса, она ће одражавати нове датотеке које сам управо направио.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.

(use "git push" to publish your local commits)

Changes to be committed:

(use "git restore --staged <file>..." to unstage)

new file:
file1.txt

new file:
file2.txt

new file:
file3.txt

Пре урезивања, дозволите ми да вам покажем, тренутно имам дневник од 3 урезивања у Гиту.

$ git log --oneline
0db602e (HEAD -> master) one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Сада ћу се посветити спремишту.

$ git commit -m 'added 3 files'
[master d69950b] added 3 files
3 files changed, 3 insertions(+)
create mode 100644 file1.txt
create mode 100644 file2.txt
create mode 100644 file3.txt

Ако урадим лс-фајлове, видећете да су нове датотеке додате.

$ git ls-files
demo
dummyfile
newfile
file1.txt
file2.txt
file3.txt

Када покренем наредбу дневника у гит-у, имам 4 урезивања, а ХЕАД указује на најновије урезивање.

$ git log --oneline
d69950b (HEAD -> master) added 3 files
0db602e one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Ако одем и избришем фајл1.ткт ручно и извршим гит статус, приказаће се порука да промене нису постављене за урезивање.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.

(use "git push" to publish your local commits)

Changes not staged for commit:

(use "git add/rm <file>..." to update what will be committed)

(use "git restore <file>..." to discard changes in working directory)

deleted:
file1.txt

no changes added to commit (use "git add" and/or "git commit -a")

Сада ћу покренути команду за хард ресет.

$ git reset --hard
HEAD is now at d69950b added 3 files

Ако поново проверим статус, открићу да нема шта да се урезује, а датотека коју сам обрисао се вратила у спремиште. Враћање се догодило јер након брисања датотеке нисам урезао, па се након хард ресетовања вратио у претходно стање.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.

(use "git push" to publish your local commits)

nothing to commit, working tree clean

Ако проверим дневник гит-а, овако ће изгледати.

$ git log
commit d69950b7ea406a97499e07f9b28082db9db0b387 (HEAD -> master)
Author: mrgeek <[email protected]>
Date:
Mon May 17 19:53:31 2020 +0530

added 3 files

commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14
Author: mrgeek <[email protected]>
Date:
Mon May 17 01:04:13 2020 +0530

one more commit

commit 59c86c96a82589bad5ecba7668ad38aa684ab323
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:54:53 2020 +0530

new commit

commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:16:33 2020 +0530

test

Сврха хард ресетовања је да укаже на наведено урезивање и ажурира радни директоријум и област за постављање. Дозволите ми да вам покажем још један пример. Тренутно, визуелизација мојих урезивања изгледа овако:

  Како функционише инкапсулација у умрежавању?

Овде ћу покренути команду са ХЕАД^, што значи да желим да се вратим на претходно урезивање (једно урезивање назад).

$ git reset --hard HEAD^
HEAD is now at 0db602e one more commit

Можете видети да је показивач главе сада промењен у 0дб602е са д69950б.

$ git log --oneline
0db602e (HEAD -> master) one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Ако проверите дневник, урезивање д69950б је нестало, а глава сада показује на 0дб602е СХА.

$ git log
commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14 (HEAD -> master)
Author: mrgeek <[email protected]>
Date:
Mon May 17 01:04:13 2020 +0530

one more commit

commit 59c86c96a82589bad5ecba7668ad38aa684ab323
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:54:53 2020 +0530

new commit

commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:16:33 2020 +0530

Test

Ако покренете лс-датотеке, можете видети да филе1.ткт, филе2.ткт и филес3.ткт више нису у спремишту јер су то урезивање и његова датотека уклоњени након хард ресетовања.

$ git ls-files
demo
dummyfile
newfile

Гит Софт Ресет

Слично томе, сада ћу вам показати пример меког ресетовања. Узмите у обзир, поново сам додао 3 фајла као што је горе поменуто и урезао их. Гит дневник ће се појавити као што је приказано испод. Можете видети да је ‘софт ресет’ моје најновије урезивање, а ХЕАД такође указује на то.

$ git log --oneline
aa40085 (HEAD -> master) soft reset
0db602e one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Детаљи урезивања у дневнику могу се видети помоћу доње команде.

$ git log
commit aa400858aab3927e79116941c715749780a59fc9 (HEAD -> master)
Author: mrgeek <[email protected]>
Date:
Mon May 17 21:01:36 2020 +0530

soft reset

commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14
Author: mrgeek <[email protected]>
Date:
Mon May 17 01:04:13 2020 +0530

one more commit

commit 59c86c96a82589bad5ecba7668ad38aa684ab323
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:54:53 2020 +0530

new commit

commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:16:33 2020 +0530

test

Сада користећи меко ресетовање, желим да пређем на једно од старијих урезивања са СХА 0дб602е085а4д59цфа9393абац41фф5фд7афцб14

Да бих то урадио, покренућу наредбу испод. Морате да проследите више од 6 почетних знакова СХА, комплетан СХА није потребан.

$ git reset --soft 0db602e085a4

Сада када покренем гит дневник, видим да је ХЕАД ресетован на урезивање које сам навео.

$ git log
commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14 (HEAD -> master)
Author: mrgeek <[email protected]>
Date:
Mon May 17 01:04:13 2020 +0530

one more commit

commit 59c86c96a82589bad5ecba7668ad38aa684ab323
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:54:53 2020 +0530

new commit

commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
Author: mrgeek <[email protected]>
Date:
Mon May 17 00:16:33 2020 +0530

test

Али разлика је у томе што су датотеке урезивања (аа400858ааб3927е79116941ц715749780а59фц9) где сам додао 3 датотеке још увек у мом радном директоријуму. Нису избрисани. Зато би требало да користите меко ресетовање уместо хард ресетовање. Не постоји ризик од губитка датотека у меком режиму.

$ git ls-files
demo
dummyfile
file1.txt
file2.txt
file3.txt
newfile

Гит Реверт

У Гиту, команда реверт се користи за извођење операције враћања, тј. за враћање неких промена. Слично је команди за ресетовање, али једина разлика је у томе што изводите ново урезивање да бисте се вратили на одређено урезивање. Укратко, поштено је рећи да је команда гит реверт урезивање.

  Пронађите број језгара у процесору и ограничите употребу језгара од стране апликација

Гит реверт команда не брише никакве податке током извршавања операције враћања.

Рецимо да додајем 3 датотеке и изводим гит операцију урезивања за пример враћања.

$ git commit -m 'add 3 files again'
[master 812335d] add 3 files again
3 files changed, 3 insertions(+)
create mode 100644 file1.txt
create mode 100644 file2.txt
create mode 100644 file3.txt

Дневник ће показати ново урезивање.

$ git log --oneline
812335d (HEAD -> master) add 3 files again
0db602e one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Сада бих желео да се вратим на једно од мојих прошлих урезивања, рецимо – „59ц86ц9 ново урезивање“. Покренуо бих наредбу испод.

$ git revert 59c86c9

Ово ће отворити датотеку, наћи ћете детаље урезивања на које покушавате да се вратите, и можете да дате име новом урезовању, а затим сачувате и затворите датотеку.

Revert "new commit"

This reverts commit 59c86c96a82589bad5ecba7668ad38aa684ab323.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.
# (use "git push" to publish your local commits)
#
# Changes to be committed:
# modified: dummyfile

Након што сачувате и затворите датотеку, ово је излаз који ћете добити.

$ git revert 59c86c9
[master af72b7a] Revert "new commit"
1 file changed, 1 insertion(+), 1 deletion(-)

Сада да извршите неопходне промене, за разлику од ресетовања, реверт је извршио још једно ново урезивање. Ако поново проверите дневник, наћи ћете ново урезивање због операције враћања.

$ git log --oneline
af72b7a (HEAD -> master) Revert "new commit"
812335d add 3 files again
0db602e one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Гит дневник ће имати сву историју урезивања. Ако желите да уклоните урезивање из историје, онда враћање није добар избор, али ако желите да задржите промене урезивања у историји, онда је реверт одговарајућа команда уместо ресетовања.

Гит Ребасе

У Гиту, ребасе је начин премештања или комбиновања урезивања једне гране преко друге гране. Као програмер, не бих креирао своје карактеристике на главној грани у стварном сценарију. Радио бих на својој грани („ограничена грана“), а када имам неколико урезивања у својој грани са додатом функцијом, онда бих желео да је преместим у главну грану.

Ребасе понекад може бити мало збуњујуће за разумевање јер је веома слично спајању. Циљ спајања и поновног базирања оба је да узмем урезивање из моје гране функција и ставим их на главну грану или било коју другу грану. Узмите у обзир, имам графикон који изгледа овако:

Претпоставимо да радите у тиму са другим програмерима. У том случају, можете замислити да би ово могло постати веома сложено када имате гомилу других програмера који раде на различитим гранама функција, а они спајају више промена. Постаје збуњујуће за праћење.

  Ансибле за почетнике – Ансибле основе и како то функционише

Дакле, овде ће ребасе помоћи. Овог пута, уместо да радим гит мерге, урадићу ребасе, где желим да узмем своја два урезивања гране функција и преместим их на главну грану. Ребасе ће узети све моје урезивање из гране функције и преместити их на врх урезивања главне гране. Дакле, иза сцене, гит дуплира урезивање гране карактеристика на главној грани.

Овај приступ ће вам дати чист праволинијски графикон са свим урезивањем у низу.

Олакшава праћење где су урезивања отишла. Можете замислити да ако сте у тиму са много програмера, сва урезивања су и даље у низу. Дакле, заиста је лако пратити чак и ако имате много људи који раде на истом пројекту у исто време.

Дозволите ми да вам ово практично покажем.

Овако тренутно изгледа моја главна грана. Има 4 урезивања.

$ git log --oneline
812335d (HEAD -> master) add 3 files again
0db602e one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Покренућу наредбу испод да креирам и пребацим се на нову грану која се зове функција, а ова грана ће бити креирана од 2. урезивања, тј. 59ц86ц9

(master)
$ git checkout -b feature 59c86c9
Switched to a new branch 'feature'

Ако проверите дневник у грани функција, он има само 2 урезивања која долазе од мастера (главне линије).

(feature)
$ git log --oneline
59c86c9 (HEAD -> feature) new commit
e2f44fc (origin/master, origin/HEAD) test

Направићу функцију 1 и урезати је у грану функције.

(feature)
$ vi feature1.txt

(feature)
$ git add .
The file will have its original line endings in your working directory

(feature)
$ git commit -m 'feature 1'
[feature c639e1b] feature 1
1 file changed, 1 insertion(+)
create mode 100644 feature1.txt

Направићу још једну функцију, тј. функцију 2, у грани карактеристика и урезати је.

(feature)
$ vi feature2.txt

(feature)
$ git add .
The file will have its original line endings in your working directory

(feature)
$ git commit -m 'feature 2'
[feature 0f4db49] feature 2
1 file changed, 1 insertion(+)
create mode 100644 feature2.txt

Сада, ако проверите дневник гране карактеристика, има два нова урезивања, које сам извршио изнад.

(feature)
$ git log --oneline
0f4db49 (HEAD -> feature) feature 2
c639e1b feature 1
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

Сада желим да додам ове две нове функције у главну грану. За то ћу користити команду ребасе. Из гране карактеристика, пребазираћу у односу на главну грану. Оно што ће ово учинити је да ће поново усидрити моју грану карактеристика у односу на најновије промене.

(feature)
$ git rebase master
Successfully rebased and updated refs/heads/feature.

Сада ћу ићи напред и проверити главну грану.

(feature)
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 3 commits.

(use "git push" to publish your local commits)

И на крају, поново поставите главну грану у односу на моју грану карактеристика. Ово ће узети та два нова урезивања на мојој грани функција и поново их репродуковати на врху моје главне гране.

(master)
$ git rebase feature
Successfully rebased and updated refs/heads/master.

Сада ако проверим дневник на главној грани, могу да видим да су два урезивања моје гране функција успешно додата у моју главну грану.

(master)
$ git log --oneline
766c996 (HEAD -> master, feature) feature 2
c036a11 feature 1
812335d add 3 files again
0db602e one more commit
59c86c9 new commit
e2f44fc (origin/master, origin/HEAD) test

То је било све о ресетовању, враћању и поновном базовању команди у Гиту.

Закључак

То је било све о ресетовању, враћању и поновном базовању команди у Гиту. Надам се да је овај водич корак по корак био од помоћи. Сада знате како да се играте са својим урезивањем према потреби користећи команде поменуте у чланку.