🧰 Git Rescue Notes

Git Rebase Macet: Cara Aman Pulihkan Branch Main Lokal

Kadang masalah Git bukan karena filenya konflik, tapi karena proses rebase lama belum selesai, pointer branch berubah, atau object Git belum lengkap. Kasus ini terlihat menyeramkan, padahal bisa dibereskan asal urutannya tidak asal gas.

Ilustrasi terminal Git untuk memperbaiki rebase branch main yang macet
Satu pesan error Git bisa terlihat seperti kiamat kecil, tapi biasanya ia cuma minta kita membaca status dengan tenang.

Ceritanya dimulai dari perintah yang kelihatannya biasa saja: `git pull`. Harapannya sederhana, ambil perubahan terbaru dari remote lalu lanjut kerja. Namun Git malah berhenti dengan pesan bahwa ada direktori `.git/rebase-merge`. Artinya, Git mendeteksi proses rebase sebelumnya belum selesai.

git pull
fatal: It seems that there is already a rebase-merge directory, and
I wonder if you are in the middle of another rebase.

Di titik ini, godaan paling besar adalah langsung menghapus folder `.git/rebase-merge`. Secara teknis bisa saja, tetapi itu seperti membongkar meja operasi saat pasien belum benar-benar selesai dijahit. Git sudah memberi peringatan karena mungkin masih ada informasi penting di sana.

**Jangan buru-buru menghapus folder rebase.** Kalau rebase memang masih aktif, menghapus metadata-nya bisa membuat riwayat commit makin sulit dibaca. Langkah pertama yang lebih sehat adalah membaca kondisi repo dengan `git status`.

Ketika Git Bilang Branch Sudah Bercabang

Dari `git status`, terlihat bahwa branch lokal `main` dan `origin/main` sudah tidak berada di jalur yang sama. Lokal punya empat commit, sementara remote punya satu commit berbeda. Ini bukan bencana. Ini hanya berarti riwayat commit bercabang dan perlu disatukan dengan strategi yang benar.

git status
On branch main
Your branch and 'origin/main' have diverged,
and have 4 and 1 different commits each, respectively.
You are currently editing a commit while rebasing branch 'main' on '82f8fad1'.
nothing to commit, working tree clean

Bagian yang menarik adalah kalimat currently editing a commit while rebasing. Ini menunjukkan Git masih menganggap rebase sedang berjalan. Karena working tree bersih, tidak ada file konflik yang perlu diselesaikan. Maka langkah wajar berikutnya adalah mencoba melanjutkan rebase.

git rebase --continue
error: update_ref failed for ref 'refs/heads/main':
cannot lock ref 'refs/heads/main':
is at 79408d277201822a2d50b2f5a86f7854dff0ff33
but expected aeb1fee171a18a222d7dc0eb738a7299331017a8
error: could not update refs/heads/main

Nah, ini bagian yang sering bikin orang menatap terminal sambil mulai mempertanyakan pilihan hidup. Git tidak sedang mengeluh soal isi file, tetapi soal pointer branch. Ia mau memperbarui `refs/heads/main`, tetapi posisi branch yang ia temukan sudah berbeda dari posisi yang ia harapkan.

Masalahnya Bukan Konflik File, Tapi Pointer Branch

Error `cannot lock ref` dalam konteks ini berarti Git menolak memindahkan branch karena ia takut menimpa perubahan yang tidak sesuai ekspektasi. Ini justru mekanisme pengaman. Git agak cerewet, tapi cerewetnya berguna.

KondisiArti PraktisRespons Aman
`.git/rebase-merge` masih adaRebase lama belum ditutup sempurna.Periksa `git status`, jangan langsung hapus.
Branch lokal dan remote divergedLokal dan remote punya commit berbeda dari titik yang sama.Rebase lokal ke atas `origin/main`.
`cannot lock ref`Pointer branch berubah dari yang Git harapkan.Backup branch dulu, lalu lanjutkan dengan hati-hati.
`Could not read` pada SHA tertentuAda object Git yang belum tersedia atau tidak terbaca.Fetch ulang dari remote dan verifikasi object.

