Bayangkan sedang menyusun footer baru untuk beranda toko daring: satu suntingan setengah jadi, satu berkas lain sudah telanjur di-stage. Tepat saat itu laporan bug mendesak masuk dan perbaikannya menunggu di branch hotfix untuk diverifikasi. Membuat commit setengah jadi akan mengotori riwayat; membuang suntingan berarti mengulang kerja dari nol. git stash membuka pintu ketiga: seluruh perubahan dimasukkan ke tumpukan simpanan sementara, working tree dibersihkan seketika, dan kita bebas berpindah branch. Chapter ini membedah mekanisme tersebut dari keluaran aslinya — menyimpan dengan dan tanpa pesan, perlakuan khusus berkas untracked, hingga pembuktian bahwa setiap stash sebenarnya adalah commit.

Skenario: Pekerjaan Setengah Jadi dan Branch yang Tak Bisa Dituju #

Repository latihan-stash menyiapkan cermin skenario di atas. Branch hotfix sengaja dibuat lebih dulu berisi perbaikan judul beranda, lalu kita kembali ke main dan mengerjakan footer:

bash
mkdir latihan-stash && cd latihan-stash
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"
git switch -c hotfix
printf 'beranda\njudul diperbaiki\n' > situs.md
git add situs.md
git commit -m "Perbaiki judul beranda"
git switch main
printf '# Tentang\n' > tentang.md
git add tentang.md
git commit -m "Tambah halaman tentang"

Pekerjaan setengah jadi kemudian dimulai — suntingan situs.md yang belum di-stage plus kontak.md yang sudah di-stage:

bash
printf 'beranda\nfooter v1\n' > situs.md
printf 'kontak v1\n' > kontak.md
git add kontak.md
git status --short
git switch hotfix

Output yang Dihasilkan:

text
A  kontak.md
 M situs.md

Output yang Dihasilkan:

text
error: Your local changes to the following files would be overwritten by checkout:
	situs.md
Please commit your changes or stash them before you switch branches.
Aborting

Status memperlihatkan dua jenis perubahan sekaligus: A kontak.md (berkas baru di staging) dan M situs.md (suntingan working tree). Perpindahan ke hotfix ditolak keras karena versi situs.md di working tree akan tertimpa versi branch yang berbeda — persis penolakan yang kita temui di Menangani Detached HEAD . Perhatikan saran Git di baris Please commit your changes or stash them: penyimpanan sementara memang jalur resminya.

git stash: Menyimpan Tanpa Commit #

Satu perintah polos menyelesaikan kebuntuan:

bash
git stash
git status
git switch hotfix
git log --oneline -1
git switch main

Output yang Dihasilkan:

text
Saved working directory and index state WIP on main: 02ffe85 Tambah halaman tentang

Output yang Dihasilkan:

text
On branch main
nothing to commit, working tree clean

Output yang Dihasilkan:

text
Switched to branch 'hotfix'

Output yang Dihasilkan:

text
c6e58a4 Perbaiki judul beranda

Output yang Dihasilkan:

text
Switched to branch 'main'

Baris Saved working directory and index state WIP on main: 02ffe85 Tambah halaman tentang padat informasi: working directory and index state berarti suntingan working tree dan isi staging (kontak.md) ikut tersimpan; label WIP on main mencatat branch saat penyimpanan; hash pendek 02ffe85 beserta subjek Tambah halaman tentang adalah commit HEAD ketika stash dibuat — hash di mesin pembaca akan berbeda. Status berubah bersih total, perpindahan ke hotfix mulus, verifikasi perbaikan selesai, dan kita sudah kembali di main. Simpanannya sendiri menunggu di sebuah tumpukan:

bash
git stash list

Output yang Dihasilkan:

text
stash@{0}: WIP on main: 02ffe85 Tambah halaman tentang

Formatnya stash@{<nomor>}: tumpukan LIFO dengan simpanan terbaru selalu di stash@{0}. Labelnya sama persis dengan baris Saved ... tadi.

Berkas Untracked Tidak Ikut Tanpa -u #

