Chapter Reset menutup dengan janji: tabel dimensi tiap mode dan skenario nyata kapan masing-masing dipilih. Hafalan “soft aman, hard berbahaya” memang benar, tetapi hafalan itu tidak cukup saat keputusan harus diambil cepat — melebur dua commit terakhir, melepas staging yang tercampur, atau membuang eksperimen yang gagal total menuntut tiga mode yang berbeda. Chapter ini membedah ketiganya dari dimensi yang mereka pisahkan, lalu membuktikan tiap mode pada skenario khasnya: soft melebur commit WIP, mixed menata ulang staging, hard menyapu eksperimen — lengkap dengan nasib berkas untracked yang ternyata selamat dari --hard.

Tiga Dimensi yang Dipisahkan Mode #

Di balik layar, git reset <mode> <target> menjalankan rangkaian tiga langkah. Langkah pertama menggeser HEAD beserta penunjuk branch ke commit target. Langkah kedua menyalin isi commit target ke staging area. Langkah ketiga memaksa working tree menyesuaikan isi commit target. Mode adalah rem yang menentukan rangkaian itu berhenti di langkah mana — dan di sanalah seluruh perbedaan antara mode berada. Rincian resminya terdokumentasi di git-reset .

ModeHEAD dan branch bergerakIndex direset ke targetWorking tree disentuh
--softyatidaktidak
--mixed (default)yayatidak
--hardyayaya

Konsekuensi tiap baris terbaca langsung di git status: karena soft berhenti setelah langkah pertama, perubahan dari commit yang dilepas kembali tampil sebagai staged. Mixed berhenti setelah langkah kedua, sehingga staging kosong dan perubahan jatuh ke working tree sebagai unstaged atau untracked. Hard berjalan sampai ujung, sehingga semua perubahan terlacak lenyap. Satu kolom tambahan yang tidak masuk tabel: berkas untracked tidak disentuh mode mana pun — buktinya menyusul di skenario hard.

Diagram itu juga menjelaskan mengapa --mixed menjadi default: berhenti di tengah adalah kompromi paling aman — pointer sudah bergeser, tapi kerja kita masih tergelar utuh di working tree.

Skenario Soft: Melebur Dua Commit WIP #

Skenario paling khas untuk soft: dua commit work in progress yang seharusnya menjadi satu commit rapi. Repositori latihannya berisi laporan dengan dua langkah penulisan:

bash
mkdir latihan-mode-soft && cd latihan-mode-soft
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Laporan\n' > laporan.md
git add laporan.md
git commit -m "Mulai proyek laporan"
printf '# Laporan\npendahuluan\n' > laporan.md
git add laporan.md
git commit -m "wip: tulis pendahuluan"
printf '# Laporan\npendahuluan\npembahasan\n' > laporan.md
git add laporan.md
git commit -m "wip: tulis pembahasan"
git log --oneline

Output yang Dihasilkan:

text
76416df wip: tulis pembahasan
ad6c183 wip: tulis pendahuluan
4051748 Mulai proyek laporan

Kedua commit wip: ingin dilebur menjadi satu Tulis pendahuluan dan pembahasan. Mundur dua commit dengan soft:

bash
git reset --soft HEAD~2

Output yang Dihasilkan:

text

Tanpa keluaran — mode soft bekerja senyap. Buktinya ada di status:

bash
git status

Output yang Dihasilkan:

text
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   laporan.md

modified: laporan.md duduk di Changes to be committed — perubahan dari dua commit yang barusan dilepas kini terkumpul utuh sebagai satu paket staged. Isi paketnya bisa diintip:

bash
git diff --cached

Output yang Dihasilkan:

text
diff --git a/laporan.md b/laporan.md
index 15d43ac..6de4b62 100644
--- a/laporan.md
+++ b/laporan.md
@@ -1 +1,3 @@
 # Laporan
+pendahuluan
+pembahasan

Diff itu adalah gabungan kedua commit: dua baris tambahan, pendahuluan dan pembahasan. Commit ulang dengan pesan yang layak:

bash
git commit -m "Tulis pendahuluan dan pembahasan"

Output yang Dihasilkan:

text
[main 58a5ed0] Tulis pendahuluan dan pembahasan
 1 file changed, 2 insertions(+)
bash
git log --oneline

Output yang Dihasilkan:

text
58a5ed0 Tulis pendahuluan dan pembahasan
4051748 Mulai proyek laporan
bash
cat laporan.md

Output yang Dihasilkan:

text
# Laporan
pendahuluan
pembahasan

Tiga commit menjadi dua; isi laporan.md utuh byte demi byte. Soft adalah alat “bongkar kemasan, simpan isinya” — kerja tidak pernah keluar dari staging.

Skenario Mixed: Menyusun Ulang Staging #

Mixed tidak selalu soal commit. Skenario khasnya: staging yang terlanjur tercampur — dua berkas masuk bersamaan padahal kebijakan tim satu commit per halaman:

bash
mkdir latihan-mode-mixed && cd latihan-mode-mixed
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 kerangka situs"
printf '[email protected]\n' > kontak.md
printf 'galeri foto\n' > galeri.md
git add kontak.md galeri.md
git status

Output yang Dihasilkan:

text
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   galeri.md
	new file:   kontak.md

