Ulinganisho

git reset na git revert: jinsi ya kughairi commit bila kuvunja historia ya timu

Imesasishwa: · Skillaria.Top

git reset husogeza kielekezi cha tawi hadi commit nyingine na kuandika upya historia, kwa hiyo inafaa tu kwa commit za ndani ambazo bado hazijatumwa. git revert huunda commit mpya yenye mabadiliko ya kinyume na haigusi historia, kwa hiyo ndiyo njia salama ya kughairi commit ambayo tayari iko kwenye seva.

Kwa ufupi: git reset hurudisha tawi nyuma na kufanya ionekane kana kwamba commit za ziada hazikuwepo. git revert huacha historia kama ilivyo na kuongeza commit mpya inayoghairi mabadiliko ya ile ya zamani. Ya kwanza inafaa kwa kazi ya ndani, ya pili kwa kila kitu ambacho tayari kimefika kwenye hifadhi ya pamoja. Ukikumbuka kanuni hii moja tu, utaepuka ajali nyingi za Git.

Hapa chini tunaeleza jinsi amri zote mbili zinavyofanya kazi, tofauti za hali za reset, jinsi ya kughairi commit baada ya push, jinsi ya kurudisha commit zilizopotea, na nafasi ya git clean.

Sehemu tatu zinazobadilisha amri za kughairi

Ili kuelewa tofauti, kumbuka sehemu tatu za Git: folda ya kazi (faili kwenye diski), index (staging area, yaani kile kitakachoingia kwenye commit ijayo) na historia (commit ambazo tawi na HEAD vinaelekeza). Kila amri ya kughairi hufanya kazi na mchanganyiko wake wa sehemu hizi.

AmriHistoriaIndexFolda ya kaziSalama kwa tawi la pamoja
git restore failihapanahapanandiyondiyo
git restore --staged failihapanandiyohapanandiyo
git reset --softndiyohapanahapanahapana
git reset --mixed (chaguo-msingi)ndiyondiyohapanahapana
git reset --hardndiyondiyondiyohapana
git reverthuongeza commit——ndiyo
git cleanhapanahapanahufuta faili zisizofuatiliwandiyo, lakini hairudishiki

Jinsi git reset inavyofanya kazi

Amri git reset <commit> husogeza kielekezi cha tawi la sasa (na HEAD pamoja nayo) hadi commit uliyoitaja. Commit zilizo "baada" yake hazifutwi kimwili, lakini hazionekani tena kwenye tawi. Hali (mode) ndiyo inayoamua kinachotokea kwenye index na faili.

git reset --soft: kughairi commit na kubaki na mabadiliko kwenye index

Tawi linasogea, lakini index na faili zinabaki zilivyo. Mabadiliko yote ya commit zilizoghairiwa yanakuwa tayari kwa commit. Hii ndiyo njia nzuri ya kuandika upya ujumbe wa commit au kuunganisha commit kadhaa za mwisho kuwa moja.

git reset --soft HEAD~3
git commit -m "feat: fomu ya usajili"

Commit tatu za mwisho zimekuwa moja, maudhui ya faili hayajabadilika.

git reset --mixed: kughairi commit na index

Hali ya chaguo-msingi: git reset HEAD~1 ni sawa na git reset --mixed HEAD~1. Tawi linasogea, index inasafishwa, lakini mabadiliko yanabaki kwenye folda ya kazi kama ambayo hayajaandaliwa. Ni rahisi unapokuwa umecommit kitu kisichohitajika na unataka kuamua upya ni nini na kwa vipande gani kiongezwe.

git reset HEAD~1
git status
# Changes not staged for commit:
#   modified:   app.py
#   modified:   config.yml

git reset --hard: kurudi kikamilifu

Tawi, index na folda ya kazi vinarudishwa kwenye hali ya commit uliyoitaja. Mabadiliko yote ambayo hayajacommitiwa kwenye faili zinazofuatiliwa yanapotea bila onyo. Hii ndiyo hali pekee ya reset inayoweza kweli kuharibu kazi yako.

git reset --hard HEAD~1          # tupa commit ya mwisho na marekebisho yote
git reset --hard origin/main     # rudisha tawi kwenye hali ya seva

Kabla ya --hard, ni vizuri kutekeleza git status na git stash ikiwa kuna kitu cha thamani. Kilichocommitiwa kinaweza kurudishwa (tazama hapa chini), lakini kisichocommitiwa hakiwezi.

git reset kwa faili moja

Ukiweka njia ya faili, reset haisogezi tawi bali inabadilisha index tu: git reset app.py huondoa faili kwenye zilizoandaliwa. Mbadala wa kisasa ni git restore --staged app.py, ambao ni wazi zaidi. Bendera --soft na --hard hazifanyi kazi pamoja na njia za faili.

Jinsi git revert inavyofanya kazi

