Chapter Rebase Conflicts menutup setiap konflik dengan git rebase --continue sampai baris Successfully rebased muncul. Padahal blok hint: saat rebase berhenti menawarkan tiga tombol: --continue, --skip, dan --abort. Ketiganya adalah panel kendali penuh atas rebase yang sedang berjalan — plus satu perintah penyusun ulang daftar sisa, --edit-todo. Chapter ini menjalankan keempatnya secara nyata pada skenario konflik yang sama, termasuk bukti bahwa --skip membuat sebuah commit hilang dari riwayat dan --abort mengembalikan branch ke kondisi pra-rebase persis byte-per-byte.

Repositori Latihan #

Bentuk tabrakan sengaja dibuat sederhana: branch fitur-harga menaikkan dua harga lewat dua commit, sementara main hanya menaikkan harga kopi — sehingga commit kopi pasti menabrak, sedangkan commit gula dapat diteruskan:

bash
mkdir latihan-abort && cd latihan-abort
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf 'kopi: 1000\n\ngula: 500\n' > harga.md
git add harga.md
git commit -m "Buat daftar harga"
git switch -c fitur-harga
printf 'kopi: 1500\n\ngula: 500\n' > harga.md
git add harga.md
git commit -m "Naikkan harga kopi jadi 1500"
printf 'kopi: 1500\n\ngula: 700\n' > harga.md
git add harga.md
git commit -m "Naikkan harga gula jadi 700"
git switch main
printf 'kopi: 1200\n\ngula: 500\n' > harga.md
git add harga.md
git commit -m "Sesuaikan harga kopi"
git switch fitur-harga
git log --oneline --graph --all

Output yang Dihasilkan:

text
* 68d9ea8 Sesuaikan harga kopi
| * e575135 Naikkan harga gula jadi 700
| * c90ae43 Naikkan harga kopi jadi 1500
|/  
* b2949fa Buat daftar harga

Setiap alur di chapter ini dijalankan dari keadaan persis ini — setelah satu alur selesai, bangun ulang repositorinya dengan blok perintah di atas (hapus direktori latihan-abort, lalu jalankan ulang) sebelum melanjutkan ke alur berikutnya. Hash pada keluaran milik kita akan berbeda di mesin Anda; polanya yang dipelajari.

Melanjutkan Rebase dengan –continue #

Dari fitur-harga, rebase ke main berhenti persis seperti chapter sebelumnya:

bash
git rebase main

Output yang Dihasilkan:

text
Auto-merging harga.md
CONFLICT (content): Merge conflict in harga.md
error: could not apply c90ae43... Naikkan harga kopi jadi 1500
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config advice.mergeConflict false"
Could not apply c90ae43... Naikkan harga kopi jadi 1500

Sebelum memutuskan apa pun, git status selalu menjadi layar progres: commit mana yang barusan gagal, command mana yang masih menunggu, dan opsi apa saja yang tersedia:

bash
git status

Output yang Dihasilkan:

text
interactive rebase in progress; onto 68d9ea8
Last command done (1 command done):
   pick c90ae43 Naikkan harga kopi jadi 1500
Next command to do (1 remaining command):
   pick e575135 Naikkan harga gula jadi 700
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'fitur-harga' on '68d9ea8'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
	both modified:   harga.md

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

Resolusinya mengikuti keputusan bisnis: harga kopi hasil fitur memang 1500. Setelah menulis hasilnya dan menandai dengan git add, git rebase --continue dijalankan. Karena commit hasil resolusi lahir kembali, editor pesan terbuka berisi pesan asli — supaya isinya ikut tercetak di keluaran, kita pakai cat sebagai editor (pola yang sudah dikenal dari chapter Interactive Rebase ); di terminal biasa, editor teks Anda yang terbuka:

bash
printf 'kopi: 1500\n\ngula: 500\n' > harga.md
git add harga.md
GIT_EDITOR=cat git rebase --continue

