git checkout, switch, dan restore: kapan memakai yang mana
git checkout punya dua fungsi berbeda: berpindah branch dan memulihkan file, sehingga sejak Git 2.23 tugasnya dipisah ke git switch (branch) dan git restore (file). Untuk berpindah branch gunakan git switch nama, untuk membatalkan perubahan yang belum di-commit pada file gunakan git restore file, dan checkout tetap dipakai pada skrip lama.
Mengapa git checkout punya dua peran
git checkout secara historis melakukan dua hal yang sangat berbeda. Dengan nama branch, ia berpindah HEAD dan memperbarui direktori kerja. Dengan path file, ia mengambil versi file dari index atau commit dan diam-diam menimpa perubahan Anda. Perintah yang sama bisa berpindah branch dengan aman, tetapi juga bisa membuang pekerjaan yang belum tersimpan tanpa bisa dikembalikan.
Karena itu, Git 2.23 memperkenalkan dua perintah terpisah: git switch untuk branch dan git restore untuk file. Checkout tidak dihapus dan masih berfungsi penuh, tetapi kode baru, dokumentasi, dan saran dari Git sendiri kini memakai switch dan restore. Jika Anda baru belajar, mulailah dari keduanya; checkout tetap perlu dikenal karena masih muncul di instruksi, skrip, dan saat wawancara kerja.
Padanan perintah
| Tugas | git checkout | Perintah baru |
|---|---|---|
| Berpindah ke branch | git checkout main | git switch main |
| Membuat branch dan pindah | git checkout -b feature | git switch -c feature |
| Membuat atau menimpa branch | git checkout -B feature | git switch -C feature |
| Kembali ke branch sebelumnya | git checkout - | git switch - |
| Pindah ke commit (detached HEAD) | git checkout 3f2a1c9 | git switch --detach 3f2a1c9 |
| Membatalkan perubahan pada file | git checkout -- app.js | git restore app.js |
| Mengeluarkan file dari index | git reset HEAD app.js | git restore --staged app.js |
| Mengambil file dari branch atau commit lain | git checkout main -- app.js | git restore --source=main --staged --worktree app.js |
| Membatalkan semua perubahan di folder | git checkout -- . | git restore . |
Perhatikan tanda -- pada perintah checkout. Itu adalah pemisah yang berarti «setelah ini adalah path». Tanda ini mencegah kerancuan ketika nama file dan nama branch sama. Pada restore masalah itu tidak ada, karena perintahnya hanya bekerja dengan file.
git checkout untuk branch
git checkout feature/login # berpindah
git checkout -b feature/login # membuat dari commit saat ini lalu berpindah
git checkout -b hotfix origin/main # membuat dari branch remote
git checkout -t origin/feature/x # branch lokal yang melacak branch remote
Jika branch lokal belum ada tetapi di server ada branch dengan nama itu, git checkout feature/x (sama seperti git switch feature/x) akan membuat branch lokal dan mengatur pelacakannya secara otomatis. Sebelumnya perlu git fetch, karena jika tidak Git belum mengenal branch remote yang baru.
Berpindah branch tidak menghilangkan perubahan yang belum di-commit: perubahan itu ikut dibawa ke branch lain selama tidak bertabrakan. Jika bertabrakan, Git menolak dan menyarankan commit atau simpan sementara dengan git stash. Opsi -f (--force) akan berpindah sambil membuang perubahan lokal; ini operasi yang berbahaya.
git switch: hanya untuk branch
Switch mengerjakan bagian branch dari checkout, tetapi dengan aturan yang lebih ketat. Perbedaan utamanya: ia tidak berpindah ke commit atau tag tanpa --detach yang eksplisit. Perintah git switch v1.0 akan menghasilkan error alih-alih diam-diam berpindah ke detached HEAD, sehingga lebih sulit tanpa sengaja berada «di luar branch».
git switch main
git switch -c feature/cart
git switch -c feature/cart origin/main
git switch --detach v1.0
git switch - # branch sebelumnya
git switch -m main # bawa perubahan dengan three-way merge
git restore: tombol batal untuk file
Restore mengembalikan file ke keadaan yang tersimpan dan tidak menyentuh riwayat commit sama sekali. Agar bisa memakainya dengan yakin, ingat tiga area di Git: direktori kerja (yang terlihat di editor), index (yang sudah disiapkan lewat git add), dan commit.
Membatalkan perubahan pada file sebelum git add
git restore app.js # kembalikan versi dari index
git restore src/ # semua file di dalam folder
git restore . # semua file yang berubah di proyek
Tanpa flag, restore mengembalikan direktori kerja dari index. Jika file tidak pernah ditambahkan ke index sejak commit terakhir, hasilnya sama dengan versi di commit terakhir. Perubahan itu lenyap tanpa jejak dan tidak masuk ke tempat sampah, jadi sebelum menjalankan git restore . periksa dulu dengan git diff.
Mengeluarkan file dari index setelah git add
git restore --staged app.js
File berhenti disiapkan untuk commit, tetapi perubahan Anda di dalamnya tetap ada. Ini bentuk restore yang paling aman karena tidak ada yang hilang. Perintah inilah yang disarankan git status pada bagian «Changes to be committed».
Membatalkan semuanya: di index dan di file
git restore --staged --worktree app.js
# bentuk singkat
git restore -SW app.js
Mengambil file dari commit atau branch lain
git restore --source=HEAD~2 app.js # versi dari dua commit yang lalu
git restore --source=main config.yml # versi dari branch main
git restore --source=3f2a1c9 -- docs/ # seluruh folder dari suatu commit
Secara default, --source hanya mengubah direktori kerja. Tambahkan --staged jika ingin langsung menyiapkan perubahan itu untuk commit. Cara lama git checkout main -- app.js selalu mengubah index sekaligus direktori kerja.
Memulihkan file yang terhapus
git restore deleted.txt # sudah dihapus tetapi belum di-commit
git restore --source=HEAD~1 deleted.txt # penghapusannya sudah di-commit
Jika tidak tahu di commit mana file itu dihapus, cari dengan git log --oneline -- deleted.txt. Commit terakhir dalam daftar adalah tempat file dihapus, dan file harus dipulihkan dari induknya: git restore --source=<hash>~1 deleted.txt.
restore, reset, dan revert: jangan tertukar
Ketiganya sama-sama «membatalkan», tetapi pada kedalaman yang berbeda:
- restore — bekerja pada file di direktori kerja dan index, tidak mengubah riwayat. Aman untuk dipakai.
- reset — memindahkan penunjuk branch ke belakang sambil menulis ulang riwayat.
--softmenyisakan perubahan di index,--mixed(default) menyisakannya di direktori kerja,--hardmembuangnya. Berbahaya untuk commit yang sudah dikirim ke branch bersama. - revert — membuat commit baru yang merupakan kebalikan dari commit yang dimaksud. Riwayat tidak ditulis ulang, sehingga ini cara yang benar untuk membatalkan commit yang sudah ada di server.
Aturan sederhananya: perubahan belum di-commit — gunakan restore; commit hanya ada di komputer Anda — gunakan reset; commit sudah dipakai rekan kerja — gunakan revert.
Detached HEAD setelah checkout
Setelah menjalankan git checkout 3f2a1c9 atau git checkout v1.0, Anda akan melihat peringatan panjang «You are in 'detached HEAD' state». HEAD sekarang menunjuk ke commit, bukan ke branch. Ini berguna untuk melihat versi lama atau menjalankan tes di atasnya.
Anda boleh membuat commit dalam keadaan ini, tetapi commit baru tidak akan masuk ke branch mana pun. Jika Anda sudah mengubah sesuatu dan ingin menyimpannya:
git switch -c fix-for-v1
Jika hanya melihat-lihat, kembali saja dengan git switch - atau git switch main. Jika sudah pindah tanpa membuat branch, commit-nya masih bisa ditemukan lewat git reflog: cari hash-nya lalu jalankan git branch rescue <hash>.
Kesalahan yang sering terjadi
error: pathspec 'feature' did not match any file(s) known to git
Git tidak menemukan branch maupun file dengan nama itu. Biasanya branch hanya ada di server dan Anda belum menjalankan fetch. Jalankan git fetch lalu coba lagi. Periksa juga penulisannya, karena nama branch sensitif terhadap huruf besar-kecil.
Perubahan terbuang karena checkout -- atau restore
Perubahan yang belum di-commit dan belum ada di index tidak disimpan oleh Git, sehingga tidak bisa dikembalikan lewat Git. Yang tersisa hanyalah riwayat lokal dari editor atau IDE. Namun jika file sudah pernah ditambahkan dengan git add, isinya tersimpan di basis data sebagai objek yatim, dan bisa dicari dengan git fsck --lost-found.
File dan branch dengan nama yang sama
git checkout test ketika ada branch test sekaligus folder test akan memberi peringatan ambigu. Gunakan git switch test untuk branch dan git restore test (atau git checkout -- test) untuk file.
Skenario harian
Beberapa situasi yang sering terjadi, beserta perintah yang tepat untuk masing-masing:
- Sudah mulai mengubah file dan sadar salah arah —
git restore file. - Salah menambahkan file ke index sebelum commit —
git restore --staged file. - Perlu segera pindah ke tugas lain di tengah pekerjaan —
git stash, lalugit switch cabang; setelah kembali, jalankangit switch -dangit stash pop. - Ingin mengambil satu file dari branch lain tanpa menggabungkan seluruh branch —
git restore --source=feature/x --staged --worktree path. - Ingin memeriksa apakah bug sudah ada di versi lama —
git switch --detach v1.0, lakukan pengecekan, lalugit switch -. - Ingin membatalkan sebagian perubahan dalam satu file —
git restore -p file: Git menampilkan setiap potongan dan menanyakan apakah akan dibatalkan.
Mode interaktif -p (--patch) sangat berguna. Mode ini tersedia pada checkout maupun restore, dan memungkinkan Anda membuang kode debug sambil tetap menyimpan perbaikan yang ada di file yang sama.
Memeriksa hasil sebelum dibatalkan
Restore dan checkout dengan path membuang perubahan tanpa konfirmasi, jadi biasakan melihat dulu apa yang akan hilang. git diff menampilkan perubahan di direktori kerja terhadap index, git diff --staged menampilkan yang sudah disiapkan untuk commit, dan git diff main -- app.js menampilkan perbedaan file dengan versi di branch lain. Jika ragu, simpan kondisi saat ini dengan git stash: dari sana perubahan selalu bisa dikembalikan, berbeda dengan restore.
Ringkasan
git checkout menggabungkan perpindahan branch dan pemulihan file, dan justru di situlah letak bahayanya. Untuk branch gunakan git switch, untuk file gunakan git restore: satu perintah hanya mengubah posisi HEAD, perintah lainnya hanya mengubah isi file. Branch, restore, reset, dan revert beserta skenario yang baik dan yang berisiko dibahas dengan praktik dalam kursus Git.
Pertanyaan umum
Apakah git checkout sudah usang?
Tidak. Perintah ini belum dinyatakan usang dan akan terus berfungsi. Hanya saja untuk pekerjaan harian Git menyarankan git switch dan git restore yang lebih sempit dan aman.
Sejak versi Git berapa ada switch dan restore?
Keduanya muncul di Git 2.23 (2019). Versi Git Anda bisa dicek dengan git --version.
Bisakah perubahan yang dibuang git restore dikembalikan?
Jika yang dipulihkan adalah direktori kerja, perubahan yang terbuang tidak tersimpan oleh Git dan tidak bisa dikembalikan. git restore --staged aman, karena perubahan tetap ada di file dan bisa ditambahkan lagi dengan git add.
Bagaimana cara berpindah ke branch milik rekan kerja?
Jalankan git fetch, lalu git switch nama-branch. Git akan membuat branch lokal yang terhubung dengan origin/nama-branch.
Apa bedanya git checkout . dengan git reset --hard?
git checkout . (atau git restore .) mengembalikan file yang berubah ke versi di index tanpa menyentuh index maupun riwayat. git reset --hard mengembalikan index dan direktori kerja ke commit, dan jika diberi commit sebagai argumen juga memindahkan branch.
Topik ini dibahas mendalam dengan praktik di kursus “Git dari Nol hingga Pengembang Percaya Diri”.
- Cabang: Realitas Paralel untuk Kode Anda
- Membatalkan Kesalahan: restore, reset, revert — dengan Benar dan Berbahaya