Simpanan tadi hanya membawa perubahan tracked. Berkas yang belum pernah dilacak punya nasib berbeda — kita buktikan dengan satu berkas liar:

bash
printf 'catatan liar\n' > catatan-liar.md
git stash
git status --short

Output yang Dihasilkan:

text
No local changes to save

Output yang Dihasilkan:

text
?? catatan-liar.md

git stash polos menolak bekerja: No local changes to save karena menurut Git tidak ada perubahan tracked, dan catatan-liar.md tetap berdiri di working tree sebagai berkas untracked (??). Untuk ikut menyimpannya, flag -u (atau --include-untracked) dipasang — sekaligus kita pakai bentuk panjang push dengan pesan:

bash
git stash push -u -m "bawa catatan liar"
git status
git stash list

Output yang Dihasilkan:

text
Saved working directory and index state On main: bawa catatan liar

Output yang Dihasilkan:

text
On branch main
nothing to commit, working tree clean

Output yang Dihasilkan:

text
stash@{0}: On main: bawa catatan liar
stash@{1}: WIP on main: 02ffe85 Tambah halaman tentang

Tiga hal berubah sekaligus: label WIP on main diganti pesan kita sendiri menjadi On main: bawa catatan liar, berkas untracked ikut tersimpan sehingga status kini sungguh-sungguh bersih, dan tumpukan memuat dua entri — simpanan baru menempati stash@{0}, yang lama turun ke stash@{1}. Referensi sintaks lengkap ada di git-stash .

Jenis perubahangit stash polosgit stash -u
Berkas tracked yang dimodifikasiikut tersimpanikut tersimpan
Berkas baru yang sudah di-stageikut tersimpanikut tersimpan
Berkas untrackedtertinggal di working treeikut tersimpan
Berkas yang diabaikan .gitignoretertinggaltertinggal (perlu -a)

Stash Adalah Commit Khusus di refs/stash #

Stash bukan berkas sementara di luar repository — ia commit sungguhan yang ditunjuk ref khusus refs/stash. Pembuktiannya cukup cat-file -p pada kedua entri tumpukan:

bash
git cat-file -p "stash@{1}"
git cat-file -p "stash@{0}"

Output yang Dihasilkan:

text
tree 5c14543972f453b83144ec7282341fb92199391a
parent 02ffe85f2df5df23abcf55e9e4d4634dfb89c1c8
parent 825a6fe3b1727c700ef8aed350a3ab1ee2256fce
author Budi Santoso <[email protected]> 1792721700 +0700
committer Budi Santoso <[email protected]> 1792721700 +0700

WIP on main: 02ffe85 Tambah halaman tentang

Output yang Dihasilkan:

text
tree 4aae92b52bdf6137d43dff0a6ea755b4fd2979e3
parent 02ffe85f2df5df23abcf55e9e4d4634dfb89c1c8
parent f1bb7063a83851c4a4ff19611ca2c7b3190d9bea
parent d6882a2d039d9339b671d2e4a981b68fbeffff7c
author Budi Santoso <[email protected]> 1792722300 +0700
committer Budi Santoso <[email protected]> 1792722300 +0700

On main: bawa catatan liar

Struktur commit bertelepon pada objek blob, tree, commit, dan tag terbaca telanjang di situ. Simpanan polos (stash@{1}) adalah merge commit dengan dua parent: parent pertama 02ffe85f adalah commit HEAD saat stash dibuat (basis perbandingan), parent kedua 825a6fe snapshot isi index. Simpanan -u (stash@{0}) menambah parent ketiga d6882a2 yang merangkai berkas untracked. Angka 1792721700 adalah stempel waktu Unix hasil tanggal deterministik sandbox — di mesin pembaca nilainya menyesuaikan waktu penyimpanan.

Dua simpanan kini tertata rapi dan working tree bersih. Pertanyaan berikutnya sudah menggantung: bagaimana mengambil isi tumpukan itu kembali — dibiarkan di tumpukan atau dibuang sekaligus? Jawabannya adalah duel apply lawan pop di Stash Apply, Pop, dan Drop .