Jika Anda sudah lama menggunakan Git, Anda mungkin pernah menemukan riwayat yang penuh dengan commit yang tidak berguna, pesan "WIP", pengujian cepat, atau bahkan commit kosong yang dibuat hanya untuk memicu hook atau pipeline. Pada saat itu, Anda melihat log dan berpikir: “Tidak ada yang bisa memahami ini”Kabar baiknya adalah Anda tidak sendirian: hal ini terjadi pada kita semua, dan itulah gunanya dukungan. git rebase.
Yang menarik adalah, jika digunakan dengan benar, Perintah `git rebase` memungkinkan Anda untuk "membersihkan" riwayat commit.Buatlah agar terstruktur, bebas dari gangguan, dan jauh lebih mudah untuk ditinjau. Anda dapat menghapus commit pengujian, menggabungkan beberapa commit menjadi satu, menyusun ulang commit, mengoreksi pesan commit, dan bahkan menghapus perubahan dari remote melalui push paksa. Mari kita lihat, dengan contoh konkret, bagaimana menggunakan rebase untuk mengubah riwayat Anda dari kekacauan total menjadi sesuatu yang terorganisir dan mudah dibaca.
Apa sebenarnya Git Rebase dan mengapa hal itu memengaruhi riwayat?
Ketika kita berbicara tentang menyalip, kita benar-benar berbicara tentang mengubah titik awal suatu cabangGit mengambil commit dari branch Anda dan "mereproduksinya" satu per satu pada base lain (biasanya branch). utama atau cabang jarak jauh yang diperbarui). Seolah-olah Anda kembali ke masa lalu dan memulai pekerjaan Anda dari commit yang berbeda, tetapi tetap mempertahankan perubahannya.
Bayangkan proyek Anda memiliki cerita ini di cabang utama: A – B – CAnda membuat cabang fungsionalitas dan kemudian melakukan dua commit: DARISementara itu, di main, seseorang menambahkan commit baru. FTanpa melakukan rebase, cabang Anda akan terlihat seperti ini:
A---B---C---F (main)
A---B---C---D---E (feature)
Jika Anda melakukan penggabungan klasik cabang fitur Anda ke cabang utama, yang Anda dapatkan adalah commit penggabungan tambahan, yang sering kali menghasilkan sejarah yang kusut dengan beberapa garis yang bersilangan. Dengan rebase, di sisi lain, Git mengambil commit D dan E Anda dan menerapkannya kembali ke F:
A---B---C---F---D'---E' (feature reescrita)
Itu D' dan E' Ini bukan commit yang persis sama dengan D dan E: ini adalah "salinan" dengan pengenal (hash) baru. Itulah mengapa kita menyebutnya rebase. menulis ulang sejarahHasilnya adalah log yang lebih linier, tanpa commit penggabungan perantara yang hanya menambah gangguan.

Mengapa Anda harus memiliki riwayat commit yang bersih
Pengorganisasian arsip yang baik bukan hanya soal estetika. Catatan yang rapi membuat pekerjaan sehari-hari jauh lebih mudah.Anda dapat melihat sekilas apa yang telah dilakukan, kapan, dan mengapa, tanpa harus menelusuri commit penggabungan yang kosong atau pesan "perbaikan cepat" yang tidak kontekstual.
Ketika cabang digabungkan dengan terus-menerus menggabungkan dari cabang utama, Anda akan mendapatkan banyak commit seperti “Gabungkan cabang 'utama' ke dalam fitur-x” yang Mereka tidak memberikan informasi yang sebenarnya tentang perubahan kode.Hal ini mempersulit tugas-tugas seperti:
- Temukan commit tempat bug tersebut muncul menggunakan alat untuk membandingkan filekarena sejarahnya penuh dengan penggabungan yang tidak relevan.
- Tinjau permintaan pull.karena Anda harus berpindah-pindah antara commit yang berulang untuk melihat apa yang sebenarnya berubah.
- Memahami evolusi suatu fiturterutama jika hal tersebut dikembangkan melalui banyak komitmen pengujian kecil.
Git rebase adalah alat yang ideal untuk "memoles" semua kekacauan itu sebelum membagikan branch tersebut kepada anggota tim lainnya. Ini seperti memasukkan sejarahmu ke dalam mesin cuci.Anda menyimpan perubahan-perubahan penting, dikelompokkan dengan baik dan dengan pesan yang jelas.
Perbedaan utama antara git merge dan git rebase
Untuk sepenuhnya memahami apa yang Anda lakukan saat menggunakan rebase, ada baiknya membandingkan perilakunya dengan perilaku git bergabungKeduanya berfungsi untuk mengintegrasikan perubahan, tetapi dengan cara yang berbeda dan dengan implikasi penting bagi catatan tersebut.
dengan bergabungGit membuat commit penggabungan baru yang memiliki dua induk: ujung cabang Anda dan ujung cabang yang Anda gabungkan. Riwayat yang dihasilkan mempertahankan urutan commit asli secara persis.Namun, pada akhirnya bisa dipenuhi dengan cabang dan penggabungan paralel.
dengan RebaseAlih-alih membuat commit penggabungan, Git mengambil commit Anda dan menerapkannya satu per satu ke basis data baru. Ini menghasilkan komitmen baru dengan hash barumeskipun perubahan kodenya sama.
Dalam praktek:
- Bergabung Ia mempertahankan sejarah persis seperti yang terjadi, dengan semua keterkaitan dan penggabungannya.
- rebase Ini menghasilkan riwayat yang linier dan rapi, seolah-olah semuanya terjadi dalam garis lurus.
Pilihannya bukanlah "salah satu lebih baik daripada yang lain" tetapi Masing-masing lebih cocok untuk situasi yang mana?Untuk menggabungkan cabang yang sudah dibagikan dan ditutup, penggabungan (merging) biasanya lebih aman. Untuk menjaga agar cabang kerja lokal tetap terorganisir atau sebelum membuka permintaan pull (pull request), rebase lebih unggul.