Saat Git Log Ikut Gagal

Setelah error ref, pemeriksaan riwayat dengan `git log --all` sempat gagal. Ini tanda bahwa Git sedang mencoba membaca sebuah object commit, tetapi object tersebut belum tersedia di database lokal.

git log --oneline --decorate --graph --all -15
error: Could not read 857c7958099887bd81f636daf105f6647515ee6c
fatal: revision walk setup failed

Untuk memastikan apakah object tersebut benar-benar hilang atau hanya belum terambil, perintah yang tepat adalah `git cat-file -t`. Perintah ini menanyakan tipe object kepada Git: apakah itu commit, tree, blob, tag, atau memang tidak ada.

git cat-file -t 857c7958099887bd81f636daf105f6647515ee6c
remote: Enumerating objects: 7394, done.
remote: Counting objects: 100% (7394/7394), done.
remote: Compressing objects: 100% (2622/2622), done.
Receiving objects: 100% (7394/7394), done.
Resolving deltas: 100% (2648/2648), done.
commit

Begitu hasilnya `commit`, object yang sebelumnya tidak terbaca sudah berhasil tersedia lagi. Dalam kasus ini, proses pembacaan memicu pengambilan object dari remote. Setelah itu, riwayat commit bisa dilihat normal.

Membaca Peta Commit Sebelum Bertindak

Setelah object pulih, tampilan log akhirnya menjelaskan duduk perkaranya. Branch lokal `main` berada di atas beberapa commit lokal, sedangkan `origin/main` punya satu commit baru di jalur terpisah.

git log --oneline --decorate --graph --all -15
* 79408d27 (HEAD -> main, backup-rebase-result, backup-main-current) audit konten
* 5602b4e3 audit konten
* aeb1fee1 audit konten
* 6d369078 audit konten
| * 82f8fad1 (origin/main, origin/HEAD) beres: update data site [2026-06-17 13:11]
|/
* 227edcab audit konten
* 96fa9448 audit konten
* 88f2bc18 audit konten

Bentuk grafik itu memberi jawaban yang jelas: commit lokal perlu dipindahkan ke atas commit remote terbaru. Dengan kata lain, yang dibutuhkan bukan merge asal-asalan, melainkan rebase ulang ke `origin/main`.

**Kenapa bukan langsung pull lagi?** Karena `git pull` adalah gabungan dari fetch dan integrasi. Saat kondisi repo masih belum jelas, lebih aman melakukan langkah eksplisit: cek status, fetch, baca log, lalu rebase.

Urutan Pemulihan yang Lebih Aman

Dalam kasus seperti ini, pendekatannya harus berlapis. Bukan karena Git manja, tetapi karena kita sedang menyentuh riwayat commit. Sekali salah reset atau hapus metadata, efeknya bisa melebar.

  1. **Baca kondisi repo.** Mulai dari `git status` untuk memastikan apakah masih ada rebase aktif, konflik, atau working tree kotor.
  2. **Jangan hapus metadata rebase sebelum yakin.** Folder `.git/rebase-merge` bisa berisi state penting dari proses sebelumnya.
  3. **Verifikasi object yang tidak terbaca.** Gunakan `git cat-file -t SHA` untuk memastikan object bisa diakses.
  4. **Buat backup branch.** Simpan posisi branch saat ini agar ada jalur pulang kalau eksperimen berubah jadi episode tambahan.
  5. **Rebase lokal ke remote terbaru.** Setelah log sehat, jalankan `git rebase origin/main`.
  6. **Verifikasi lalu push.** Jika rebase sukses dan status bersih, barulah push ke remote.

Perintah Final yang Menyelesaikan Kasus

Setelah kondisi repo terbaca normal dan branch lokal sudah aman, perintah kunci yang menyelesaikan kasus ini adalah:

