Rebase dan merge bekerja dengan satuan branch — seluruh rangkaian commit dipindahkan atau digabungkan sekaligus. Sering kali yang dibutuhkan jauh lebih kecil: satu perbaikan salah ketik yang kebetulan dibuat di main, sementara branch release yang lebih tua juga membutuhkannya. git cherry-pick mengambil commit pilihan — satu hash, atau sebuah rentang — lalu menerapkannya di branch aktif sebagai commit baru, tanpa merge dan tanpa membawa branch lainnya. Chapter ini membuktikan tiga sifat pentingnya secara nyata: commit hasilnya ber-hash beda, isinya sama persis, dan prosesnya tetap harus melewati konflik bila ada tabrakan.
Repositori Latihan #
release dipotong dari main sebelum dua hal terjadi: sebuah rilis versi 1.0 di release, dan sebuah perbaikan salah ketik di main. Klasiknya alur hotfix — perbaikan muncul di satu tempat, dibutuhkan di tempat lain:
mkdir latihan-cherry && cd latihan-cherry
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf 'beranda\n' > situs.md
git add situs.md
git commit -m "Buat kerangka situs"
printf '[email protected]\n' > kontak.md
git add kontak.md
git commit -m "Tambah halaman kontak"
git switch -c release
printf 'versi 1.0\n' > versi.md
git add versi.md
git commit -m "Rilis versi 1.0"
git switch main
printf '[email protected]\n' > kontak.md
git add kontak.md
git commit -m "Perbaiki salah ketik di kontak"
git switch release
git log --oneline --graph --allOutput yang Dihasilkan:
* 01e14e8 Perbaiki salah ketik di kontak
| * 9a6d757 Rilis versi 1.0
|/
* cfab6aa Tambah halaman kontak
* 051264e Buat kerangka situsPerhatikan salah ketiknya: exmaple. Commit perbaikan ada di ujung main (hash 01e14e8 di mesin kita), sementara release membawa versi kontak.md yang masih salah.
Mengambil Satu Commit #
Dari release, terapkan commit perbaikan itu dengan hash pendeknya (hash di mesin Anda berbeda — salin dari git log milik Anda):
git cherry-pick 01e14e8Output yang Dihasilkan:
[release bbdc48a] Perbaiki salah ketik di kontak
Date: Wed Oct 21 10:30:00 2026 +0700
1 file changed, 1 insertion(+), 1 deletion(-)Bedah keluarannya baris demi baris: [release bbdc48a] mengumumkan commit baru lahir di branch release dengan hash bbdc48a; subjeknya menyalin commit asal, Perbaiki salah ketik di kontak. Baris Date: menampilkan tanggal penulis asli — bukti author date dipertahankan, hanya tanggal committer yang baru. Terakhir, 1 file changed, 1 insertion(+), 1 deletion(-) adalah diffstat perbaikan yang sama. Bentuk grafnya:
git log --oneline --graph --allOutput yang Dihasilkan:
* bbdc48a Perbaiki salah ketik di kontak
* 9a6d757 Rilis versi 1.0
| * 01e14e8 Perbaiki salah ketik di kontak
|/
* cfab6aa Tambah halaman kontak
* 051264e Buat kerangka situsDua baris Perbaiki salah ketik di kontak kini berdiri di dua branch dengan hash berbeda — 01e14e8 di main, bbdc48a di release.
Hash Beda, Isi Sama #
Bukti terkuat datang dari membandingkan kedua commit secara langsung:
git show 01e14e8Output yang Dihasilkan:
commit 01e14e896c6be14aee856152d9521e89b0ebe9fd
Author: Budi Santoso <[email protected]>
Date: Wed Oct 21 10:30:00 2026 +0700
Perbaiki salah ketik di kontak
diff --git a/kontak.md b/kontak.md
index f7f04d6..0759f3f 100644
--- a/kontak.md
+++ b/kontak.md
@@ -1 +1 @@
[email protected]
[email protected]git show bbdc48aOutput yang Dihasilkan:
commit bbdc48a19d5eaf74001c04e621dd4afcad019397
Author: Budi Santoso <[email protected]>
Date: Wed Oct 21 10:30:00 2026 +0700
Perbaiki salah ketik di kontak
diff --git a/kontak.md b/kontak.md
index f7f04d6..0759f3f 100644
--- a/kontak.md
+++ b/kontak.md
@@ -1 +1 @@
[email protected]
[email protected]Kedua keluaran identik — penulis, tanggal, pesan, hingga diff exmaple menjadi example — kecuali satu baris: commit 01e14e8... berbanding commit bbdc48a.... Itulah kontrak cherry-pick: Git tidak menyalin objek commit lama, melainkan menerapkan patch-nya pada posisi baru sehingga parent, dan otomatis hash, ikut berubah. Isi berkasnya kini sama di kedua branch — verifikasi cepat: git diff main release -- kontak.md tidak mencetak apa pun.
Rentang Commit: cherry-pick A..B #
Satu commit bisa; beberapa commit sekaligus juga bisa. main mendapat dua halaman baru setelah perbaikan tadi:
git switch main
printf 'faq\n' > faq.md
git add faq.md
git commit -m "Tambah halaman faq"
printf 'tentang\n' > tentang.md
git add tentang.md
git commit -m "Tambah halaman tentang"
git switch release
git cherry-pick main~2..mainOutput yang Dihasilkan:
[release 2d942b3] Tambah halaman faq
Date: Wed Oct 21 10:40:00 2026 +0700
1 file changed, 1 insertion(+)
create mode 100644 faq.md
[release 8337406] Tambah halaman tentang
Date: Wed Oct 21 10:45:00 2026 +0700
1 file changed, 1 insertion(+)
create mode 100644 tentang.mdSintaks rentangnya sama dengan rentang pada git log: main~2..main berarti “commit setelah main~2 sampai main” — dua commit terakhir main, tidak termasuk main~2 itu sendiri. Cherry-pick menerapkannya berurutan, sehingga keluarannya dua blok ringkasan commit.
Riwayat setelah rentang:
git log --oneline --graph --allOutput yang Dihasilkan:
* 8337406 Tambah halaman tentang
* 2d942b3 Tambah halaman faq
* bbdc48a Perbaiki salah ketik di kontak
* 9a6d757 Rilis versi 1.0
| * 4fb1d9c Tambah halaman tentang
| * 407a5ec Tambah halaman faq
| * 01e14e8 Perbaiki salah ketik di kontak
|/
* cfab6aa Tambah halaman kontak
* 051264e Buat kerangka situsKedua halaman kini ada di release — sebagai commit berhash baru 2d942b3 dan 8337406, kembaran dari 407a5ec dan 4fb1d9c milik main.
–no-commit: Stage Saja, Tanpa Commit #
Kadang patch ingin digabungkan ke commit lain yang sedang disiapkan, bukan berdiri sendiri. --no-commit menerapkan perubahan hanya sampai staging area:
git switch main
printf 'beranda\njudul baru\n' > situs.md
git add situs.md
git commit -m "Ubah judul beranda"
git switch release
git cherry-pick --no-commit main
git statusOutput yang Dihasilkan:
On branch release
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: situs.mdsitus.md tampil di Changes to be committed — perubahan siap di-commit, tapi belum menjadi commit. Kita boleh menyusun pesan sendiri, menggabungkannya dengan perubahan lain yang di-stage, atau membatalkan dengan git restore --staged situs.md. Di latihan ini, komit dengan pesan versi kita sendiri:
git commit -m "Ambil judul beranda ke release"Output yang Dihasilkan:
[release 3e2b8da] Ambil judul beranda ke release
1 file changed, 1 insertion(+)Konflik Saat Cherry-Pick #
Tabrakan tetap mungkin: penerapan patch adalah merge tiga arah, sama seperti chapter Merge Conflicts
. Repositori kedua menyediakannya — release menaikkan harga kopi dan gula sendiri, lalu keputusan resmi harga kopi di main juga ingin diambil:
mkdir latihan-cherry-konflik && cd latihan-cherry-konflik
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 release
printf 'kopi: 1500\n\ngula: 700\n' > harga.md
git add harga.md
git commit -m "Naikkan harga kopi dan gula di release"
git switch main
printf 'kopi: 1200\n\ngula: 500\n' > harga.md
git add harga.md
git commit -m "Naikkan harga kopi jadi 1200"
git switch release
git cherry-pick mainOutput yang Dihasilkan:
Auto-merging harga.md
CONFLICT (content): Merge conflict in harga.md
error: could not apply 5ff037e... Naikkan harga kopi jadi 1200
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
hint: Disable this message with "git config advice.mergeConflict false"Blok hint:-nya khas cherry-pick: git cherry-pick --continue, --skip, dan --abort — panel kendali dari chapter Abort dan Continue Rebase
, versi cherry-pick. Berkasnya membawa penanda konflik yang sudah dikenal:
cat harga.mdOutput yang Dihasilkan:
<<<<<<< HEAD
kopi: 1500
=======
kopi: 1200
>>>>>>> 5ff037e (Naikkan harga kopi jadi 1200)
gula: 700Sisi HEAD (1500) adalah harga versi release; sisi bawah (1200) patch dari main. Keputusan bisnisnya: harga kopi mengikuti keputusan resmi main, harga gula tetap 700 milik release. Setelah resolve dan git add, git cherry-pick --continue melahirkannya (editor pesan terbuka berisi pesan asli Naikkan harga kopi jadi 1200 — simpan lalu tutup; di sini dijalankan dengan GIT_EDITOR=: agar otomatis diterima):
printf 'kopi: 1200\n\ngula: 700\n' > harga.md
git add harga.md
git cherry-pick --continueOutput yang Dihasilkan:
[release 9cb9342] Naikkan harga kopi jadi 1200
Date: Wed Oct 21 11:25:00 2026 +0700
1 file changed, 1 insertion(+), 1 deletion(-)git log --oneline --graph --allOutput yang Dihasilkan:
* 9cb9342 Naikkan harga kopi jadi 1200
* ee5ea54 Naikkan harga kopi dan gula di release
| * 5ff037e Naikkan harga kopi jadi 1200
|/
* 2ec53cb Buat daftar hargaCommit 9cb9342 lahir di release membawa keputusan main — tanpa merge commit, tanpa parent kedua. Pola inilah yang dipakai alur hotfix ke branch rilis
: perbaikan dibuat sekali, diterapkan ke branch yang membutuhkan.
Sekilas: git cherry -v, Jangan Tertukar #
Satu perintah mirip nama yang sering tertukar: git cherry -v. Perintah ini tidak mengambil commit apa pun — ia membandingkan commit mana milik sebuah head yang belum ada di upstream, dengan patch-id sebagai pembandingnya:
git cherry -v main releaseOutput yang Dihasilkan (di latihan-cherry):
+ 9a6d757014bb70733e5bf9302a8bf4fbe91e3ca1 Rilis versi 1.0
- bbdc48a19d5eaf74001c04e621dd4afcad019397 Perbaiki salah ketik di kontak
- 2d942b3c24fcd5e3361bdad3846dc0d8192ed3a7 Tambah halaman faq
- 83374065d85f5ba640b7aa7444b7012bae464e9a Tambah halaman tentang
- 3e2b8da823fde3f6d6c89233b99bc8ecc6a4c3ef Ambil judul beranda ke releaseSetiap baris berawalan + atau -: + berarti patch commit itu belum ada di main (misalnya Rilis versi 1.0 milik release), - berarti patch setaranya sudah ada. Empat commit hasil cherry-pick tadi bertanda - — bukti otomatis bahwa isinya memang sudah terwakili di main. Detail keduanya ada di git-cherry-pick
dan git-cherry
.
Cherry-pick menambah riwayat — commit baru lahir, commit lama tak tersentuh. Karakter itu membuatnya aman dipakai di branch mana pun, termasuk yang shared. Bagaimana bila kebutuhannya kebalikan: menghapus perubahan yang sudah ter-commit, tanpa menghapus riwayatnya? Jawabannya adalah commit pembalik — Revert .