Kamu sedang mengerjakan fitur export user ke Excel di project Laravel. Method baru di app/Models/User.php sudah ditambahkan, controller export-nya belum kelar, belum sempat di-test. Pokoknya pekerjaan masih separuh jalan. Lalu tiba-tiba muncul bug di production: halaman login melempar error di jam tertentu, dan harus diperbaiki sekarang juga.
Masalahnya, working directory kamu sedang kotor. Pindah ke branch main? Git akan menolak karena ada perubahan yang belum di-commit. Commit dulu? History jadi penuh commit WIP yang tidak jelas maksudnya — belum lagi kalau perubahannya belum siap di-commit.
Di sinilah git stash berperan. Stash menyimpan perubahanmu sementara, membuat working directory kembali bersih, dan mengembalikan semua perubahan itu saat kamu siap. Artikel ini membahas cara kerjanya, perintah-perintah dasar yang paling sering dipakai, varian lanjutan untuk situasi tertentu, sampai cara memulihkan stash yang terlanjur terhapus.
Apa Itu git stash?
git stash merekam state working directory dan index — artinya semua perubahan yang sedang berjalan, baik yang sudah di-git add maupun belum — menjadi sebuah commit khusus, lalu mengembalikan working directory menjadi bersih sesuai HEAD. Setelah stash, git status kembali tenang, seolah-olah tidak ada yang pernah kamu ubah.
Stash disimpan di referensi khusus bernama refs/stash. Stash paling baru selalu menjadi stash@{0}, stash berikutnya stash@{1}, dan seterusnya. Setiap entri mendapat pesan default dengan format WIP on <branch>: <sha> <pesan commit>, misalnya stash@{0}: WIP on feature/export-user: 3f8a1c2 Add export user controller.
Poin terpenting: stash tidak terikat branch. Kamu boleh membuat stash di branch feature/export-user, lalu menerapkannya di branch main. Justru ini kegunaannya. Konsekuensinya, saat diterapkan di branch yang sudah banyak berubah, stash bisa memunculkan konflik.
Stash vs Commit
Perbedaan mendasarnya dengan commit: commit mengubah history dan menjadi bagian permanen dari riwayat project. Stash tidak mengubah apa-apa — ia hanya titipan sementara. Karena bersifat sementara, stash juga lokal: tidak pernah ikut ter-push ke remote. Kalau kamu pindah mesin atau clone ulang repository, stash tidak ikut serta.
Kalau kebutuhanmu justru mengubah history — misalnya membatalkan commit yang sudah terlanjur dibuat — maka alat yang tepat adalah git reset dan git revert, bukan stash. Perbedaannya sudah pernah kita bahas di artikel Git Reset vs Git Revert. Stash untuk menyimpan, reset/revert untuk mengubah riwayat.
Karena disimpan sebagai objek commit di belakang layar, stash juga bisa dipulihkan meski sudah dihapus dari daftar — ini kita bahas di bagian menghapus stash.
Menyimpan Perubahan
Perintah paling dasar: git stash tanpa argumen, yang setara dengan git stash push. Keduanya menyimpan perubahan yang sedang berjalan — file tracked yang dimodifikasi dan file yang sudah di-staging. File untracked baru tidak ikut secara default.
Menambahkan Pesan Deskriptif
Supaya daftar stash tidak membingungkan, biasakan memberi pesan:
git stash push -m "WIP: export user ke excel"
Dengan -m, pesanmu akan tampil di git stash list. Tanpa -m, Git membuatkan label default WIP on <branch> yang isinya sama untuk setiap stash di branch itu — lama-lama tidak bisa dibedakan.
Menyimpan Hanya File Tertentu
Pathspec membatasi stash hanya untuk file yang cocok:
git stash push -- app/Models/User.php
Perintah di atas menyimpan perubahan di app/Models/User.php saja. File lain yang sedang kamu ubah tetap utuh — tidak ikut tersimpan, dan yang penting, tidak ikut di-rollback. Ini berguna kalau kamu cuma mau menyimpan sebagian perubahan sementara sisanya tetap berjalan.
Kalau kamu pernah mengikuti tutorial lama yang memakai git stash save, ketahuilah bahwa perintah itu sekarang deprecated. Penggantinya memang git stash push, karena push mendukung pathspec seperti contoh di atas.
Melihat dan Memeriksa Stash
git stash list menampilkan semua stash yang tersimpan, lengkap dengan branch asal dan pesannya:
git stash list
Contoh outputnya:
stash@{0}: WIP on feature/export-user: 3f8a1c2 Add export user controller
stash@{1}: WIP on main: 9cc0589 Fix login redirect
Untuk memeriksa file apa saja yang berubah di dalam sebuah stash, git stash show menampilkan diffstat-nya:
git stash show
Mau melihat detail per baris? Tambahkan -p agar ditampilkan diff penuh dalam bentuk patch:
git stash show -p
Keduanya bisa diarahkan ke stash tertentu dengan selector — misalnya git stash show -p stash@{1} untuk stash kedua dari yang terbaru. Stash juga bisa dirujuk cukup dengan angka indeksnya, jadi stash@{1} bisa ditulis sebagai 1. Untuk stash yang dibuat dengan -u, file untracked di dalamnya bisa ditampilkan dengan git stash show -u (alias --include-untracked). Perilaku default git stash show juga bisa diubah lewat konfigurasi stash.showStat, stash.showPatch, dan stash.showIncludeUntracked.
Memulihkan Perubahan
git stash pop
Perintah yang paling sering dipakai: git stash pop menerapkan stash paling baru ke working directory, lalu menghapusnya dari daftar.
git stash pop
Satu hal yang perlu dipahami sejak awal: kalau pop menemui konflik, pop tidak menghapus stash. Git berhenti, memberimu daftar file yang konflik, dan entri stash tetap tersimpan di daftar. Kamu harus menyelesaikan konfliknya dulu, lalu menghapus stash secara manual dengan git stash drop kalau memang sudah tidak dibutuhkan. Banyak yang kaget saat stash-nya "tidak hilang" — ini proteksi, bukan bug.
git stash apply
git stash apply bekerja seperti pop, tapi tidak menghapus stash dari daftar.
git stash apply
Kapan pakai yang mana? pop kalau kamu yakin perubahannya tinggal dipakai sekali — sekalian bersih. apply kalau stash-nya masih ingin dipertahankan: misalnya mau menerapkan perubahan yang sama ke beberapa tempat, atau masih ragu dan mau memastikan dulu sebelum stash-nya hilang.
Mengembalikan Posisi Staging dengan --index
Secara default, pop dan apply mengembalikan perubahan sebagai unstaged — semuanya kembali seperti belum di-git add. Kalau sebelumnya kamu sudah staging sebagian perubahan dan ingin posisi itu dipulihkan, gunakan --index:
git stash apply --index
Perlu diingat: --index bisa gagal kalau hasilnya konflik. Karena perubahan konflik tersimpan di index, Git tidak bisa menerapkan ulang perubahan sesuai posisi staging aslinya. Kalau konflik muncul, ikuti alur resolve seperti biasa.
Alur Hotfix
Kembali ke skenario di awal. Rangkaian perintahnya kurang lebih begini:
git stash push -m "WIP: export user ke excel"
git switch main
git pull origin main
# perbaiki file bug di sini
git add -A
git commit -m "fix: perbaiki redirect login"
git push origin main
git switch feature/export-user
git stash pop
Setelah stash, working directory bersih sehingga kamu bebas pindah ke main, pull, dan menyelesaikan hotfix. Commit hotfix dibuat normal, di-push, lalu kamu kembali ke branch fitur dan menjalankan git stash pop untuk melanjutkan pekerjaan. Karena stash tidak terikat branch, pop bekerja di branch mana pun — tinggal pastikan kamu pop di branch yang benar.
Varian Lanjutan
-u dan --include-untracked
Secara default, stash tidak menyentuh file untracked. File baru yang belum pernah di-git add tidak ikut tersimpan. Kalau itu yang kamu butuhkan:
git stash -u
-u alias --include-untracked ikut menyimpan file untracked — tapi tidak termasuk file yang di-ignore seperti .env atau node_modules. Untuk menyertakan juga file ignored, gunakan -a alias --all:
git stash -a
Hati-hati dengan -a: artinya file konfigurasi lokal yang bisa berisi secret ikut tersimpan. Di project Laravel, git stash -a akan membawa .env masuk ke stash — pastikan memang itu yang kamu inginkan.
--keep-index
git stash push --keep-index menyimpan perubahan yang belum di-staging, tapi membiarkan perubahan yang sudah staged tetap berada di index.
Ini dipakai untuk skenario testing per bagian sebelum commit. Kamu punya satu set perubahan besar dan ingin memecahnya jadi beberapa commit. Alurnya: staging satu bagian, stash sisanya dengan --keep-index, test bagian yang sudah staged, commit, lalu pop untuk melanjutkan:
git add app/Http/Controllers/UserExportController.php
git stash push --keep-index
php artisan test
git commit -m "feat: tambah controller export user"
git stash pop
Setelah --keep-index, perubahan yang sudah di-git add tetap ada di index meskipun stash berjalan — jadi kamu bisa test dan commit bagian itu lebih dulu. Sisa perubahan kembali lagi setelah git stash pop.
-p dan --patch
git stash push -p menjalankan stash secara interaktif per-hunk:
git stash push -p
Git menampilkan potongan perubahan satu per satu dan kamu menentukan mana yang ikut disimpan. Ini ideal saat dalam satu file ada dua perubahan yang tidak berhubungan — yang satu ingin di-stash, yang lain mau dibawa ke commit sekarang.
--staged
Di Git versi modern, ada git stash push --staged (alias -S) untuk menyimpan hanya perubahan yang sudah staged:
git stash push --staged
Contoh kasusnya: perubahan fitur A sudah kamu simpan di staging area, tapi belum mau di-commit karena ada urusan lain — sementara perubahan fitur B di working tree tidak ingin kamu sentuh. --staged menyimpan yang A saja.
Stash dan Branch
Kalau kamu menyadari pekerjaan di stash seharusnya dikerjakan di branch terpisah — atau branch sekarang sudah berubah terlalu jauh sehingga apply berisiko konflik — git stash branch adalah jalan keluarnya:
git stash branch fitur/export-user
Perintah ini membuat branch baru dari commit tempat stash awalnya dibuat, memindahkanmu ke sana, menerapkan perubahan stash, lalu menghapus stash dari daftar. Karena branch baru berangkat dari titik yang sama dengan stash, penerapannya jauh lebih mulus dibanding apply ke branch yang sudah berevolusi.
Menghapus Stash
git stash drop
Menghapus satu entri stash:
git stash drop stash@{0}
Tanpa selector, entri terbaru yang dihapus. Ini operasi yang wajar untuk membersihkan stash yang sudah tidak dipakai.
git stash clear
git stash clear menghapus semua stash sekaligus. Dan inilah bagian yang perlu ditegaskan: clear tidak punya undo normal.
git stash clear
Berbeda dengan commit yang masih bisa diselamatkan lewat reflog, clear langsung menghapus semua entri dari daftar. Kalau masih butuh isi stash tersebut, jalankan git stash list dulu sebelum memutuskan clear.
Memulihkan Stash yang Terlanjur Terhapus
Karena stash disimpan sebagai objek commit, stash yang sudah di-drop atau ter-clear sebenarnya masih ada di dalam repository sebagai objek yang menggantung (dangling) — selama belum dibersihkan oleh garbage collection.
Untuk menemukannya:
git fsck --unreachable | grep commit
Dari daftar commit yang muncul, cari yang pesannya mengandung "WIP" — itu stash yang terlanjur terhapus. Lalu pulihkan dengan:
git stash apply <sha-commit-tersebut>
Di sini apply digunakan, bukan pop, karena entri tersebut sudah tidak terdaftar sebagai stash. Setelah di-apply, kamu bisa melanjutkan seperti biasa. Perlu diingat: pemulihan ini tidak dijamin selamanya — begitu objek unreachable dibersihkan oleh git gc, stash tersebut benar-benar hilang. Jadi jangan mengandalkan trik ini untuk seenaknya memakai git stash clear.
Kesalahan Umum yang Harus Dihindari
- Mengira
git stash clearbisa di-undo. Tidak ada undo normal. Kalau masih ragu, hapus entri satu per satu dengandrop. - Mengira
git stash popselalu menghapus stash. Saat ada konflik, pop berhenti dan stash tetap tersimpan. Selesaikan konfliknya, laludropmanual. - Mengira stash menangkap semua file. Default hanya menyimpan file tracked yang berubah atau staged. File untracked dan ignored butuh
-uatau-a. - Menumpuk stash tanpa pesan yang jelas. Stash yang menumpuk tanpa
-mlama-lama tidak bisa dibedakan satu sama lain. Biasakangit stash push -mdan rutin bersihkan dengandrop. - Melupakan bahwa stash bersifat lokal. Stash tidak pernah ikut push. Pekerjaan penting yang hanya dititipkan di stash bisa hilang jejaknya saat kamu pindah mesin. Karena itu stash juga sering dipakai sebagai jaring pengaman sementara sebelum operasi rewrite history — misalnya saat membersihkan
.envdari riwayat git — bukan sebagai tempat penyimpanan jangka panjang.
Penutup
git stash adalah penyelamat untuk pekerjaan yang belum selesai: menyimpan perubahan, membersihkan working directory, dan mengembalikan semuanya saat kondisi sudah memungkinkan. Pop untuk mengambil sekaligus menghapus, apply untuk mengambil tanpa menghapus, --index untuk memulihkan posisi staging, dan stash branch untuk memindahkan pekerjaan ke branch baru.
Biasakan tiga hal: tulis pesan deskriptif dengan -m, periksa git stash list secara berkala, dan jangan asal clear. Kalau terlanjur terhapus, git fsck --unreachable masih bisa menolong selama objek commit-nya belum dibersihkan.
Untuk pendalaman, dokumentasi resmi adalah rujukan terbaik: git-stash dan bab Stashing and Cleaning di Pro Git Book. Praktikkan langsung di repository-mu — semakin sering dipakai, semakin terasa manfaatnya saat harus berganti konteks kerja secara mendadak.
Fitur komentar belum diaktifkan oleh administrator.