Tanpa argumen target, git reset berarti --mixed ke HEAD — pointer tidak berpindah karena targetnya commit tempat kita berdiri; yang dilepas hanya staging:

bash
git reset

Perintah itu sunyi tanpa keluaran. Statusnya berubah total:

bash
git status

Output yang Dihasilkan:

text
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	galeri.md
	kontak.md

nothing added to commit but untracked files present (use "git add" to track)

Staging kosong. Kedua berkas jatuh ke Untracked files — bukan modified, karena keduanya memang belum pernah di-commit. Dari titik ini staging disusun ulang selektif, satu per satu:

bash
git add kontak.md
git commit -m "Tambah halaman kontak"

Output yang Dihasilkan:

text
[main dd75cc0] Tambah halaman kontak
 1 file changed, 1 insertion(+)
 create mode 100644 kontak.md
bash
git status

Output yang Dihasilkan:

text
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	galeri.md

nothing added to commit but untracked files present (use "git add" to track)

Satu berkas sudah menjadi commit; galeri.md masih menunggu di untracked. Selesaikan yang kedua:

bash
git add galeri.md
git commit -m "Tambah halaman galeri"

Output yang Dihasilkan:

text
[main b62c73e] Tambah halaman galeri
 1 file changed, 1 insertion(+)
 create mode 100644 galeri.md
bash
git log --oneline

Output yang Dihasilkan:

text
b62c73e Tambah halaman galeri
dd75cc0 Tambah halaman kontak
4d7be7d Buat kerangka situs

Riwayat berakhir rapi: satu commit per halaman. Bila yang dibutuhkan hanya melepas staging satu berkas tertentu, git restore --staged <berkas> lebih tepat karena tidak mengosongkan seluruh index — pola itu dibedah di Membatalkan Staging .

Skenario Hard: Membuang Eksperimen #

Hard untuk keadaan yang tidak layak diselamatkan: eksperimen gagal total dan seluruh jejaknya ingin dihapus. Repositori latihannya menyiapkan eksperimen ter-commit plus satu berkas coretan yang belum pernah di-track:

bash
mkdir latihan-mode-hard && cd latihan-mode-hard
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 kerangka situs"
printf 'tombol simpan\n' > tombol.md
git add tombol.md
git commit -m "Eksperimen tombol"
printf 'catatan sementara\n' > catatan-sampah.md
git status

Output yang Dihasilkan:

text
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	catatan-sampah.md

nothing added to commit but untracked files present (use "git add" to track)

Buang commit eksperimen sekaligus seluruh isinya:

bash
git reset --hard HEAD~1

Output yang Dihasilkan:

text
HEAD is now at c671f06 Buat kerangka situs
bash
git status

Output yang Dihasilkan:

text
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	catatan-sampah.md

nothing added to commit but untracked files present (use "git add" to track)

Baris untracked masih ada — catatan-sampah.md selamat. Periksakan isinya:

bash
cat catatan-sampah.md

Output yang Dihasilkan:

text
catatan sementara
bash
git ls-files

Output yang Dihasilkan:

text
situs.md

tombol.md lenyap dari index dan disk, sementara catatan-sampah.md utuh isinya. Hard menyapu bersih semua perubahan terlacak — commit, staging, unstaged — tetapi berkas untracked tidak pernah tersentuh: berkas itu tidak ada di index, tidak dirujuk commit mana pun, sehingga tidak ada apa pun yang bisa “direset”. Git tidak menganggap berkas itu miliknya.

Kembali ke Remote: git reset –hard origin/main #

Skenario penutup yang memakai hard justru paling sering dipakai sehari-hari: branch lokal berisi eksperimen yang tidak mau dilanjutkan, dan titik aman adalah keadaan remote. Latihan memakai bare repo toko-c.git sebagai origin:

bash
mkdir latihan-mode-remote && cd latihan-mode-remote
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 init --bare ../toko-c.git
git remote add origin ../toko-c.git
git push -u origin main
printf 'tombol simpan\n' > tombol.md
git add tombol.md
git commit -m "Coba tombol eksperimen"
git log --oneline

Output yang Dihasilkan:

text
cbd6955 Coba tombol eksperimen
81f1e33 Buat halaman beranda

HEAD unggul satu commit dari origin/main. Serahkan diri sepenuhnya ke remote:

bash
git reset --hard origin/main

Output yang Dihasilkan:

text
HEAD is now at 81f1e33 Buat halaman beranda
bash
git status

Output yang Dihasilkan:

text
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
bash
git log --oneline

Output yang Dihasilkan:

text
81f1e33 Buat halaman beranda

Eksperimen tombol lenyap; branch lokal kini persis sama dengan keadaan remote — up to date with 'origin/main'. Dalam kerja nyata origin/main di sini adalah refs remote-tracking, jadi bila rekan ikut mendorong pembaruan, awali dengan git fetch origin agar acuannya segar; varian lengkapnya — fetch, branch bercerai, lalu reset — sudah dibuktikan di chapter Reset .

Tiga mode kini terukur dimensinya: soft melebur kemasan, mixed menata staging, hard menyapu bersih — dan semuanya aman dimainkan selama riwayat masih lokal. Pertanyaan penutupnya bukan lagi mode mana, melainkan alat mana: membatalkan lewat revert yang menambah jejak, atau reset yang menulis ulang riwayat? Alur keputusannya menanti di Revert vs Reset .