git rebase origin/main
Successfully rebased and updated refs/heads/main.

Pesan itu adalah tanda bagus. Artinya commit lokal sudah berhasil ditempatkan ulang di atas commit terbaru dari remote. Riwayat menjadi lebih linear, dan branch `main` lokal sudah siap diverifikasi.

git status
git log --oneline --decorate --graph --all -15
git push

Jika `git push` normal ditolak karena remote berubah lagi, opsi yang lebih aman daripada `--force` polos adalah `--force-with-lease`. Perintah ini tetap menjaga agar kita tidak menimpa update orang lain yang belum kita ambil.

git push --force-with-lease
**Intinya:** kasus ini selesai bukan dengan menghapus paksa folder rebase, melainkan dengan membaca state Git, memulihkan object yang belum terbaca, memahami grafik commit, lalu menjalankan rebase ke `origin/main`.

Kenapa Sparse Checkout Muncul di Status?

Dalam status tadi juga muncul keterangan bahwa repository memakai sparse checkout dengan sebagian file tracked yang hadir di working tree. Sparse checkout berarti Git hanya menampilkan sebagian isi repository di folder kerja lokal. Ini umum dipakai untuk repo besar atau ketika kita hanya butuh area tertentu.

Keterangan sparse checkout tidak otomatis berarti repo bermasalah. Namun saat ada error object atau rebase, informasi ini tetap penting karena working tree lokal memang tidak memuat semua file. Jadi, saat memperbaiki konflik, jangan heran kalau file yang terlihat di folder lokal tidak sebanyak isi repo sebenarnya.

Pola Pikir yang Perlu Diingat

Git sering terlihat galak karena pesan error-nya panjang dan nadanya seperti dosen pembimbing yang kecewa. Padahal, kebanyakan pesan itu cukup informatif kalau dibaca pelan-pelan. Dalam kasus ini, ada tiga lapisan masalah yang saling menumpuk.

  • Rebase lama masih meninggalkan state aktif.
  • Branch lokal dan remote sudah bercabang.
  • Salah satu object commit sempat belum terbaca, lalu pulih setelah fetch.

Begitu tiga lapisan itu dipisahkan, solusinya jadi masuk akal. Jangan langsung reset, jangan langsung hapus folder internal Git, dan jangan langsung force push. Baca dulu. Backup dulu. Baru eksekusi.

Rebase yang macet itu bukan akhir dunia. Paling banter akhir dari ketenangan sepuluh menit, sebelum akhirnya kita ingat bahwa `git status` adalah teman, bukan hiasan terminal.

Checklist Cepat Jika Mengalami Kasus Serupa

Kalau suatu hari `git pull` gagal karena rebase lama belum selesai, gunakan checklist pendek ini. Cocok ditempel di catatan kerja biar tidak perlu panik sambil mengetik perintah random.

git status
git log --oneline --decorate --graph --all -15
git fetch origin --prune
git branch -f backup-main-current main
git branch -f backup-rebase-result HEAD
git rebase origin/main
git status
git push

Untuk bacaan teknis tambahan, dokumentasi resmi Git tentang git rebase, git status, dan git fetch menjelaskan detail perilaku masing-masing perintah. Tidak selalu ringan dibaca, tapi lumayan ampuh untuk membedakan error sungguhan dan Git yang cuma sedang protektif.

Penutup

Kasus ini menunjukkan bahwa penyelamatan Git yang aman bukan soal hafal satu mantra sakti, melainkan memahami urutan. Mulai dari status, pahami pesan error, cek object, baca grafik commit, lalu pilih tindakan yang paling kecil risikonya.

Ketika akhirnya muncul pesan `Successfully rebased and updated refs/heads/main`, berarti branch lokal sudah kembali rapi di atas remote. Setelah itu tinggal verifikasi dan push. Git-nya selesai drama, manusianya boleh lanjut ngopi.