git revert <commit> hukokotoa mabadiliko ya commit uliyoitaja, huyatumia kinyume, na kuunda commit mpya. Mistari iliyoongezwa inafutwa, iliyofutwa inarudishwa. Historia inakua mbele, hakuna kilichoandikwa upya, kwa hiyo wenzako hawana haja ya kurekebisha chochote kwao.

git log --oneline
# a3f9c21 (HEAD -> main) docs: README
# 7be41d0 feat: kuhifadhi majibu kwenye cache
# 1c02e8f fix: muda wa ombi kuisha

git revert 7be41d0
# [main 5d8e2aa] Revert "feat: kuhifadhi majibu kwenye cache"
#  2 files changed, 3 insertions(+), 41 deletions(-)

Git itafungua kihariri chenye ujumbe wa aina ya Revert "..." na mstari This reverts commit 7be41d0.... Ni desturi nzuri kuongeza sababu ya kughairi.

Bendera muhimu za revert

  • --no-edit — kukubali ujumbe wa kawaida bila kufungua kihariri.
  • -n (--no-commit) — kutumia mabadiliko ya kinyume kwenye index bila kuunda commit. Hivyo unaweza kughairi commit kadhaa kwa commit moja.
  • git revert A..B — kughairi safu ya commit (kila moja kwa revert yake, kuanzia mpya hadi ya zamani).
  • -m 1 — ni lazima kwa merge commit: inaonyesha ni mzazi gani ahesabiwe kama mstari mkuu.
git revert --no-commit HEAD~3..HEAD
git commit -m "Revert: kughairi commit tatu za jaribio"

Kughairi merge commit

Muunganiko una wazazi wawili, na Git haijui ni kinyume cha upande gani cha kuhesabu, kwa hiyo bila -m itatoa kosa is a merge but no -m option was given. Kwa kawaida tawi kuu ni mzazi wa kwanza:

git revert -m 1 9f1e2ab

Tahadhari: baadaye ukitaka kuunganisha tawi lilelile tena, Git itaona commit zake tayari zimeunganishwa na haitaleta mabadiliko. Suluhisho ni kwanza kughairi revert yenyewe, kisha kuongeza marekebisho mapya.

git reset dhidi ya git revert: ipi ichague

Kigezogit resetgit revert
Inafanya nini na historiainaiandika upya (commit zinatoweka kwenye tawi)inaongeza commit mpya
Commit tayari imetumwainahitaji push --force, inavunja kazi ya wenzakoni git push ya kawaida
Kughairi commit katikati ya historiatu pamoja na zote zinazofuatainawezekana kwa usahihi
Alama kwenye historiahakuna inayobakiinabaki, inaonekana nani alighairi na kwa nini
Hali ya kawaidakusafisha commit za ndani kabla ya pushkughairi commit iliyovunja main

Kanuni rahisi: ikiwa commit imeonekana na mtu mwingine zaidi yako, tumia revert; ikiwa haijaonekana, tumia reset. Kipekee ni tawi lako binafsi la feature ambalo hakuna mtu mwingine anaelitumia: humo kuandika upya historia na git push --force-with-lease kunaruhusiwa.

Kwa nini reset --hard kwenye tawi la pamoja si wazo zuri

Fikiria: umefanya git reset --hard HEAD~2 kwenye main kisha git push --force. Kwa wenzako commit hizo mbili bado zipo. Wakati wa git pull ijayo, Git itajaribu kuunganisha tawi lao na lako, na commit "zilizofutwa" zitarudi, sasa pamoja na merge commit isiyo na maana. Mbaya zaidi, ikiwa mtu alishasukuma commit zake juu yako, force push itazifuta.

Kwa hiyo kwenye matawi yaliyolindwa (main, release) force push kwa kawaida inazuiwa na mipangilio ya hifadhi. Ikiwa haiwezekani kuepuka kuandika upya, tumia git push --force-with-lease: itakataa ikiwa seva ina commit ambazo hujaziona.

Hali za kawaida za kughairi

Jinsi ya kughairi commit ya mwisho ambayo haijatumwa

git reset --soft HEAD~1   # mabadiliko yako kwenye index, unaweza kucommit upya
git reset HEAD~1          # mabadiliko kwenye faili, index tupu
git reset --hard HEAD~1   # mabadiliko yametupwa

Ikiwa unataka tu kurekebisha ujumbe au kuongeza faili uliyosahau, reset haihitajiki: tumia git add faili-uliyosahau.txt kisha git commit --amend.

Jinsi ya kughairi commit baada ya push

git revert <hash>
git push

Hili ndilo jibu la swali la kawaida "git reverse commit": hakuna amri tofauti ya git reverse kwenye Git. Commit ya "kinyume" inaundwa na git revert.

Jinsi ya kurudisha tawi kwenye hali ya seva

git fetch origin
git reset --hard origin/main

