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:
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:
printf 'beranda\nfooter v1\n' > situs.md
printf 'kontak v1\n' > kontak.md
git add kontak.md
git status --short
git switch hotfixOutput yang Dihasilkan:
A kontak.md
M situs.mdOutput yang Dihasilkan:
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.
AbortingStatus 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:
git stash
git status
git switch hotfix
git log --oneline -1
git switch mainOutput yang Dihasilkan:
Saved working directory and index state WIP on main: 02ffe85 Tambah halaman tentangOutput yang Dihasilkan:
On branch main
nothing to commit, working tree cleanOutput yang Dihasilkan:
Switched to branch 'hotfix'Output yang Dihasilkan:
c6e58a4 Perbaiki judul berandaOutput yang Dihasilkan:
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:
git stash listOutput yang Dihasilkan:
stash@{0}: WIP on main: 02ffe85 Tambah halaman tentangFormatnya 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:
printf 'catatan liar\n' > catatan-liar.md
git stash
git status --shortOutput yang Dihasilkan:
No local changes to saveOutput yang Dihasilkan:
?? catatan-liar.mdgit 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:
git stash push -u -m "bawa catatan liar"
git status
git stash listOutput yang Dihasilkan:
Saved working directory and index state On main: bawa catatan liarOutput yang Dihasilkan:
On branch main
nothing to commit, working tree cleanOutput yang Dihasilkan:
stash@{0}: On main: bawa catatan liar
stash@{1}: WIP on main: 02ffe85 Tambah halaman tentangTiga 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 perubahan | git stash polos | git stash -u |
|---|---|---|
| Berkas tracked yang dimodifikasi | ikut tersimpan | ikut tersimpan |
| Berkas baru yang sudah di-stage | ikut tersimpan | ikut tersimpan |
| Berkas untracked | tertinggal di working tree | ikut tersimpan |
Berkas yang diabaikan .gitignore | tertinggal | tertinggal (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:
git cat-file -p "stash@{1}"
git cat-file -p "stash@{0}"Output yang Dihasilkan:
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 tentangOutput yang Dihasilkan:
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 liarStruktur 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
.