Kasus-kasus di mana rebase unggul: memperbarui dan menyempurnakan branch.
Ada dua skenario di mana sebagian besar pengembang menggunakan rebase setiap hari: Pastikan cabang kerja Anda selalu diperbarui dengan versi utama. y Bersihkan commit sebelum membagikannyaMari kita lihat lebih detail.
Perbarui cabang fitur Anda dengan perubahan terbaru dari cabang utama.
Anda sedang mengerjakan fitur baru di cabang Anda, tetapi sementara itu rekan-rekan Anda masih melakukan commit di cabang lain. utamaJika Anda ingin mengintegrasikan perubahan Anda, salah satu opsinya adalah:
git checkout tu-rama-feature
git merge main
Cara ini berhasil, tetapi menghasilkan commit penggabungan setiap kali Anda melakukan sinkronisasi, yang pada akhirnya akan menimbulkan masalah. sejarah yang penuh dengan penggabungan berulangNamun, jika Anda melakukan hal tersebut:
git checkout tu-rama-feature
git rebase main
Git akan memindahkan commit Anda ke atas status terakhir cabang utama, seolah-olah Anda memulai cabang tersebut setelah perubahan tersebut. Anda akan mendapatkan riwayat linier, tanpa commit penggabungan perantaradan ulasannya akan lebih jelas.
Bersihkan commit Anda sebelum membuka pull request.
Sangat umum terjadi bahwa, selama pengembangan suatu fitur, Anda akan mendapatkan commit seperti "perbaikan kesalahan ketik", "pengujian pipeline", "perubahan login lainnya", dll. Itu tidak masalah selama Anda bekerja, tetapi Itu bukan jenis sejarah yang ingin Anda tunjukkan. saat Anda membuka permintaan pull (PR).
Rebase interaktif memungkinkan Anda mengatur ulang dan mengelompokkan komitmen-komitmen tersebut menjadi sesuatu yang lebih logis. Misalnya, alih-alih seperti ini:
- WIP: añadir login
- Más cambios login
- Corregir tests login
- Arreglar typo variable
Anda bisa mendapatkan satu commit yang terdeskripsi dengan baik:
- Añadir funcionalidad completa de login de usuario con tests
"Penyempurnaan" sejarah tersebut membuatnya jauh lebih mudah dipahami oleh para pengulas. kontribusi setiap commit dan menyederhanakan pemecahan masalah di masa mendatang.
Rebase interaktif untuk menulis ulang sejarah.
Versi dasar rebase hanya memindahkan commit Anda ke basis lain. Tetapi fitur utamanya adalah... overbase interaktif, yang membuka editor dengan daftar commit terbaru sehingga Anda dapat memutuskan apa yang akan dilakukan dengan masing-masing commit.
Cara umum untuk memulainya adalah dengan menentukan berapa banyak commit ke belakang yang ingin Anda "sentuh" dari HEAD Anda saat ini. Misalnya:
git rebase -i HEAD~6
Perintah ini memberi tahu Git: “ambil 6 commit terakhir dari cabang ini dan siapkan rebase interaktif untuk saya.” Git akan membuka editor default Anda (Vim, Nano, VS Code, dll.) dengan tampilan seperti ini:
pick 7ed9c6e update version
pick ecb7ef3 empty commit 1
pick a323615 empty commit 2
pick 2c3d41d empty commit 3
pick d53c00f empty commit 4
pick 22dcc79 empty commit 5
# Rebase 549dd76..22dcc79 onto 549dd76 (6 commands)
#
# Perintah:
# p, pilih = gunakan commit
# r, mengubah kata = Gunakan commit, tetapi edit pesannya
# e, edit = Gunakan commit dan stop untuk memodifikasinya
# s, labu = gabungkan commit sebelumnya
# f, perbaikan = seperti squash, tetapi mengabaikan pesannya
# x, eksekusi = jalankan perintah shell
# b, break = hentikan rebase di sini
# d, jatuhkan = hapus komit
#…
Perhatikan satu detail penting: Urutan dalam file ini adalah kebalikan dari apa yang Anda lihat di git log.Dalam file tersebut, commit pertama yang tercantum (7ed9c6e) adalah yang tertua dari keenam commit, dan yang terakhir (22dcc79) adalah yang terbaru. Ini penting untuk menghindari kebingungan saat Anda menghapus atau mengubah urutan commit.
Hapus commit uji atau kosong dari riwayat lokal.
Misalkan, untuk menguji sebuah Git hook, Anda telah membuat commit kosong dengan opsi tersebut. –izinkan kosong. Sebagai contoh:
git commit -m "commit with no changes" --allow-empty
Opsi ini memungkinkan Anda membuat commit bahkan ketika tidak ada perubahan pada file, yang berguna untuk pengujian, tetapi Hal itu mengacaukan riwayat dengan commit yang tidak memiliki nilai nyata.Bayangkan log Anda terlihat seperti ini:
git log --pretty=oneline --abbrev-commit
Dan Anda mendapatkan:
22dcc79 (HEAD -> main, origin/main, origin/HEAD) empty commit 5
d53c00f empty commit 4
2c3d41d empty commit 3
a323615 empty commit 2
ecb7ef3 empty commit 1
7ed9c6e update version
Dalam skenario ini, Anda hanya ingin menyimpan commit "versi pembaruan" yang berguna dan menghapus semua commit lainnya. komitmen kosong yang hanya berupa pengujian. Untuk melakukan ini, Anda menjalankan rebase interaktif pada 6 commit terakhir:
git rebase -i HEAD~6
Editor akan terbuka dengan 6 commit. Tujuan Anda adalah menghapus baris yang sesuai dengan commit kosong. Artinya, Anda hanya menyisakan sesuatu seperti ini:
pick 7ed9c6e update version
# Rebase 549dd76..22dcc79 onto 549dd76 (6 commands)
# … sisa komentar …
Seperti yang tertera di bagian bantuan pada file itu sendiri, Jika Anda menghapus sebuah baris, commit tersebut akan hilang dari riwayat. Pada versi baru yang telah ditulis ulang, saat menyimpan dan menutup editor, Git hanya akan mereproduksi commit "versi pembaruan" dan mengabaikan yang lainnya.
Mengunggah cerita baru ke Origin: menggunakan push paksa.
Sejauh ini, semua perubahan rebase telah dilakukan pada salinan lokal repositori Anda. Jika Anda ingin pembersihan tersebut juga tercermin di repositori jarak jauh (misalnya, di asal/utama), Anda harus menimpa riwayat jarak jauh dengan yang baru.
Ini dilakukan dengan sebuah dorongan paksaCara umum untuk menunjukkannya adalah dengan menggunakan tanda "+" di depan nama cabang saat melakukan push:
git push origin +main
Tanda plus itu memberi tahu Git bahwa Abaikan perbedaan riwayat dan timpa cabang jarak jauh. dengan versi yang Anda tulis ulang. Jika Anda hanya mencoba melakukan:
git push origin main
Git akan memperingatkan Anda bahwa riwayat lokal Anda bukanlah turunan langsung dari riwayat jarak jauh (karena Anda telah menulis ulang commit dengan rebase) dan akan menolak push untuk menghindari kehilangan data.
Penting untuk dipahami bahwa, setelah dorongan paksa ini, Commit yang dihapus tidak akan lagi dapat diakses dari origin/main.Riwayat tersebut mungkin masih tersimpan dalam reflog atau salinan lokal dari kolega lain, tetapi untuk tujuan praktis, Anda telah menghapus riwayat jarak jauh.
Peringatan serius: menulis ulang cabang bersama bukanlah permainan.
Menulis ulang riwayat terdengar bagus untuk mengatur segalanya, tetapi hal ini memiliki konsekuensi penting: ketika membuat commit baru dengan hash baru, Anda mengacaukan siapa pun yang telah mendasarkan pekerjaan mereka pada commit lama.Itulah mengapa aturan emas yang terkenal itu ada:
Jangan melakukan rebase pada branch yang sudah dibagikan dan aktif digunakan oleh orang lain.
Dalam praktiknya, ini berarti aman untuk menggunakan rebase pada:
- Cabang fitur lokal yang belum Anda publikasikan atau yang hanya Anda gunakan.
- Komitmen Terbaru orang-orang yang Anda tahu belum diandalkan oleh orang lain.
Dan melakukan hal itu tentang: adalah ide yang sangat buruk.
- cabang utama, pengembangan, atau cabang "resmi" mana pun dari repositori yang menjadi dasar bagi beberapa orang.
- Cabang kerja bersama di mana terdapat lebih dari satu pengembang yang melakukan commit.
Jika Anda menulis ulang riwayat cabang bersama dan kemudian melakukan push paksa, rekan tim lainnya akan menemukan bahwa Cabang-cabangnya mengarah ke commit yang sudah tidak ada lagi di remote.Mereka harus melakukan operasi yang lebih canggih (seperti melakukan rebase pada riwayat baru atau melakukan reset) untuk memperbaiki kekacauan tersebut.
Dorongan paksa: lebih baik dengan sabuk pengaman
Dalam banyak kasus, setelah rebase Anda perlu melakukan push paksa. Opsi klasiknya adalah:
git push --force origin tu-rama
Namun, varian ini menimpa apa pun yang ada di repositori jarak jauh tanpa meminta izin. Untuk menghindari penimpaan pekerjaan orang lain secara tidak sengaja, Git menawarkan opsi yang jauh lebih baik: –paksa-dengan-sewa.
Saat Anda melakukan:
git push --force-with-lease origin tu-rama
Git pertama-tama memeriksa bahwa Remote tersebut masih dalam kondisi seperti yang Anda duga. Saat Anda melakukan pull atau fetch terakhir. Jika sistem mendeteksi bahwa seseorang telah melakukan push commit baru ke branch tersebut sejak saat itu, push akan ditolak dan tidak dipaksakan, sehingga mencegah Anda menimpa perubahan orang lain.
Ide dasarnya adalah menggabungkan rebase dan force push, selalu dengan kepala dingin: hanya di cabang yang Anda kendalikan dan menggunakan, jika memungkinkan, –force-with-lease sebagai lapisan keamanan tambahan.
Apa yang harus dilakukan ketika rebase gagal: reflog sebagai penyelamat.
Hal ini pernah terjadi pada kita semua: Anda memulai rebase interaktif, secara tidak sengaja menghapus atau mengubah sesuatu, menyelesaikan konflik dengan tidak benar, dan tiba-tiba Sepertinya kamu kehilangan sebagian pekerjaanmuSebelum Anda panik, ingatlah bahwa Git memiliki kartu AS di lengan bajunya: git reflog.
Reflog adalah catatan lokal dari semua pergerakan HEAD: commit baru, reset, rebase, merge… Berkat itu, Anda dapat menemukan di mana branch Anda berada sebelum Anda mengacaukannya dan kembali ke titik tersebut dengan hard reset.
Alur tipikal akan seperti ini:
git reflog
Di sana Anda akan melihat daftar entri dengan sesuatu seperti:
abc1234 HEAD@{0}: rebase terminado
def5678 HEAD@{1}: checkout: moving from main to main
...
Anda mengidentifikasi commit yang Anda gunakan sebelum memulai rebase (misalnya, def5678) dan kamu kembali kepadanya dengan:
git reset --hard def5678
Dengan cara ini, Anda sepenuhnya menghapus lapisan tersebut. dan Anda kembali ke keadaan sebelumnya. Anda juga dapat membatalkan rebase yang sedang berlangsung (jika Anda berada di tengah proses dan belum selesai) hanya dengan:
git rebase --abort
Perintah ini akan mempertahankan branch Anda seperti sebelum memulai rebase saat ini, sangat cocok ketika muncul konflik yang tidak Anda inginkan atau Anda merasa bahwa ini bukan waktu yang tepat untuk melanjutkan.
Git pull vs git pull –rebase: perbedaan kecil, dampak besar
Poin lain yang sering menimbulkan keraguan adalah perbedaan antara git pull biasa dan git pull --rebaseKeduanya memperbarui cabang lokal Anda dari jarak jauh, tetapi mereka melakukannya dengan cara yang berbeda.
Saat Anda berlari:
git pull
Git terdiri dari dua langkah: git ambil untuk membawa perubahan dari jarak jauh dan kemudian git bergabung untuk menggabungkannya dengan cabang Anda saat ini. Ini mungkin akan membuat commit penggabungan tambahan jika Anda memiliki commit lokal di atas commit jarak jauh, yang sekali lagi riwayat dengan penggabungan yang tidak perlu.
Namun, jika Anda menjalankan:
git pull --rebase
Git melakukan pengambilan data (fetch) dan kemudian Salin commit lokal Anda ke versi yang diperbarui di remote.Hasilnya mirip dengan jika Anda melakukan hal tersebut. git fetch diikuti oleh git rebase origin/maindan mempertahankan sejarah yang lebih bersih dan lebih linier.
Itulah mengapa banyak tim mengkonfigurasi Git untuk menggunakan rebase secara default saat melakukan pull. Ini adalah cara sederhana untuk hindari commit penggabungan otomatis yang tidak memberikan kontribusi banyak.
Menghapus file atau gambar dari riwayat: gambaran umum
Terkadang masalahnya bukan pada commit yang buruk, tetapi sebuah file yang seharusnya tidak pernah sampai ke repositori: gambar yang salah, kredensial yang tidak tepat, file yang terlalu besar, dll. Godaannya adalah pergi ke GitHub dan mencari ikon tempat sampah, tetapi jika ikon tersebut tampak dinonaktifkan dan menampilkan pesan seperti "Anda harus berada di cabang", itu karena GitHub tidak mengizinkan Anda menghapus riwayat seperti itu..
Cara yang benar biasanya melibatkan penggunaan penulisan ulang riwayat dari mesin lokal Anda (dengan rebase interaktif atau alat seperti git filter-repo) lalu melakukan push paksa. Di GitHub Desktop Anda juga dapat mengelola branch dan commit, tetapi pengoperasiannya menghapus file sepenuhnya dari semua commit Ini melibatkan penulisan ulang sejarah dengan cara yang mirip dengan apa yang kita lihat di sini.
Singkatnya, jika Anda mengunggah gambar yang salah atau file sensitif dan ingin agar gambar atau file tersebut "hilang" dari riwayat, menghapusnya di commit terakhir saja tidak cukup: Commit tempat fitur ini diperkenalkan perlu ditulis ulang. lalu paksakan dorongan tersebut. Ini adalah operasi yang rumit dan harus dilakukan dengan tenang dan berkoordinasi dengan tim Anda.
Alur praktis untuk berlatih menyalip tanpa merusak apa pun.
Cara terbaik untuk mahir menyalip adalah dengan berlatih di lingkungan yang terkontrol, tanpa takut mengganggu pekerjaan orang lain. Alur sederhananya adalah:
- Buat cabang baru dari cabang utama dengan git checkout -b my-branch-tests.
- Lakukan beberapa commit kecil (ini bisa berupa perubahan sepele atau file pengujian).
- Simulasikan kemajuan di cabang utama dengan membuat commit baru di sana (atau meminta orang lain untuk melakukannya).
- Kembali ke cabang pengujian Anda dan jalankan git rebase main untuk melihat bagaimana commit Anda diposisikan ulang.
- coba a git rebase -i HEAD~3 untuk menggabungkan, mengganti nama, atau menghapus salah satu commit terbaru.
Dengan latihan ini Anda akan melihat bagaimana Ubah riwayat sebelum dan sesudahBagaimana Git merespons konflik dan bagaimana Anda dapat mengembalikan ke keadaan sebelumnya menggunakan reflog jika diperlukan. Semakin banyak latihan yang Anda lakukan secara lokal, semakin percaya diri Anda saat menerapkan teknik ini ke cabang proyek nyata.
Menguasai Git rebase memungkinkan Anda mengubah riwayat yang kacau, penuh dengan commit kosong, merge yang tidak perlu, dan pesan yang tidak bermakna, menjadi urutan perubahan signifikan yang jelas dan mudah dibaca. Dengan menggunakan rebase interaktif, menghapus commit uji coba, mengelompokkan pekerjaan yang tersebar, memperbarui branch secara linear, dan mengandalkan alat seperti reflog dan push paksa dengan `--force-with-lease`, Anda dapat menjaga repositori Anda dalam kondisi yang jauh lebih sehat dan profesional, selama Anda ingat untuk menerapkan teknik ini hanya pada branch yang berada di bawah kendali Anda dan memberi tahu tim sebelum menulis ulang riwayat bersama.