Ni muhimu tawi lako la ndani linapochanganyikiwa baada ya rebase iliyoshindikana au majaribio. Commit zote za ndani ambazo hazipo kwenye seva zitatoweka kwenye tawi.

Jinsi ya kurejesha commit baada ya reset iliyoshindikana

Git inarekodi kila mabadiliko ya HEAD kwenye jarida la reflog. Commit baada ya reset zinabaki kwenye hifadhidata ya Git angalau wiki kadhaa (kwa chaguo-msingi, ingizo lisilofikika la reflog huhifadhiwa siku 30).

git reflog
# 1c02e8f HEAD@{0}: reset: moving to HEAD~2
# a3f9c21 HEAD@{1}: commit: docs: README
# 7be41d0 HEAD@{2}: commit: feat: kuhifadhi majibu kwenye cache

git reset --hard a3f9c21   # au HEAD@{1}

Reflog ni ya ndani: inapatikana tu kwenye nakala yako ya repo na haipelekwi kwenye seva.

git clean: kufuta faili zisizofuatiliwa

git reset --hard haigusi faili ambazo Git haizifuatilii: faili mpya ambazo hazijaongezwa kwenye index, matokeo ya kujenga (build), kumbukumbu za logi. Kwa hizo kuna git clean. Amri hii hairudishiki: faili zilizofutwa nayo hazipatikani kwenye reflog wala kwenye tupio.

git clean -n      # jaribio kavu: onyesha kitakachofutwa
git clean -f      # futa faili zisizofuatiliwa
git clean -fd     # pamoja na folda zisizofuatiliwa
git clean -fdx    # pamoja na faili zilizopuuzwa (.gitignore): node_modules, dist
git clean -i      # chagua kwa mkono

Bila -f, Git kwa chaguo-msingi inakataa kufanya kazi (mpangilio clean.requireForce). Anza kila mara na -n, hasa na -x: itafuta pia .env yako ya ndani ikiwa iko kwenye orodha ya kupuuzwa.

Mchanganyiko wa kusafisha kabisa hadi commit ya mwisho: git reset --hard && git clean -fd.

Makosa ya kawaida

  • reset --hard badala ya --soft. Kilichocommitiwa kinaokolewa na reflog, kisichocommitiwa kimepotea. Tabia ya kufanya git stash kabla ya majaribio inatatua tatizo.
  • revert bila kuelewa utegemezi. Ikiwa commit za baadaye zilibadilisha mistari ileile, revert italeta mgongano. Uhariri wake kama mgongano wa kawaida: rekebisha faili, git add, kisha git revert --continue; ukibadili mawazo, git revert --abort.
  • Kuchanganya restore na reset. Ili kurudisha mabadiliko ya faili moja, hauhitaji reset ya tawi zima: tumia git restore faili.
  • force push kwenye main. Ni bora revert na push ya kawaida, hata historia ikiwa ndefu kidogo.

Hitimisho

git reset ni zana ya historia yako binafsi ambayo bado haijachapishwa: --soft huhifadhi mabadiliko kwenye index, --mixed kwenye faili, --hard hutupa yote. git revert ni kughairi salama kwenye matawi ya pamoja, inayoacha alama ya kweli kwenye historia. git clean husafisha faili zisizofuatiliwa, lakini inafanya kazi bila nafasi ya kosa. Mazoezi ya kughairi kwa restore, reset na revert yanafundishwa kwa vitendo katika kozi ya Git.

Maswali ya mara kwa mara

Je, git reset hufuta commit milele?

Hapana, commit zinabaki kwenye hifadhidata ya vitu na zinapatikana kupitia git reflog, hadi mkusanyaji wa takataka (garbage collector) azifute, kwa chaguo-msingi baada ya siku 30 kwa ingizo lisilofikika.

Je, inawezekana kughairi git revert?

Ndiyo. Commit ya revert ni commit ya kawaida, unaweza kuighairi kwa git revert nyingine, au ikiwa haijatumwa, kuiondoa kwa git reset.

git reset inatofautianaje na git checkout?

git reset husogeza kielekezi cha tawi la sasa, wakati git checkout (au git switch) hubadilisha HEAD kuelekea tawi au commit nyingine bila kubadilisha tawi lenyewe.

HEAD~1 na HEAD^ zinamaanisha nini?

Zote zinamaanisha mzazi wa commit ya sasa; HEAD~3 ni babu wa tatu kupitia wazazi wa kwanza, na HEAD^2 ni mzazi wa pili wa merge commit.

Je, kughairi git clean kunawezekana?

Si kwa zana za Git: faili zisizofuatiliwa zilizofutwa hazikuwa kwenye hifadhi, kwa hiyo daima endesha <code>git clean -n</code> kwanza.

Jifunze mada hii kwa video

Mada hii inafundishwa kwa kina pamoja na mazoezi katika kozi “Git kutoka mwanzo hadi msanidi programu anayejiweza”.

Nenda kwenye kozi