Git Reset vs Revert vs Rebase

Šajā rakstā jūs uzzināsit par dažādiem veidiem, kā spēlēties ar saistībām programmā Git.

Jums kā izstrādātājam būtu vairākas reizes nācies saskarties ar šādām situācijām, kad būtu vēlējies atgriezties pie kādas no savām iepriekšējām saistībām, bet nezināt, kā to izdarīt. Un pat tad, ja zināt Git komandas, piemēram, atiestatīt, atjaunot, rebase, jūs nezināt par atšķirībām starp tām. Tātad sāksim un sapratīsim, kas ir git reset, revert un rebase.

Git Reset

Git atiestatīšana ir sarežģīta komanda, un to izmanto, lai atsauktu izmaiņas.

Git atiestatīšanu var uzskatīt par atcelšanas funkciju. Izmantojot git atiestatīšanu, varat pārslēgties starp dažādām saistībām. Ir trīs git atiestatīšanas komandas palaišanas režīmi: –soft, –mixed un –hard. Pēc noklusējuma komanda git reset izmanto jaukto režīmu. Git atiestatīšanas darbplūsmā tiek parādīti trīs git iekšējie pārvaldības mehānismi: HEAD, stadijas apgabals (indekss) un darba direktorijs.

Darba direktorijs ir vieta, kur jūs pašlaik strādājat, tā ir vieta, kur atrodas jūsu faili. Izmantojot git statusa komandu, varat redzēt, kādi faili/mapes atrodas darba direktorijā.

Uzstādīšanas apgabals (indekss) ir vieta, kur git izseko un saglabā visas izmaiņas failos. Saglabātās izmaiņas tiek atspoguļotas .git direktorijā. Jūs izmantojat git add “faila nosaukums”, lai pievienotu failu pieturas apgabalam. Un tāpat kā iepriekš, palaižot git statusu, jūs redzēsit, kuri faili atrodas uzstāšanās apgabalā.

Pašreizējā Git filiāle tiek saukta par HEAD. Tas norāda uz pēdējo saistību izpildi, kas notika pašreizējā norēķinu filiālē. Tas tiek uzskatīts par norādi jebkurai atsaucei. Kad veicat norēķināšanos citā filiālē, arī HEAD pāriet uz jauno filiāli.

Ļaujiet man paskaidrot, kā git atiestatīšana darbojas cietajā, mīkstajā un jauktā režīmā. Cietais režīms tiek izmantots, lai pārietu uz norādīto apstiprināšanu, darba direktorijs tiek aizpildīts ar šīs apstiprināšanas failiem, un pieturvietas apgabals tiek atiestatīts. Mīkstajā atiestatīšanā tikai rādītājs tiek mainīts uz norādīto apstiprināšanu. Visu apņemšanos faili pirms atiestatīšanas paliek darba direktorijā un izlaiduma apgabalā. Jauktā režīmā (noklusējums) tiek atiestatīts gan rādītājs, gan pieturvietas apgabals.

Git Reset Hard

Git cietās atiestatīšanas mērķis ir pārvietot HEAD uz norādīto apņemšanos. Tas noņems visas saistības, kas notika pēc norādītās apņemšanās. Šī komanda mainīs izpildes vēsturi un norādīs uz norādīto apstiprināšanu.

Šajā piemērā es pievienošu trīs jaunus failus, pievienošu tos un pēc tam veiksim cieto atiestatīšanu.

Kā redzat no tālāk esošās komandas, šobrīd nav ko izdarīt.

$ 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

Tagad es izveidošu 3 failus un pievienošu tiem saturu.

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

Pievienojiet šos failus esošajam repozitorijam.

$ git add file*

Atkārtoti izpildot statusa komandu, tā atspoguļos jaunos failus, ko tikko izveidoju.

$ 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

Pirms apņemšanās, ļaujiet man jums parādīt, ka man šobrīd Git ir 3 apņemšanos žurnāls.

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

Tagad es iesaistīšos krātuvē.

$ 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

Ja es darīšu ls-failus, jūs redzēsit, ka jaunie faili ir pievienoti.

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

Kad es palaižu log komandu programmā git, man ir 4 commit, un HEAD norāda uz jaunāko apstiprinājumu.

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

Ja es manuāli izdzēšu failu 1.txt un veicu git statusu, tiks parādīts ziņojums, ka izmaiņas nav veiktas apstiprināšanai.

$ 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")

Tagad es izpildīšu cietās atiestatīšanas komandu.

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

