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:

bash
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 list

Output yang Dihasilkan:

text
Saved working directory and index state On main: draf footer

Output yang Dihasilkan:

text
Saved working directory and index state On main: draf kontak

Output yang Dihasilkan:

text
Saved working directory and index state On main: draf galeri

Output yang Dihasilkan:

text
stash@{0}: On main: draf galeri
stash@{1}: On main: draf kontak
stash@{2}: On main: draf footer

Urutan 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:

bash
git stash show
git stash show -p
git stash show "stash@{2}"

Output yang Dihasilkan:

text
 situs.md | 1 +
 1 file changed, 1 insertion(+)

Output yang Dihasilkan:

text
diff --git a/situs.md b/situs.md
index 516cb37..cbd7a39 100644
--- a/situs.md
+++ b/situs.md
@@ -1 +1,2 @@
 beranda
+galeri v1

Output yang Dihasilkan:

text
 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:

bash
git stash apply
git status --short
git stash list

Output yang Dihasilkan:

text
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:

text
 M situs.md

Output yang Dihasilkan:

text
stash@{0}: On main: draf galeri
stash@{1}: On main: draf kontak
stash@{2}: On main: draf footer

Dua 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:

bash
git add situs.md
git commit -m "Selesaikan draf galeri"
git stash drop
git stash list

Output yang Dihasilkan:

text
[main d02e003] Selesaikan draf galeri
 1 file changed, 1 insertion(+)

Output yang Dihasilkan:

text
Dropped refs/stash@{0} (e52cd99576926092632895f293fac4a14213939f)

Output yang Dihasilkan:

text
stash@{0}: On main: draf kontak
stash@{1}: On main: draf footer

git 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:

bash
git stash pop "stash@{1}"
git stash list
cat situs.md

Output yang Dihasilkan:

text
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:

text
stash@{0}: On main: draf kontak
stash@{1}: On main: draf footer

Output yang Dihasilkan:

text
beranda
<<<<<<< Updated upstream
galeri v1
=======
footer v1
>>>>>>> Stashed changes

Mekanisme 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:

bash
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 list

Output yang Dihasilkan:

text
[main 395738c] Selesaikan draf footer
 1 file changed, 1 insertion(+)

Output yang Dihasilkan:

text
Dropped stash@{1} (bbcad7cb2042dde41cccc3a33fe49ee7acfa4ace)

Output yang Dihasilkan:

text
stash@{0}: On main: draf kontak

Bentuk 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:

bash
git stash pop
git status --short

Output yang Dihasilkan:

text
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:

text
 M tentang.md

Satu 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 .

PerintahEfek pada tumpukanKecocokan penggunaan
git stash show [-p] [stash@{N}]tidak berubahmemeriksa isi sebelum diambil
git stash apply [stash@{N}]tidak berubahmencoba simpanan di beberapa branch
git stash pop [stash@{N}]diterapkan lalu dijatuhkan bila bersihsimpanan sekali pakai
git stash drop [stash@{N}]dijatuhkan tanpa diterapkanmembuang 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 .