git reset

Membatalkan commit lokal dengan git reset dan perbedaan mode soft, mixed, dan hard pada tiga pohon.

Daftar isi

Perintah git reset memindahkan penunjuk branch ke commit mana pun, dan setiap mode pemanggilannya menentukan seberapa jauh dua keadaan lain, yaitu staging area dan working directory, ikut diselaraskan. Topik ini membahas tiga pohon Git yang menjadi kerangka pemikirannya, perbedaan mode soft, mixed, dan hard, serta batas aman penggunaannya. Reset adalah alat yang paling kuat di antara perintah pembatalan, sehingga pemahaman modelnya lebih penting daripada menghafal opsinya.

Tiga pohon yang diselaraskan#

Git mengelola tiga keadaan yang berbeda, dan istilah pohon (tree) dipakai Git untuk menyebut ketiganya. Pohon pertama adalah HEAD, yaitu commit yang ditunjuk branch aktif dan mewakili riwayat. Pohon kedua adalah staging area, yaitu draf commit berikutnya. Pohon ketiga adalah working directory, yaitu keadaan berkas di disk.

Perintah git reset commit selalu melakukan langkah pertama yang sama, yaitu memindahkan penunjuk branch aktif menuju commit yang disebut. Setelah itu, mode yang dipilih menentukan kelanjutannya: --soft berhenti di situ, --mixed yang menjadi bawaan menyelaraskan staging area, dan --hard menyelaraskan working directory juga. Pembacaan tiga baris ini menyelesaikan hampir seluruh kebingungan tentang reset, karena setiap mode hanyalah kelanjutan dari yang sebelumnya.

Tiga pohon Git dan jangkauan tiap mode resetHEAD (commit)staging (index)working directory--softhanya HEAD--mixedHEAD dan staging--hardketiganya diselaraskan
Jangkauan tiap mode reset terhadap tiga pohon Git

Mode soft: commit kembali menjadi draf#

Mode --soft hanya memindahkan penunjuk branch, sehingga selisih antara commit lama dan commit baru berpindah ke staging area dalam keadaan siap commit. Keadaan ini tepat untuk menyusun ulang commit yang terlalu dini tanpa kehilangan penyusunannya.

bash
# tanggal commit ditetapkan agar keluaran contoh dapat direproduksi secara persis
export GIT_AUTHOR_DATE="2026-11-01T09:00:00+07:00"
export GIT_COMMITTER_DATE="2026-11-01T09:00:00+07:00"
bash
rm -rf /tmp/lab-reset-soft
mkdir /tmp/lab-reset-soft
cd /tmp/lab-reset-soft
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Satu.\n" > berkas.txt
git add berkas.txt
git commit -m "Satu"
printf "Satu.\nDua.\n" > berkas.txt
git commit -am "Dua"
printf "Satu.\nDua.\nTiga.\n" > berkas.txt
git commit -am "Tiga"
git reset --soft HEAD~2
git status -s
git log --oneline
text Keluaran
Initialized empty Git repository in /tmp/lab-reset-soft/.git/
[main (root-commit) 04068da] Satu
 1 file changed, 1 insertion(+)
 create mode 100644 berkas.txt
[main 83d9ee7] Dua
 1 file changed, 1 insertion(+)
[main 968dadf] Tiga
 1 file changed, 1 insertion(+)
M  berkas.txt
04068da Satu

Branch main kini menunjuk commit pertama, sedangkan isi gabungan dua commit terakhir menunggu di staging area dengan status A . Tidak ada pekerjaan yang hilang sama sekali, hanya batas commit yang digeser mundur, dan commit pengganti dapat disusun dengan pembagian yang lebih baik.

Mode mixed: draf kembali terurai#

Mode --mixed, yang juga menjadi bawaan apabila mode tidak disebut, menyelaraskan staging area terhadap commit tujuan, sehingga isi commit yang dilewati berpindah ke working directory dalam keadaan belum di-stage.

bash
rm -rf /tmp/lab-reset-mixed
mkdir /tmp/lab-reset-mixed
cd /tmp/lab-reset-mixed
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Satu.\n" > berkas.txt
git add berkas.txt
git commit -m "Satu"
printf "Satu.\nDua.\nTiga.\n" > berkas.txt
git commit -am "Dua dan tiga"
git reset HEAD~1
git status -s
text Keluaran
Initialized empty Git repository in /tmp/lab-reset-mixed/.git/
[main (root-commit) 04068da] Satu
 1 file changed, 1 insertion(+)
 create mode 100644 berkas.txt
[main 4cbbc25] Dua dan tiga
 1 file changed, 2 insertions(+)
Unstaged changes after reset:
M	berkas.txt
 M berkas.txt

Perbedaannya dengan mode soft terletak pada kolom statusnya: A berubah menjadi M, yang berarti isi commit terakhir kini berupa perubahan biasa di working directory. Mode inilah yang dipakai untuk membongkar commit agar dapat dipecah, karena staging area kosong memberikan kebebasan penuh untuk men-stage ulang per bagian.

Mode hard: keselarasan penuh#

Mode --hard menyelaraskan working directory juga, sehingga seluruh selisih terhadap commit tujuan hilang dari disk. Mode ini berguna untuk membuang keadaan yang memang tidak diinginkan, dan sama berbahayanya terhadap pekerjaan yang belum tercatat.

bash
rm -rf /tmp/lab-reset-hard
mkdir /tmp/lab-reset-hard
cd /tmp/lab-reset-hard
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Satu.\n" > berkas.txt
git add berkas.txt
git commit -m "Satu"
printf "Satu.\nDua.\nTiga.\n" > berkas.txt
git commit -am "Dua dan tiga"
printf "Catatan mentah yang belum di-commit.\n" > draf.txt
git reset --hard HEAD~1
git status -s
cat berkas.txt
ls
text Keluaran
Initialized empty Git repository in /tmp/lab-reset-hard/.git/
[main (root-commit) 04068da] Satu
 1 file changed, 1 insertion(+)
 create mode 100644 berkas.txt
[main 4cbbc25] Dua dan tiga
 1 file changed, 2 insertions(+)
HEAD is now at 04068da Satu
?? draf.txt
Satu.
berkas.txt
draf.txt

Isi berkas.txt kembali ke satu baris, dan berkas draf.txt yang tidak pernah di-commit hilang sama sekali. Untuk perubahan yang sudah pernah di-commit, pemulihannya masih mungkin melalui reflog, sedangkan perubahan yang tidak pernah dicatat tidak meninggalkan jejak apa pun.

Ringkasan#

  • Reset selalu memindahkan penunjuk branch ke commit tujuan, dan mode menentukan seberapa jauh staging area dan working directory ikut diselaraskan.
  • --soft menyisakan isi commit di staging area, --mixed menguraikannya ke working directory, dan --hard membuang selisihnya dari disk.
  • Perubahan yang sudah pernah di-commit masih dapat dipulihkan melalui reflog, sedangkan perubahan yang tidak pernah dicatat hilang tanpa jejak.
  • Reset adalah perintah penataan ulang riwayat lokal, dan commit yang sudah dibagikan dibatalkan dengan revert.

Referensi#