Ja es vēlreiz pārbaudīšu statusu, es atklāšu, ka nav ko izdarīt, un fails, kuru es izdzēsu, ir atgriezies repozitorijā. Atcelšana ir notikusi, jo pēc faila dzēšanas es neveicu saistības, tāpēc pēc cietās atiestatīšanas tas atgriezās iepriekšējā stāvoklī.

$ 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

Ja es pārbaudīšu git žurnālu, tas izskatīsies šādi.

$ 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

Cietās atiestatīšanas mērķis ir norādīt uz norādīto apņemšanos un atjaunināt darba direktoriju un pieturvietas apgabalu. Ļaujiet man parādīt jums vēl vienu piemēru. Pašlaik manu saistību vizualizācija izskatās šādi:

  Kas vispār ir G Suite?

Šeit es izpildīšu komandu ar HEAD^, kas nozīmē, ka es vēlos atiestatīt iepriekšējo apņemšanos (vienu apstiprinājumu atpakaļ).

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

Varat redzēt, ka galvas rādītājs tagad ir mainīts uz 0db602e no d69950b.

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

Ja pārbaudīsit žurnālu, d69950b saistīšana vairs nav pieejama, un tagad virsraksts norāda uz 0db602e SHA.

$ 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

Ja palaižat ls-failus, varat redzēt, ka fails1.txt, fails2.txt un faili3.txt vairs neatrodas repozitorijā, jo šī apņemšanās un tās fails tika noņemti pēc cietās atiestatīšanas.

$ git ls-files
demo
dummyfile
newfile

Git Soft Reset

Līdzīgi tagad es jums parādīšu mīkstās atiestatīšanas piemēru. Apsveriet, ka esmu atkal pievienojis 3 failus, kā minēts iepriekš, un veicis tos. Git žurnāls parādīsies, kā parādīts zemāk. Varat redzēt, ka “soft reset” ir mana jaunākā apņemšanās, un HEAD arī norāda uz to.

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

Sīkāku informāciju par apņemšanos žurnālā var redzēt, izmantojot tālāk norādīto komandu.

$ 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

Tagad, izmantojot mīksto atiestatīšanu, es vēlos pārslēgties uz vienu no vecākām saistībām ar SHA 0db602e085a4d59cfa9393abac41ff5fd7afcb14

Lai to izdarītu, es izpildīšu tālāk norādīto komandu. Jums ir jānokārto vairāk nekā 6 SHA rakstzīmes. Pilnīga SHA rakstzīme nav nepieciešama.

$ git reset --soft 0db602e085a4

Tagad, kad es palaižu git žurnālu, es redzu, ka HEAD ir atiestatīts uz manis norādīto saistību.

$ 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

Bet atšķirība šeit ir tāda, ka apņemšanās faili (aa400858aab3927e79116941c715749780a59fc9), kurā es biju pievienojis 3 failus, joprojām atrodas manā darba direktorijā. Tie nav izdzēsti. Tāpēc jums vajadzētu izmantot mīksto atiestatīšanu, nevis cieto atiestatīšanu. Mīkstajā režīmā nepastāv risks pazaudēt failus.

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

Git Revert

Programmā Git komanda revert tiek izmantota, lai veiktu atgriešanas darbību, ti, lai atsauktu dažas izmaiņas. Tā ir līdzīga atiestatīšanas komandai, taču vienīgā atšķirība šeit ir tāda, ka jūs veicat jaunu apņemšanos, lai atgrieztos pie noteiktas apņemšanās. Īsāk sakot, ir godīgi teikt, ka git revert komanda ir apņemšanās.

  Kā instalēt Chromium pārlūkprogrammu Ubuntu 20?

Git revert komanda neizdzēš nekādus datus, veicot atgriešanas darbību.

Pieņemsim, ka es pievienoju 3 failus un veicu git commit darbību atgriešanas piemēram.

$ 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

Žurnālā tiks parādīta jaunā apņemšanās.

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

Tagad es vēlētos atgriezties pie vienas no savām pagātnes saistībām, teiksim – “59c86c9 new commit”. Es palaistu tālāk norādīto komandu.

$ git revert 59c86c9

Tiks atvērts fails, jūs atradīsiet informāciju par saistību, uz kuru mēģināt atgriezties, un šeit varat piešķirt savai jaunajai apņemšanai nosaukumu, pēc tam saglabāt un aizvērt failu.

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

Pēc faila saglabāšanas un aizvēršanas šī ir izvade, ko saņemsit.

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

Tagad, lai veiktu nepieciešamās izmaiņas, atšķirībā no atiestatīšanas, atgriešana ir veikusi vēl vienu jaunu apņemšanos. Ja vēlreiz pārbaudīsit žurnālu, atgriešanas darbības dēļ jūs atradīsiet jaunu apņemšanos.