Output yang Dihasilkan:

text
Naikkan harga kopi jadi 1500

# Conflicts:
#	harga.md

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto 68d9ea8
# Last command done (1 command done):
#    pick c90ae43 Naikkan harga kopi jadi 1500
# Next command to do (1 remaining command):
#    pick e575135 Naikkan harga gula jadi 700
# You are currently rebasing branch 'fitur-harga' on '68d9ea8'.
#
# Changes to be committed:
#	modified:   harga.md
#
[detached HEAD e70dfcd] Naikkan harga kopi jadi 1500
 1 file changed, 1 insertion(+), 1 deletion(-)
Successfully rebased and updated refs/heads/fitur-harga.

Bagian atas keluaran itu adalah isi editor: pesan asli Naikkan harga kopi jadi 1500, daftar # Conflicts: yang barusan diselesaikan, dan ringkasan status rebase sebagai komentar — baris-baris # diabaikan Git saat pesan disimpan. Sisanya adalah keluaran permanen: [detached HEAD e70dfcd] menandai commit hasil resolusi lahir, 1 file changed, 1 insertion(+), 1 deletion(-) adalah diffstat-nya, dan karena commit gula diterapkan mulus di atasnya, rebase langsung tamat dengan Successfully rebased and updated refs/heads/fitur-harga.. Riwayat akhirnya linear:

bash
git log --oneline --graph --all

Output yang Dihasilkan:

text
* 9dd3de6 Naikkan harga gula jadi 700
* e70dfcd Naikkan harga kopi jadi 1500
* 68d9ea8 Sesuaikan harga kopi
* b2949fa Buat daftar harga
bash
cat harga.md

Output yang Dihasilkan:

text
kopi: 1500

gula: 700

Melewati Commit dengan –skip #

Bangun ulang repositori latihan, lalu jalankan rebase yang sama — ia berhenti di konflik kopi yang sama persis. Kali ini kita anggap commit kopi memang tidak layak diselamatkan (misalnya keputusan harga kopi sudah diambil main, jadi patch-nya tidak relevan lagi). Daripada menyelesaikan konfliknya, lewati saja:

bash
git rebase --skip

Output yang Dihasilkan:

text
Successfully rebased and updated refs/heads/fitur-harga.

Keluarannya pendek: tanpa resolusi, tanpa commit baru untuk kopi — rebase langsung menerapkan command berikutnya (pick gula) yang ternyata mulus, lalu selesai. Bukti dampaknya ada di log:

bash
git log --oneline --graph --all

Output yang Dihasilkan:

text
* 1e87cee Naikkan harga gula jadi 700
* 68d9ea8 Sesuaikan harga kopi
* b2949fa Buat daftar harga
bash
cat harga.md

Output yang Dihasilkan:

text
kopi: 1200

gula: 700

Commit Naikkan harga kopi jadi 1500 hilang dari riwayat fitur-harga — tiga commit tersisa, bukan empat. Harga kopi di berkas pun kembali milik main (1200), karena patch kenaikan 1500 tidak pernah diterapkan; hanya kenaikan gula yang dibawa fitur.

Membatalkan Semua dengan –abort #

Alur ketiga: bangun ulang repositori, simpan dulu hash ujung fitur-harga pra-rebase sebagai pembanding, lalu jalankan rebase hingga berhenti di konflik:

bash
git rev-parse HEAD > hash-pra.txt
cat hash-pra.txt
git rebase main

Output yang Dihasilkan (rebase berhenti di konflik kopi):

text
Auto-merging harga.md
CONFLICT (content): Merge conflict in harga.md
error: could not apply c90ae43... Naikkan harga kopi jadi 1500
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config advice.mergeConflict false"
Could not apply c90ae43... Naikkan harga kopi jadi 1500

Sekarang batalkan semuanya:

bash
git rebase --abort

