Rebase interaktif menyediakan ruang kerja untuk menata commit sebelum dibagikan: urutan diubah, pesan diperbaiki, commit yang kecil digabung, dan commit yang salah dibuang. Daftar pekerjaannya disebut daftar todo, dan seluruh penyuntingan dilakukan pada berkas teks itu. Topik ini membaca dulu daftar todonya, lalu mempraktikkan empat operasinya, dan seluruh latihannya dijalankan tanpa editor penuh agar setiap keluaran dapat direproduksi.
Membaca daftar todo#
Menjalankan git rebase -i dengan editor cat membuat Git menampilkan daftar todo sebagaimana adanya, lalu melanjutkan dengan isi yang tidak berubah.
# 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"rm -rf /tmp/lab-rebase-i
mkdir /tmp/lab-rebase-i
cd /tmp/lab-rebase-i
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Fitur laporan.\n" > laporan.md
git add laporan.md
git commit -m "Fitur laporan"
printf "Fitur laporan.\nTabel.\n" > laporan.md
git commit -am "Tambah tabel"
printf "Fitur laporan.\nTabel.\ntypo\n" > laporan.md
git commit -am "typo"
GIT_SEQUENCE_EDITOR="cat" git rebase -i main~2Initialized empty Git repository in /tmp/lab-rebase-i/.git/
[main (root-commit) fc7d7b5] Fitur laporan
1 file changed, 1 insertion(+)
create mode 100644 laporan.md
[main 04ee8b8] Tambah tabel
1 file changed, 1 insertion(+)
[main 4b0a79e] typo
1 file changed, 1 insertion(+)
pick 04ee8b8 Tambah tabel
pick 4b0a79e typo
# Rebase fc7d7b5..4b0a79e onto fc7d7b5 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# create a merge commit using the original merge commit's
# message (or the oneline, if no original merge commit was
# specified); use -c <commit> to reword the commit message
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
# to this position in the new commits. The <ref> is
# updated at the end of the rebase
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
Successfully rebased and updated refs/heads/main.Daftar todo berisi satu baris per commit yang akan diputar ulang, diikuti catatan bantuan yang selalu diawali pagar dan tidak pernah ikut tersimpan. Baris paling atas diproses paling dulu, dan menyunting baris itulah seluruh cara kerja rebase interaktif: kata perintahnya diganti, barisnya dipindah, atau barisnya dihapus.
Menggabungkan commit dengan squash#
Commit typo pada contoh seharusnya menyatu dengan commit tabelnya. Mengganti kata pick pada baris kedua menjadi squash menyuruh Git melebur commit itu ke commit di atasnya, dan pesannya pun dilebur.
GIT_SEQUENCE_EDITOR="sed -i '2s/^pick/squash/'" GIT_EDITOR="cat" git rebase -i main~2
git log --onelineRebasing (2/2)
# This is a combination of 2 commits.
# This is the 1st commit message:
Tambah tabel
# This is the commit message #2:
typo
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Nov 1 09:00:00 2026 +0700
#
# interactive rebase in progress; onto fc7d7b5
# Last commands done (2 commands done):
# pick 04ee8b8 Tambah tabel
# squash 4b0a79e typo
# No commands remaining.
# You are currently rebasing branch 'main' on 'fc7d7b5'.
#
# Changes to be committed:
# modified: laporan.md
#
[detached HEAD 45562cc] Tambah tabel
Date: Sun Nov 1 09:00:00 2026 +0700
1 file changed, 2 insertions(+)
Successfully rebased and updated refs/heads/main.
45562cc Tambah tabel
fc7d7b5 Fitur laporanEditor pesan terbuka berisi gabungan kedua pesan lama, dan menyimpannya tanpa mengubah apa pun menghasilkan satu commit berisi kedua perubahan. Pada pekerjaan nyata, isi editor itulah yang dirapikan menjadi satu pesan yang utuh. Opsi fixup menawarkan variasi yang lebih pendek, yaitu melebur isi tanpa menanyakan pesan, sehingga pesan commit di atasnya tetap dipakai.
Mengganti pesan dan membuang commit#
Operasi reword mengganti pesan tanpa mengubah isi, sedangkan drop atau penghapusan baris membuang commit beserta isinya. Keduanya dipraktikkan pada skenario terpisah agar keadaannya bersih.
rm -rf /tmp/lab-rebase-w
mkdir /tmp/lab-rebase-w
cd /tmp/lab-rebase-w
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"
GIT_SEQUENCE_EDITOR="sed -i '1s/^pick/reword/'" GIT_EDITOR="sed -i '1s/.*/Tambah bab dua/'" git rebase -i main
git log --onelineInitialized empty Git repository in /tmp/lab-rebase-w/.git/
[main (root-commit) 04068da] Satu
1 file changed, 1 insertion(+)
create mode 100644 berkas.txt
[main a76d532] dua
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/main.
a76d532 dua
04068da SatuEditor pesan terbuka berisi pesan lama dua, dan perintah pengganti baris pertamanya menyimpan Tambah bab dua. Untuk pembuangan, pola yang sama dipakai dengan mengganti kata menjadi drop, dan keluaran git log pada latihan berikut memperlihatkan commit itu lenyap tanpa jejak pada riwayat.
rm -rf /tmp/lab-rebase-d
mkdir /tmp/lab-rebase-d
cd /tmp/lab-rebase-d
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_SEQUENCE_EDITOR="sed -i '2s/^pick/drop/'" git rebase -i main
git log --onelineInitialized empty Git repository in /tmp/lab-rebase-d/.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(+)
Successfully rebased and updated refs/heads/main.
968dadf Tiga
83d9ee7 Dua
04068da SatuPerubahan commit Dua tidak muncul pada keadaan akhir, dan riwayatnya terdiri atas dua commit saja. Pemutaran ulang yang melompati commit itu berjalan mulus pada contoh, sedangkan pada riwayat nyata pembuangan dapat menimbulkan konflik yang diselesaikan sebagaimana konflik merge biasa.
Melanjutkan, melompati, dan membatalkan#
Rebase interaktif yang bertemu konflik berhenti di tengah daftar todo, dan statusnya menyatakan sisa pekerjaan. Tiga perintah kelanjutan menutup keadaan itu: git rebase --continue bergerak setelah konflik diselesaikan dan ditandai, git rebase --skip membuang commit yang bermasalah dari pemutaran, dan git rebase --abort membatalkan seluruh daftar sambil mengembalikan branch ke keadaan awal. Kelompok tiga ini layak dihafal bersama daftar todo, karena rebase interaktif tanpa jalan mundurnya terasa berisiko.
Daftar todo juga dapat disusun sebelum dibuka. Menulis pesan commit yang diawali fixup! diikuti subjek commit yang dituju, kemudian menjalankan rebase dengan opsi --autosquash, membuat Git menyusun baris fixup pada posisi yang benar secara otomatis. Pola ini menggeser usaha penataan ke saat commit dibuat, sehingga sesi rebase di akhir pekerjaan berjalan hampir tanpa penyuntingan.
Kapan riwayat layak ditata#
Menata riwayat memiliki dua waktu yang tepat, dan keduanya berada sebelum commit dibagikan. Waktu pertama adalah sebelum mengirim branch pekerjaan, ketika commit percobaan dan commit typo dirapikan menjadi unit yang dapat ditinjau. Pemeriksa kode yang membaca tiga commit yang utuh jauh lebih cepat daripada yang harus membaca sembilan commit yang terpotong.
Waktu kedua adalah saat menindaklanjuti catatan pemeriksa. Perbaikan pada hasil tinjauan dibuat sebagai commit fixup! di atas commit yang diperbaiki, lalu satu sesi rebase interaktif menyatukannya ke tempatnya, dan branch kembali berupa unit utuh sebelum dikirim ulang. Setelah commit dikirim dan dipakai orang lain, seluruh peralatan topik ini kembali ke wilayah terlarang sesuai aturan emas, dan pembetulan beralih ke revert.
Ringkasan#
- Rebase interaktif menyunting daftar todo berisi satu baris per commit, dan barisnya diproses dari atas ke bawah.
squashdanfixupmelebur commit ke commit di atasnya,rewordmengganti pesan, dandropmembuang commit.- Rebase yang diganggu di tengah jalan dilanjutkan dengan
git rebase --continuedan dibatalkan dengangit rebase --abort. - Seluruh operasi menulis ulang commit, sehingga hanya tepat untuk riwayat yang belum dikirim.
Referensi#
- git-rebase — Git Documentation — bagian Interactive Mode yang merinci seluruh kata perintah daftar todo.
- Git Tools - Rewriting History — Pro Git — bab Pro Git tentang rebase interaktif.