$ 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

Git žurnālā būs visa saistību vēsture. Ja vēlaties noņemt commits no vēstures, tad revert nav laba izvēle, bet, ja vēlaties saglabāt commit izmaiņas vēsturē, tad revert ir piemērota komanda, nevis atiestatīt.

Git Rebase

Git versijā rebase ir veids, kā pārvietot vai apvienot vienas filiāles saistības pār citu. Kā izstrādātājs es neveidotu savus līdzekļus galvenajā atzarā reālā scenārijā. Es strādātu pie savas filiāles (“funkciju zars”), un, kad manā līdzekļa zarā ir dažas saistības, kurām ir pievienota funkcija, es vēlētos to pārvietot uz galveno filiāli.

Rebase dažreiz var būt nedaudz mulsinoša, jo tā ir ļoti līdzīga sapludināšanai. Abu apvienošanas un bāzes izveides mērķis ir izņemt saistības no manas funkcijas filiāles un ievietot tās galvenajā vai jebkurā citā filiālē. Apsveriet, ka man ir grafiks, kas izskatās šādi:

Pieņemsim, ka strādājat komandā ar citiem izstrādātājiem. Tādā gadījumā varat iedomāties, ka tas var kļūt ļoti sarežģīti, ja jums ir vairāki citi izstrādātāji, kas strādā pie dažādām funkciju nozarēm, un viņi ir apvienojuši vairākas izmaiņas. Izsekot kļūst mulsinoši.

  Vai jums ir nepieciešams Zoom konts, lai pievienotos sapulcei?

Tātad, šeit palīdzēs rebase. Šoreiz tā vietā, lai veiktu git sapludināšanu, es izdarīšu rebase, kur vēlos veikt savas divas iezīmes filiāles saistības un pārvietot tās uz galveno filiāli. Atkāpe ņems visas manas saistības no līdzekļa zara un pārvietos tās virs galvenās filiāles saistībām. Tātad aizkulisēs git dublē līdzekļa filiāles saistības galvenajā zarā.

Šī pieeja sniegs jums tīru taisnu līniju grafiku ar visām saistībām pēc kārtas.

Tas ļauj viegli izsekot, kuras saistības un kur tika veiktas. Varat iedomāties, ja esat komandā ar daudziem izstrādātājiem, visas saistības joprojām ir pēc kārtas. Tātad, tam ir patiešām viegli sekot pat tad, ja pie viena projekta vienlaikus strādā daudzi cilvēki.

Ļaujiet man to parādīt praktiski.

Tā šobrīd izskatās mana meistara nozare. Tam ir 4 saistības.

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

Es izpildīšu tālāk norādīto komandu, lai izveidotu un pārslēgtos uz jaunu filiāli, ko sauc par līdzekli, un šī filiāle tiks izveidota no 2. commit, ti, 59c86c9

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

Ja pārbaudāt žurnālu līdzekļu zarā, tam ir tikai 2 commits, kas nāk no galvenā (galvenā līnijas).

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

Es izveidošu 1. līdzekli un pievienošu to līdzekļa filiālei.

(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

Es izveidošu vēl vienu līdzekli, ti, 2. līdzekli, funkciju zarā un izmantošu to.

(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

Tagad, ja pārbaudāt līdzekļa filiāles žurnālu, tajā ir divas jaunas saistības, kuras es izpildīju iepriekš.

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

Tagad es vēlos pievienot šīs divas jaunās funkcijas galvenajai filiālei. Šim nolūkam es izmantošu komandu rebase. No īpašību zara es atkāpšos pret galveno zaru. Tas no jauna noenkuros manu funkciju nozari pret jaunākajām izmaiņām.

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

Tagad es iešu uz priekšu un pārbaudīšu galveno filiāli.

(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)

Un visbeidzot, novietojiet galveno zaru pret manu funkciju zaru. Tas aizņems šīs divas jaunās saistības manā funkciju zarā un atkārtos tās manā galvenajā zarā.

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

Tagad, ja es pārbaudu žurnālu galvenajā zarā, es redzu, ka divi mana līdzekļu zara apstiprinājumi ir veiksmīgi pievienoti galvenajam zaram.

(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

Tas viss bija par Git komandu atiestatīšanu, atiestatīšanu un atkārtotu bāzēšanu.

Secinājums

Tas viss bija par Git komandu atiestatīšanu, atiestatīšanu un atkārtotu bāzēšanu. Es ceru, ka šī soli pa solim sniegtā rokasgrāmata bija noderīga. Tagad jūs zināt, kā rīkoties ar savām saistībām atbilstoši vajadzībām, izmantojot rakstā minētās komandas.