Revert membatalkan perubahan dengan menambah commit pembalik. git reset bekerja dari arah yang berlawanan: ia menggeser penunjuk branch — HEAD dan ref branch — ke commit lain di riwayat, seolah commit-commit setelah titik itu tidak pernah dibuat. Perintah ini punya tiga mode yang sering bikin bingung: --soft, --mixed (default), dan --hard. Ketiganya sama-sama memindahkan pointer, tetapi berbeda perlakuan terhadap staging area dan working tree — dan itulah penentu apakah perubahan kita selamat di staging, menggantung di working tree, atau lenyap bersih. Chapter ini membuktikan tiap mode dengan status dan isi berkas nyata, lalu menutupnya dengan pola sinkronisasi ke remote.

Repositori Latihan #

Satu repositori dipakai bergantian untuk keempat alur — setiap alur dimulai dari keadaan identik, jadi bangun ulang dengan blok ini di antara alur:

bash
mkdir latihan-reset && cd latihan-reset
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 'kontak\n' > kontak.md
git add kontak.md
git commit -m "Tambah halaman kontak"
printf 'beranda\njudul\n' > situs.md
printf 'galeri\n' > galeri.md
git add situs.md galeri.md
git commit -m "Tambah galeri dan ubah judul"

Commit terakhir (HEAD) sengaja membawa dua jenis perubahan sekaligus: situs.md yang dimodifikasi dan galeri.md yang baru — supaya nasib keduanya terlihat jelas setiap mode dijalankan.

Mode –soft: Commit Hilang, Perubahan Masih Staged #

Mode paling lembut: git reset --soft HEAD~1 hanya memindahkan pointer satu langkah ke belakang. Apa yang tadinya commit HEAD kembali menjadi perubahan yang sudah di-stage:

bash
git reset --soft HEAD~1

Output yang Dihasilkan:

text

Tanpa keluaran — mode soft pendiam. Bukti nasibnya ada di git status:

bash
git status

Output yang Dihasilkan:

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

Kedua perubahan commit tadi — new file: galeri.md dan modified: situs.md — kini duduk rapi di Changes to be committed, siap di-commit ulang kapan saja:

bash
cat galeri.md

Output yang Dihasilkan:

text
galeri
bash
git log --oneline

Output yang Dihasilkan:

text
ca56fcf Tambah halaman kontak
6b60d87 Buat halaman beranda

Berkasnya utuh, tapi log hanya menyisakan dua commit. Mode soft adalah alat “urungkan commit, simpan kerjanya” — khas dipakai untuk merapikan commit yang terlanjur dibuat terpisah.

Mode –mixed: Staged Lepas, Perubahan Tetap di Worktree #

Mode default (tanpa --mode, git reset berarti --mixed) menambah satu langkah: setelah pointer bergeser, staging area dikosongkan ke keadaan commit tujuan. Perubahan tidak hilang — ia turun ke working tree sebagai unstaged:

bash
git reset HEAD~1

Output yang Dihasilkan:

text
Unstaged changes after reset:
M	situs.md

Keluarannya mencetak daftar berkas yang statusnya berubah dari staged: M situs.md (M = modified, dipisah TAB dari nama berkas). Status lengkapnya:

bash
git status

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

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

no changes added to commit (use "git add" and/or "git commit -a")

situs.md jatuh ke Changes not staged for commit, galeri.md menjadi Untracked — keduanya masih ada isinya:

bash
cat galeri.md

Output yang Dihasilkan:

text
galeri

Mode mixed adalah “urungkan commit DAN urungkan staging” — kerja tetap selamat, tapi harus di-git add ulang untuk di-commit. Itulah mengapa mode ini default: paling aman untuk sekadar melepas staging yang salah susun.

Mode –hard: Semua Lenyap #

Mode ketiga membersihkan semuanya: pointer bergeser, staging dikosongkan, dan working tree dipaksa menyesuaikan isi commit tujuan:

bash
git reset --hard HEAD~1

Output yang Dihasilkan:

text
HEAD is now at ca56fcf Tambah halaman kontak

Satu baris khas hard: HEAD is now at ca56fcf Tambah halaman kontak — Git mengumumkan posisi baru HEAD sambil menghapus semua jejak. Bukti lenyapnya:

bash
git status

Output yang Dihasilkan:

text
On branch main
nothing to commit, working tree clean
bash
cat galeri.md

