git checkout, switch, at restore: kailan gamitin ang alin
Dalawang magkaibang bagay ang kaya ng git checkout: magpalit ng branch at ibalik ang file, kaya mula Git 2.23 hinati ang gawain nito sa git switch (branch) at git restore (file). Para magpalit ng branch, gamitin ang git switch pangalan; para burahin ang hindi pa naka-commit na pagbabago sa file, gamitin ang git restore file; itira ang checkout para sa lumang script at pamilyar na gawain.
Bakit dalawa ang papel ng git checkout
Sa kasaysayan, dalawang magkaibang operasyon ang ginagawa ng git checkout. Kapag branch name ang ibinigay, inililipat nito ang HEAD at ina-update ang working directory. Kapag path ng file ang ibinigay, kinukuha nito ang bersyon ng file mula sa index o commit at tahimik na i-o-overwrite ang mga pagbabago ninyo. Iisang command ang ligtas na lumilipat sa pagitan ng mga branch, at minsan ay hindi na maibabalik na nagtatapon ng hindi pa nase-save na trabaho.
Dahil dito, lumabas sa Git 2.23 ang dalawang hiwalay na command: git switch para sa branch, at git restore para sa file. Hindi inalis ang checkout; gumagana pa rin ito nang buo, pero sa bagong code, dokumentasyon, at mga mungkahi ng mismong Git, switch at restore na ang ginagamit. Kung nagsisimula pa lang kayo, sila ang unahin; pero kailangan pa ring malaman ang checkout, dahil lumalabas ito sa mga tutorial, script, at sa interview.
Katumbas ng mga command
| Gawain | git checkout | Bagong command |
|---|---|---|
| Lumipat sa branch | git checkout main | git switch main |
| Gumawa ng branch at lumipat | git checkout -b feature | git switch -c feature |
| Gumawa o i-reset ang branch | git checkout -B feature | git switch -C feature |
| Bumalik sa naunang branch | git checkout - | git switch - |
| Pumunta sa commit (detached HEAD) | git checkout 3f2a1c9 | git switch --detach 3f2a1c9 |
| Burahin ang pagbabago sa file | git checkout -- app.js | git restore app.js |
| Alisin ang file sa index | git reset HEAD app.js | git restore --staged app.js |
| Kunin ang file mula sa ibang branch o commit | git checkout main -- app.js | git restore --source=main --staged --worktree app.js |
| Burahin ang lahat ng pagbabago sa folder | git checkout -- . | git restore . |
Pansinin ang -- sa mga checkout command. Ito ang separator na nagsasabing "ang susunod ay mga path". Pinoprotektahan nito laban sa kalituhan kapag magkapareho ang pangalan ng file at branch. Sa restore, walang ganitong problema, dahil file lang ang gumagana nito.
git checkout para sa branch
git checkout feature/login # lumipat
git checkout -b feature/login # gumawa mula sa kasalukuyang commit at lumipat
git checkout -b hotfix origin/main # gumawa mula sa remote branch
git checkout -t origin/feature/x # lokal na branch na sinusubaybayan ang remote
Kung walang lokal na branch pero may ganoong pangalan sa server, ang git checkout feature/x (tulad ng git switch feature/x) ang gagawa ng lokal na branch at magse-set ng tracking. Kailangan muna ang git fetch, kung hindi, hindi malalaman ng Git ang bagong remote branch.
Hindi nawawala ang mga hindi pa naka-commit na pagbabago kapag lumilipat: dinadala ang mga ito sa ibang branch kung walang salungatan. Kapag may salungatan, tatanggi ang Git at magmumungkahi na mag-commit o itabi muna gamit ang git stash. Ang flag na -f (--force) ay lilipat kahit itapon ang mga lokal na edit, at mapanganib na operasyon ito.
git switch: branch lang
Inuulit ng switch ang bahagi ng checkout para sa branch, pero mas mahigpit ang mga tuntunin. Ang pangunahing pagkakaiba: hindi ito lilipat sa commit o tag nang walang tahasang --detach. Ang git switch v1.0 ay magbibigay ng error sa halip na tahimik na pumasok sa detached HEAD, kaya mas mahirap na hindi sinasadyang mapunta "sa labas ng branch".
git switch main
git switch -c feature/cart
git switch -c feature/cart origin/main
git switch --detach v1.0
git switch - # naunang branch
git switch -m main # dalhin ang mga edit gamit ang three-way merge
git restore: undo button para sa mga file
Ibinabalik ng restore ang mga file sa naka-save na estado at hindi ginagalaw ang history ng mga commit. Para magamit ito nang tiyak, kailangan ninyong tandaan ang tatlong lugar ng Git: working directory (nakikita ninyo sa editor), index (inihanda gamit ang git add), at mga commit.
Paano burahin ang pagbabago sa file bago ang git add
git restore app.js # ibalik ang bersyon mula sa index
git restore src/ # lahat ng file sa folder
git restore . # lahat ng nabagong file sa project
Kapag walang flag, ibinabalik ng restore ang working directory mula sa index. Kung hindi naidagdag sa index ang file mula noong huling commit, pareho ito ng bersyon sa huling commit. Mawawala ang mga pagbabago nang walang bakas, at wala sa recycle bin ang mga ito, kaya bago ang git restore ., tingnan muna ang git diff.
Paano alisin ang file sa index pagkatapos ng git add
git restore --staged app.js
Hindi na nakahanda para sa commit ang file, pero nananatili ang mga edit ninyo. Ito ang pinakaligtas na anyo ng restore: walang nawawala. Ito mismo ang mungkahi ng git status sa seksyong "Changes to be committed".
Paano burahin ang lahat: sa index at sa file
git restore --staged --worktree app.js
# maikling anyo
git restore -SW app.js
Paano ibalik ang file mula sa ibang commit o branch
git restore --source=HEAD~2 app.js # bersyon ng dalawang commit ang nakalipas
git restore --source=main config.yml # bersyon mula sa branch na main
git restore --source=3f2a1c9 -- docs/ # buong folder mula sa commit
Bilang default, sa --source ay working directory lang ang binabago. Idagdag ang --staged kung gusto ninyong ihanda agad ang pagbabago para sa commit. Ang lumang paraang git checkout main -- app.js ay laging binabago pareho ang index at working directory.
Paano ibalik ang naburang file
git restore deleted.txt # nabura pero hindi pa naka-commit
git restore --source=HEAD~1 deleted.txt # naka-commit na ang pagbura
Kung hindi ninyo alam kung aling commit binura ang file, hanapin ito: git log --oneline -- deleted.txt. Ang pinakahuling commit sa listahan ang nagbura ng file, kaya ibalik ito mula sa parent nito: git restore --source=<hash>~1 deleted.txt.
restore, reset, at revert: huwag paghaluin
Lahat ng tatlong command ay "nag-u-undo", pero magkakaiba ang lalim:
- restore: gumagana sa mga file sa working directory at index, hindi binabago ang history. Ligtas para sa team.
- reset: inililipat ang pointer ng branch pabalik, binabago ang history. Ang
--softay nag-iiwan ng pagbabago sa index, ang--mixed(default) ay nasa working directory, ang--harday binubura ang mga ito. Delikado para sa commit na naipadala na sa shared branch. - revert: gumagawa ng bagong commit na kabaligtaran ng tinukoy. Hindi nire-rewrite ang history, kaya ito ang tamang paraan para i-undo ang commit na nasa server na.
Simpleng tuntunin: hindi pa naka-commit ang pagbabago, restore; lokal pa lang ang commit, reset; nasa katrabaho na ang commit, revert.
Detached HEAD pagkatapos ng checkout
Pagkatapos ng git checkout 3f2a1c9 o git checkout v1.0, makakakita kayo ng mahabang babala na "You are in 'detached HEAD' state". Tumuturo na ang HEAD sa commit, hindi sa branch. Magandang ito para tingnan ang lumang bersyon o patakbuhin ang test dito.
Puwede pa ring mag-commit sa estadong ito, pero hindi mapupunta sa anumang branch ang mga bagong commit. Kung may binago kayo at gusto ninyong i-save:
git switch -c fix-for-v1
Kung tiningnan lang ninyo: bumalik gamit ang git switch - o git switch main. Kung nakaalis na kayo nang hindi gumagawa ng branch, nandoon pa rin ang mga commit sa git reflog: hanapin ang hash at patakbuhin ang git branch rescue <hash>.
Karaniwang pagkakamali
error: pathspec 'feature' did not match any file(s) known to git
Walang nakitang branch o file na ganoon ang pangalan ang Git. Kadalasan, nasa server lang ang branch at hindi pa nagagawa ang fetch. Patakbuhin ang git fetch at ulitin. Tingnan din ang spelling: sensitive sa uppercase/lowercase ang mga pangalan ng branch.
Nagkamali at naitapon ang pagbabago gamit ang checkout -- o restore
Hindi itinatago ng Git ang hindi pa naka-add na pagbabago, kaya hindi na ito maibabalik gamit ang Git. Ang natitira ay ang local history ng editor o IDE. Kung naidagdag na ito gamit ang git add, nasa database pa rin ang nilalaman bilang "nakabiting" object, at makikita ito gamit ang git fsck --lost-found.
Magkapareho ang pangalan ng file at branch
Kung may branch na test at folder na test, magbibigay ng babala ang git checkout test tungkol sa kalabuan. Gamitin ang git switch test para sa branch, at git restore test (o git checkout -- test) para sa mga file.
Mga araw-araw na sitwasyon
Ilang sitwasyong madalas mangyari, at ang tamang command para sa bawat isa:
- Nagsimula kayong mag-edit ng file at napagtantong mali ang direksyon:
git restore file. - Naidagdag sa index ang sobrang file bago mag-commit:
git restore --staged file. - Kailangang lumipat agad sa ibang gawain sa gitna ng trabaho:
git stash, taposgit switch branch; pagbalik,git switch -atgit stash pop. - Gusto ninyong kunin ang isang file mula sa katabing branch nang hindi pinagsasama ang buong branch:
git restore --source=feature/x --staged --worktree path. - Kailangang tingnan kung may bug sa lumang bersyon:
git switch --detach v1.0, i-check, taposgit switch -. - Gusto ninyong i-rollback ang bahagi lang ng pagbabago sa file:
git restore -p file. Ipapakita ng Git ang bawat bahagi at magtatanong kung buburahin ito.
Lalo na kapaki-pakinabang ang interactive mode na -p (--patch): mayroon ito sa checkout at restore, at nakakatulong para itapon ang debug output habang nire-retain ang kapaki-pakinabang na pagbabago sa iisang file.
Paano suriin ang resulta bago mag-undo
Ang restore at checkout na may path ay nagtatapon ng pagbabago nang walang kumpirmasyon, kaya magandang tingnan muna kung ano ang mawawala. Ipinapakita ng git diff ang edit sa working directory laban sa index, ang git diff --staged ang nakahanda para sa commit, at ang git diff main -- app.js ang pagkakaiba ng file sa bersyon ng ibang branch. Kung nag-aalinlangan, i-save muna ang kasalukuyang estado gamit ang git stash: mula dito, laging maibabalik ang pagbabago, hindi tulad ng restore.
Buod
Pinagsasama ng git checkout ang pagpapalit ng branch at pagbabalik ng file, at iyon ang nagpapadelikado rito. Para sa branch, gamitin ang git switch; para sa file, ang git restore: ang isa ay binabago lang ang posisyon ng HEAD, ang isa ay ang nilalaman lang ng mga file. Ang mga branch, restore, reset, at revert na may mabuti at masamang sitwasyon ay itinuturo nang praktikal sa kursong Git namin.
Mga madalas itanong
Lumang command na ba ang git checkout?
Hindi, hindi ito idineklarang deprecated at gagana pa rin. Para sa araw-araw na gawain, inirerekomenda lang ang mas makitid at mas ligtas na git switch at git restore.
Mula kailan may switch at restore?
Lumabas ang dalawang command sa Git 2.23 (2019). Tingnan ang bersyon gamit ang git --version.
Maibabalik ba ang nagawa ng git restore?
Kung working directory ang naibalik, hindi nagse-save ang Git ng natapon na pagbabago, kaya hindi ito mababawi. Ligtas ang git restore --staged: nananatili ang pagbabago sa file, at maidadagdag ulit gamit ang git add.
Paano lumipat sa branch ng katrabaho?
Patakbuhin ang git fetch, tapos git switch pangalan-ng-branch: gagawa ang Git ng lokal na branch na nakakabit sa origin/pangalan-ng-branch.
Ano ang pagkakaiba ng git checkout . at git reset --hard?
Ibinabalik ng git checkout . (o git restore .) ang mga nabagong file sa bersyon ng index, nang hindi ginagalaw ang index at history. Ang git reset --hard ay nire-reset ang index at working directory sa isang commit, at kapag may tinukoy na commit, inililipat din nito ang branch.
Detalyadong tinatalakay ang paksang ito, may praktis, sa kursong “Git с нуля до уверенного разработчика”.
- Ветки: параллельная реальность вашего кода
- Отменяем ошибки: restore, reset, revert — правильно и опасно