Menyimpan pekerjaan ke tumpukan stash terbukti mudah; pertanyaan sesungguhnya muncul saat mengambilnya kembali. Tiga perintah mengurus siklus hidup tumpukan: apply menyalin isi simpanan ke working tree tanpa menghapus apa pun, pop menggabungkan pengambilan dan pembuangan sekali jalan, dan drop membuang simpanan yang tak lagi diperlukan. Kita uji ketiganya pada satu repository berisi tiga draf yang bertumpuk, lengkap dengan skenario terburuknya — pop yang bentrok dengan isi branch — dan nasib simpanan ketika bentrok itu terjadi. git stash
sudah membahas cara menyimpan; chapter ini mengurus sisa ceritanya.
Tiga Draf dalam Tumpukan LIFO #
Repository latihan-simpanan menyiapkan dua berkas tracked, lalu tiga draf dibuat dan disimpan berturut-turut — masing-masing dengan pesan bermakna:
mkdir latihan-simpanan && cd latihan-simpanan
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf 'beranda\n' > situs.md
git add situs.md
git commit -m "Buat halaman beranda"
printf '# Tentang\n' > tentang.md
git add tentang.md
git commit -m "Tambah halaman tentang"
printf 'beranda\nfooter v1\n' > situs.md
git stash push -m "draf footer"
printf '# Tentang\nkontak baru\n' > tentang.md
git stash push -m "draf kontak"
printf 'beranda\ngaleri v1\n' > situs.md
git stash push -m "draf galeri"
git stash listOutput yang Dihasilkan:
Saved working directory and index state On main: draf footerOutput yang Dihasilkan:
Saved working directory and index state On main: draf kontakOutput yang Dihasilkan:
Saved working directory and index state On main: draf galeriOutput yang Dihasilkan:
stash@{0}: On main: draf galeri
stash@{1}: On main: draf kontak
stash@{2}: On main: draf footerUrutan tumpukan terbaca jelas: tumpukan bersifat LIFO — simpanan terbaru selalu di stash@{0}, sehingga draf galeri (disimpan terakhir) berada paling atas dan draf footer (disimpan pertama) terdorong ke stash@{2}. Nomor ini bukan identitas permanen: setiap kali sebuah entri dibuang, entri di bawahnya naik dan bernomor ulang.
Memeriksa Isi dengan git stash show #
Sebelum mengambil, isi simpanan bisa diperiksa tanpa risiko. Tanpa argumen, show memeriksa simpanan teratas:
git stash show
git stash show -p
git stash show "stash@{2}"Output yang Dihasilkan:
situs.md | 1 +
1 file changed, 1 insertion(+)Output yang Dihasilkan:
diff --git a/situs.md b/situs.md
index 516cb37..cbd7a39 100644
--- a/situs.md
+++ b/situs.md
@@ -1 +1,2 @@
beranda
+galeri v1Output yang Dihasilkan:
situs.md | 1 +
1 file changed, 1 insertion(+)Keluaran pertama adalah ringkasan statistik: satu berkas berubah, satu baris ditambah. Flag -p membuka diff lengkapnya — suntingan +galeri v1 pada situs.md. Bentuk dengan indeks "stash@{2}" membuktikan simpanan lama pun bisa diintip langsung tanpa memindahkan tumpukan; format kutip penting agar kurung kurawal tidak ditafsirkan shell.
git stash apply: Mengambil Tanpa Membuang #
apply menyalin isi simpanan teratas ke working tree dan membiarkan tumpukan tidak tersentuh:
git stash apply
git status --short
git stash listOutput yang Dihasilkan:
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: situs.md
no changes added to commit (use "git add" and/or "git commit -a")Output yang Dihasilkan:
M situs.mdOutput yang Dihasilkan:
stash@{0}: On main: draf galeri
stash@{1}: On main: draf kontak
stash@{2}: On main: draf footerDua bukti berlapis: suntingan galeri v1 hadir kembali sebagai perubahan unstaged ( M — kecuali memakai --index sebagaimana diperlihatkan Memulihkan Staging
), dan git stash list masih utuh tiga entri. Inilah guna apply: simpanan bisa dicoba ke working tree berulang kali, atau dipakai di beberapa branch, tanpa risiko kehilangan cadangan. Setelah pekerjaan dilanjutkan dan di-commit, simpanannya dibuang manual:
git add situs.md
git commit -m "Selesaikan draf galeri"
git stash drop
git stash listOutput yang Dihasilkan:
[main d02e003] Selesaikan draf galeri
1 file changed, 1 insertion(+)Output yang Dihasilkan:
Dropped refs/stash@{0} (e52cd99576926092632895f293fac4a14213939f)Output yang Dihasilkan:
stash@{0}: On main: draf kontak
stash@{1}: On main: draf footergit stash drop polos menjatuhkan simpanan teratas — hash lengkap commit simpanan tercetak di pesan Dropped, dan draf kontak otomatis naik menjadi stash@{0}. Hash di mesin pembaca akan berbeda.
pop yang Bentrok: Simpanan Tetap Aman #
Sekarang kasus yang menakutkan: pop yang digabungkan apply + drop ternyata bentrok. Kita ambil draf footer di stash@{1} — simpanan itu dibuat ketika situs.md masih satu baris, sementara HEAD kini sudah memuat galeri v1:
git stash pop "stash@{1}"
git stash list
cat situs.mdOutput yang Dihasilkan:
Auto-merging situs.md
CONFLICT (content): Merge conflict in situs.md
On branch main
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: situs.md
no changes added to commit (use "git add" and/or "git commit -a")
The stash entry is kept in case you need it again.Output yang Dihasilkan:
stash@{0}: On main: draf kontak
stash@{1}: On main: draf footerOutput yang Dihasilkan:
beranda
<<<<<<< Updated upstream
galeri v1
=======
footer v1
>>>>>>> Stashed changesMekanisme pengambilan stash adalah merge tiga pihak, sehingga benturan isi ditandai persis seperti merge conflict
— hanya label sisinya khas stash: Updated upstream untuk isi branch saat ini, Stashed changes untuk isi simpanan. Baris penutupnya adalah kunci bab ini: The stash entry is kept in case you need it again. — dan git stash list membuktikan draf footer masih berdiri di stash@{1}.
Penanda konflik diselesaikan manual — kedua suntingan digabung — lalu draf diselesaikan dan simpanannya dibuang dengan indeks eksplisit:
printf 'beranda\ngaleri v1\nfooter v1\n' > situs.md
git add situs.md
git commit -m "Selesaikan draf footer"
git stash drop "stash@{1}"
git stash listOutput yang Dihasilkan:
[main 395738c] Selesaikan draf footer
1 file changed, 1 insertion(+)Output yang Dihasilkan:
Dropped stash@{1} (bbcad7cb2042dde41cccc3a33fe49ee7acfa4ace)Output yang Dihasilkan:
stash@{0}: On main: draf kontakBentuk git stash drop "stash@{1}" menjatuhkan entri spesifik tanpa menyentuh stash@{0} — pola yang sama bekerja untuk apply dan pop.
pop Bersih: Ambil Sekaligus Buang #
Sisa tumpukan tinggal satu dan tidak lagi bertabrakan dengan branch, saatnya melihat pop dalam kondisi idealnya:
git stash pop
git status --shortOutput yang Dihasilkan:
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: tentang.md
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (01aa23767a0a6be3abf65a1e15bf8fed65c724ad)Output yang Dihasilkan:
M tentang.mdSatu perintah menghasilkan dua peristiwa: suntingan draf kontak hadir di tentang.md dan baris Dropped refs/stash@{0} menandakan simpanannya sekaligus dijatuhkan. Perintah git stash list kini mencetak kosong — tumpukan habis. Referensi lengkap seluruh subperintah ada di git-stash
.
| Perintah | Efek pada tumpukan | Kecocokan penggunaan |
|---|---|---|
git stash show [-p] [stash@{N}] | tidak berubah | memeriksa isi sebelum diambil |
git stash apply [stash@{N}] | tidak berubah | mencoba simpanan di beberapa branch |
git stash pop [stash@{N}] | diterapkan lalu dijatuhkan bila bersih | simpanan sekali pakai |
git stash drop [stash@{N}] | dijatuhkan tanpa diterapkan | membuang simpanan usang |
Tiga draf tuntas: dua lewat jalur apply + drop manual, satu lewat pop bersih. Namun satu kelemahan besar masih tersimpan pada skenario terakhir — konflik terjadi karena simpanan lama dibandingkan dengan branch yang sudah berjalan jauh. git stash branch memotong akar masalahnya dengan memindahkan titik pijak; pembahasannya menanti di Stash Branch
.