Output yang Dihasilkan:

text
cat: galeri.md: No such file or directory

galeri.md tidak lagi ada — cat gagal karena berkasnya benar-benar terhapus dari disk; situs.md kembali ke isi lama tanpa baris judul. Working tree bersih total, seolah commit ketiga tak pernah dibuat.

Reset ke Hash Spesifik #

HEAD~1 hanya salah satu cara menyebut target. Target sebenarnya adalah commit mana pun — biasanya hash yang dibaca dari log. Bangun ulang repositori, lalu:

bash
git log --oneline

Output yang Dihasilkan:

text
112ec27 Tambah galeri dan ubah judul
ca56fcf Tambah halaman kontak
6b60d87 Buat halaman beranda

Kita mundur dua commit sekaligus, langsung ke 6b60d87 Buat halaman beranda (hash di mesin Anda berbeda — pakai hash Anda):

bash
git reset --hard 6b60d87

Output yang Dihasilkan:

text
HEAD is now at 6b60d87 Buat halaman beranda
bash
git log --oneline

Output yang Dihasilkan:

text
6b60d87 Buat halaman beranda
bash
git ls-files

Output yang Dihasilkan:

text
situs.md

Dua commit terakhir hilang dari riwayat; hanya situs.md tersisa terlacak. Reset dengan hash adalah cara standar “kembali ke titik aman” ketika eksperimen bercabang terlalu jauh — commit manapun di log bisa dijadikan rumah.

Reset ke origin/main: Menyamakan Remote #

Satu pola reset yang paling sering dipakai saat kolaborasi: menyamakan branch lokal dengan remote. Latihan keempat memakai bare repo toko-b.git sebagai origin (lihat polanya dari chapter Remote ; ringkasnya: git init --bare ../toko-b.git, git remote add origin ../toko-b.git, git push -u origin main) — lalu main lokal dan main di remote masing-masing mendapat satu commit berbeda. Tarik pembaruannya lalu periksa statusnya:

bash
git fetch origin
git status

Output yang Dihasilkan (git fetch origin):

text
From ../toko-b
   36c8ad6..8717b26  main       -> origin/main

Output yang Dihasilkan:

text
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" if you want to integrate the remote branch with yours)

nothing to commit, working tree clean

Fetch memindahkan pembaruan remote ke origin/main (36c8ad6..8717b26 main -> origin/main), dan status melaporkan persis masalahnya: Your branch and 'origin/main' have diverged, and have 1 and 1 different commits each. Alih-alih menggabungkan, kita menyerahkan diri ke remote — branch lokal disamakan persis ke origin/main:

bash
git reset --hard origin/main

Output yang Dihasilkan:

text
HEAD is now at 8717b26 Ubah judul 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
8717b26 Ubah judul beranda
36c8ad6 Buat halaman beranda

Commit lokal Tambah halaman kontak tertinggal, digantikan Ubah judul beranda milik rekan — branch kini “up to date with ‘origin/main’”. Pola git fetch + git reset --hard origin/main ini standar untuk membuang seluruh eksperimen lokal demi mulai bersih dari keadaan remote.

Reset Bukan Penghapus Permanen #

Kedengarannya seperti --hard menghancurkan commit selamanya — tidak. Commit yang tertinggal masih tersimpan di object database dan tercatat di reflog; ia hanya tak lagi dirujuk branch mana pun. Buktinya terlihat di latihan remote barusan:

bash
git reflog

Output yang Dihasilkan:

text
8717b26 HEAD@{0}: reset: moving to origin/main
2356444 HEAD@{1}: commit: Tambah halaman kontak
36c8ad6 HEAD@{2}: commit (initial): Buat halaman beranda

Entri HEAD@{0}: reset: moving to origin/main mencatat persis gerakan reset barusan, dan HEAD@{1}: commit: Tambah halaman kontak masih memuat commit yang “hilang” — pulihkan kapan saja lewat git reset --hard HEAD@{1} atau git switch -c selamat HEAD@{1}. Bagaimana caranya, dibahas tuntas di git reflog .

Tiga mode reset yang barusan dibuktikan statusnya satu per satu memang terasa teknis. Chapter berikutnya membedahnya lebih dalam: tabel dimensi per mode, diagram keadaan, dan skenario nyata kapan soft dipilih, kapan mixed, kapan hard — lanjut ke Reset Soft, Mixed, dan Hard .