Output yang Dihasilkan:

text

--abort tidak mencetak apa pun — ia bekerja diam-diam. Verifikasinya tiga lapis. Pertama, hash ujung branch:

bash
git rev-parse HEAD

Output yang Dihasilkan:

text
e575135c2097ef3d181996c4080d7c6a7b6b8f6d

Hash itu identik dengan isi hash-pra.txt (e575135c2097ef3d181996c4080d7c6a7b6b8f6d) yang disimpan sebelum rebase — branch pulang ke titik yang sama. Kedua, bentuk grafnya:

bash
git log --oneline --graph --all

Output yang Dihasilkan:

text
* 68d9ea8 Sesuaikan harga kopi
| * e575135 Naikkan harga gula jadi 700
| * c90ae43 Naikkan harga kopi jadi 1500
|/  
* b2949fa Buat daftar harga

Graf yang tadinya “hampir linear” kembali bercabang seperti sebelum rebase — persis c09-log-before di awal chapter. Ketiga, kebersihan working tree:

bash
git status

Output yang Dihasilkan:

text
On branch fitur-harga
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	hash-pra.txt

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

Working tree bersih; satu-satunya berkas asing adalah hash-pra.txt buatan kita sendiri yang memang belum dilacak. --abort mengembalikan seluruh keadaan — posisi branch, index, dan isi working directory — seolah rebase tidak pernah dijalankan.

Menata Ulang Sisa Daftar dengan –edit-todo #

Satu alat terakhir: git rebase --edit-todo membuka kembali daftar todo berisi command yang belum dieksekusi. Dengan trik cat, isinya terpajang tanpa mengubah apa pun (bangun ulang repositori dan biarkan rebase berhenti di konflik kopi seperti biasa):

bash
GIT_SEQUENCE_EDITOR=cat git rebase --edit-todo

Output yang Dihasilkan (dipotong):

text
pick e575135 Naikkan harga gula jadi 700
(dipotong — sisanya komentar bantuan bawaan Git)

Daftar itu hanya memuat satu baris aktif — pick e575135 Naikkan harga gula jadi 700 — karena pick c90ae43 sudah didahulukan (gagal) dan tidak lagi menunggu. Dalam praktiknya, editor todo yang dibuka --edit-todo bisa kita sunting seperti todo interaktif biasa: menukar urutan command tersisa, mengganti pick menjadi reword atau squash, bahkan menghapus baris — semua aturan dari chapter Interactive Rebase berlaku untuk sisa daftar. Setelah editor ditutup, rebase tetap berhenti menunggu --continue; mengedit todo tidak menjalankan apa pun.

Empat Perintah Kontrol Rebase #

PerintahEfekKapan dipakai
git rebase --continueBuat commit dari resolusi, jalankan command berikutnyaSetelah konflik selesai di-resolve dan di-git add
git rebase --skipBuang commit yang gagal diterapkan, lanjut ke command berikutnyaPatch memang sudah tidak relevan dengan basis baru
git rebase --abortKembalikan seluruh keadaan ke pra-rebase, hentikan rebaseRebase salah arah, ingin mulai ulang dari nol
git rebase --edit-todoBuka editor untuk menata ulang command yang belum dieksekusiStrategi sisa daftar perlu diubah di tengah jalan

Keempatnya hanya bermakna saat rebase sedang berhenti; di luar itu Git menolak dengan fatal: no rebase in progress — persis seperti --abort yang dicoba pada rebase yang sudah selesai. Detail setiap opsi terdokumentasi di git-rebase .

Dengan panel kendali lengkap di tangan, rebase tidak lagi terasa seperti sekali jalan tanpa pintu keluar. Pertanyaan berikutnya berbalik arah: bagaimana bila yang kita butuhkan bukan seluruh branch, melainkan satu-dua commit pilihan saja? Untuk itu Git punya git cherry-pick — pokok bahasan Cherry-Pick .