Apa artinya memetik komitmen dengan Git?

2340

Baru-baru ini, saya telah diminta untuk cherry-pickberkomitmen.

Jadi, apa artinya memetik komitmen di git? Bagaimana Anda melakukannya?

Rahul
sumber
13
Alih-alih bergabung, dengan memetik kembali ceri dilakukan dari cabang ke cabang target (mis: master) lebih mudah.
Levent Divilioglu

Jawaban:

2859

Memetik ceri di Git berarti memilih komit dari satu cabang dan menerapkannya pada yang lain.

Ini berbeda dengan cara-cara lain seperti mergedan rebaseyang biasanya menerapkan banyak commit ke cabang lain.

  1. Pastikan Anda berada di cabang tempat Anda ingin menerapkan komit.

    git checkout master
    
  2. Jalankan yang berikut ini:

    git cherry-pick <commit-hash>
    

NB:

  1. Jika Anda memilih dari cabang publik, Anda harus mempertimbangkan untuk menggunakan

    git cherry-pick -x <commit-hash>
    

    Ini akan menghasilkan pesan komit standar. Dengan cara ini, Anda (dan rekan kerja Anda) masih dapat melacak asal komit dan dapat menghindari penggabungan konflik di masa mendatang.

  2. Jika Anda memiliki catatan yang terlampir pada komit, mereka tidak mengikuti cherry-pick. Untuk membawanya juga, Anda harus menggunakan:

    git notes copy <from> <to>
    

Tautan tambahan:

Philip Fourie
sumber
247
Jika Anda memilih dari cabang publik, Anda harus mempertimbangkan untuk menggunakan git cherry-pick -x <commit-hash>. Ini akan menghasilkan pesan komit standar. Dengan cara ini, Anda (dan rekan kerja Anda) masih dapat melacak asal komit dan dapat menghindari penggabungan konflik di masa mendatang.
MBober
2
Apakah memetik ceri benar-benar diperlukan? Tidak akankah reset campuran atau soft reset melakukan pekerjaan serupa?
Nav
10
Perhatikan bahwa jika Anda memiliki catatan yang melekat pada komit, mereka tidak mengikuti cherry-pick. Anda harus menggunakan git notes copy <from> <to>untuk membawanya juga.
Zitrax
5
git push adalah langkah terakhir untuk melakukan perubahan pada master
merasa baik dan pemrograman
58
FYI: Komit secara semantik berisi semua file dari pohon kerja saat itu (dan hash komit dari komit sebelumnya), jadi Anda tidak menerapkan komit keseluruhan ke komit lain, tetapi perubahan yang dilakukan komit pada komit sebelumnya "cherry-pick commit applies the changes introduced by the named commit on the current branch"Kebanyakan ppl cenderung menganggap komit sebagai perubahan (seperti svn adalah iirc), tetapi tidak, masing-masing komit mengacu pada pohon kerja yang lengkap. Meskipun ini tidak membuat perbedaan dalam kasus ini, ini dapat membantu dalam memahami mengapa git bekerja seperti itu.
Emile Vrijdags
314

Kutipan ini diambil dari; Kontrol Versi dengan Git (Buku yang benar-benar hebat, saya mendorong Anda untuk membelinya jika Anda tertarik pada git)

Sunting: Karena jawaban ini masih terkesan, saya ingin menambahkan tutorial video aksi yang sangat bagus tentangnya:

Youtube: Pengantar Git-pick ceri

Menggunakan git cherry-pick Komit git cherry-pick commit menerapkan perubahan yang diperkenalkan oleh komit bernama pada cabang saat ini. Ini akan memperkenalkan komitmen baru yang berbeda. Sebenarnya, menggunakan git cherry-pick tidak mengubah riwayat yang ada dalam repositori; alih-alih, itu menambah sejarah. Seperti operasi Git lainnya yang memperkenalkan perubahan melalui proses penerapan diff, Anda mungkin perlu menyelesaikan konflik untuk sepenuhnya menerapkan perubahan dari komit yang diberikan . Perintah git cherry-pick biasanya digunakan untuk memperkenalkan commit tertentu dari satu cabang dalam repositori ke cabang lain. Penggunaan yang umum adalah untuk memforward atau back-port melakukan dari cabang pemeliharaan ke cabang pengembangan.

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, above

sebelum: sebelum

setelah: setelah

Teoman shipahi
sumber
12
ketika komit yang dipetik diambil pada beberapa cabang (b1) dan kemudian dikirim ke master. Dan jika cabang b1 (dari mana komit awalnya dipetik) juga mencoba dikirim ke master. Bagaimana dengan konfliknya? Apakah itu dijaga atau bagaimana cara kerjanya?
parasrish
3
@parasrish Ya, mereka sudah diurus dengan penggabungan Anda sebelumnya. Jadi, Anda mengubah a, b, c, d dari cabang (b1). Anda ceri memilih hanya "c". Maka di masa mendatang begitu Anda bergabung dari (b1) menjadi master, karena perubahan "c" sama, itu hanya akan menggabungkan perubahan a, b, d, dan tetap "c". Tetapi jika Anda mengembalikan gabungan Anda, maka Anda akan kembali perubahan dengan "c" di dalamnya. Anda harus mengembalikannya secara terpisah.
Teoman shipahi
12
Harus ditekankan: Dalam contoh seperti yang diberikan, hanya perbedaan (F - E) yang diterapkan ke Z. Itu adalah kasus yang sempit. Cherry-pick dapat digunakan untuk menerapkan perbedaan komit ganda, katakanlah, semua perbedaan antara dua komit tidak berbatasan. Misalnya, mengikuti dari atas, (F - E), (E - D), (D - C), dan (C - B). Itu setara dengan menerapkan perbedaan (F - B).
Thomas Bitonti
2
Juga, apa yang terjadi jika Komit yang dipilih (F dalam contoh) memiliki lebih dari satu pendahulu langsung?
Thomas Bitonti
2
@ j2emanue dengan kata lain, cherry-pick hanya akan mengambil perubahan dari commit terakhir. Jika Anda melakukan 3 kali berbeda, dan jika Anda memilih yang terakhir, itu tidak akan mengubah komit pertama dan kedua. Perintah gabung akan mengambil semua perubahan Anda dan berlaku untuk cabang target (master) Anda.
Teoman shipahi
157

Memetik ceri di Git dirancang untuk menerapkan beberapa komit dari satu cabang ke cabang lainnya. Ini dapat dilakukan jika Anda mis. membuat kesalahan dan melakukan perubahan menjadi cabang yang salah, tetapi tidak ingin menggabungkan seluruh cabang. Anda bisa saja misalnya. kembalikan komit dan ambil-ceri di cabang lain.

Untuk menggunakannya, Anda hanya perlu git cherry-pick hash, di mana hashhash komit dari cabang lain.

Untuk prosedur lengkap, lihat: http://technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.html

Tadeck
sumber
96

Contoh singkat situasi, saat Anda membutuhkan cherry pick

Pertimbangkan skenario berikut. Anda memiliki dua cabang.

a) release1 - Cabang ini menuju ke pelanggan Anda, tetapi masih ada beberapa bug untuk diperbaiki.

b) master - cabang master klasik, di mana Anda dapat misalnya menambahkan fungsionalitas untuk release2.

SEKARANG : Anda memperbaiki sesuatu di rilis1 . Tentu saja Anda perlu perbaikan ini juga di master . Dan itu adalah kasus penggunaan khas untuk memetik ceri. Jadi cherry pick dalam skenario ini berarti bahwa Anda mengambil komit dari cabang release1 dan memasukkannya ke cabang master .

Daniel Perník
sumber
3
Anda mungkin hanya perlu cara lain. Anda memperbaiki bug di master dan Anda harus memilihnya untuk melepaskan1. Juga mereka mungkin repositori daripada cabang
canbax
1
Mengapa tidak menggunakan gabungan untuk itu?
FreeLightman
Saya akan: membuat rilis cabang, memperbaikinya di cabang, menggabungkan cabang dalam rilis, menggabungkan rilis di master.
Jasper-M
57

cherry-pick adalah fitur Git. Jika seseorang ingin melakukan komitmen tertentu dalam satu cabang ke cabang target, maka cherry-pick digunakan.
langkah git-pick ceri adalah seperti di bawah ini.

  1. checkout (beralih ke) cabang target.
  2. git cherry-pick <commit id>
    

    Di sini, komit id adalah id aktivitas cabang lain.Eg.

    git cherry-pick 9772dd546a3609b06f84b680340fb84c5463264f
    
  3. dorong ke cabang sasaran

Kunjungi https://git-scm.com/docs/git-cherry-pick

Vijay SB
sumber
44

Saya menyiapkan ilustrasi selangkah demi selangkah tentang apa yang dilakukan oleh cherry-pick - dan animasi dari ilustrasi ini (mendekati akhir).

  1. Sebelum cherry-picking
    (kita akan melakukan ceri-memilih dari komit Ldari cabang feature): masukkan deskripsi gambar di sini

  1. Mulai perintah git cherry-pick feature~2
    ( feature~2adalah 2 nd melakukan sebelum
    feature, yaitu komit L): masukkan deskripsi gambar di sini

  1. Setelah melakukan perintah ( git cherry-pick feature~2): masukkan deskripsi gambar di sini

Animasi yang sama: masukkan deskripsi gambar di sini


catatan:

Komit L'adalah dari sudut pandang pengguna (komit = snapshot) salinan persis komit L.

Secara teknis (internal), ini adalah komit baru, berbeda (karena mis. LBerisi pointer ke K(sebagai induknya), sementara L'berisi pointer ke E).

MarianD
sumber
Apakah ini berarti, L 'akan berupa N -> M -> L pada master cabang? atau secara eksklusif akan membawa komit L pada cabang utama
Priyank Thakkar
1
@PriyankThakkar, ya, secara eksklusif L , tidak ada yang lain (seperti yang dapat Anda lihat dari gambar / animasi).
MarianD
22

Anda dapat berpikir jika ceri memilih mirip dengan rebase, atau lebih tepatnya itu dikelola seperti rebase. Maksud saya, ini membutuhkan komit yang sudah ada dan regenerasi mengambil, sebagai titik awal, kepala cabang Anda saat ini.

A rebasemengambil komit yang memiliki induk X dan meregenerasi komit seolah-olah itu benar-benar memiliki orangtua Y, dan inilah tepatnya yang cherry-pickdilakukan oleh orangtua .

Cherry pick lebih banyak tentang bagaimana Anda memilih komit. Dengan pull(rebase), git secara implisit meregenerasi komit lokal Anda di atas apa yang ditarik ke cabang Anda, tetapi dengan cherry-pickAnda secara eksplisit memilih beberapa commit, dan secara implisit memperbanyaknya, di atas cabang Anda saat ini.

Jadi cara Anda melakukannya berbeda, tetapi di bawah tenda mereka adalah operasi yang sangat mirip - regenerasi dari komitmen.

Hugh
sumber
1
Saya menemukan ini menjadi pandangan yang sangat membantu. Ini menyiratkan mengapa cherry-pickberperilaku seperti itu ketika cabang target kemudian digabungkan kembali ke cabang sumber. Terima kasih Pak.
Aluan Haddad
3
Saya ingin menggunakan cherry pick daripada git merge setelah fitur selesai. setiap orang selalu melakukan git menggabungkan feature_branch ketika mereka menyelesaikan suatu fitur. mengapa tidak menggunakan perintah cherry-pick? apakah Anda punya pikiran? mengapa repot-repot menekan komitmen jika saya dapat memilih-ceri
j2emanue
11

Ini seperti Salin (dari suatu tempat) dan Tempel (ke suatu tempat), tetapi untuk komitmen tertentu.

Jika Anda ingin melakukan perbaikan terbaru, misalnya, maka Anda dapat menggunakan cherry-pickfitur ini.

Apakah Anda cherry-pickdi cabang pengembangan, dan mergeyang berkomitmen untuk cabang rilis. Demikian juga, lakukan cherry-pickdari cabang rilis ke master. Voila

Ajeet Sharma
sumber
11

Ketika Anda bekerja dengan tim pengembang pada suatu proyek, mengelola perubahan antara sejumlah cabang git bisa menjadi tugas yang kompleks. Terkadang Anda tidak ingin menggabungkan seluruh cabang menjadi yang lain, dan hanya perlu memilih satu atau dua komitmen tertentu. Proses ini disebut 'memetik ceri'.

Temukan artikel hebat tentang memetik ceri, periksa untuk detail lebih dalam: https://www.previousnext.com.au/blog/intro-cherry-picking-git

Wolfack
sumber
7

Jika Anda ingin menggabungkan tanpa melakukan id Anda dapat menggunakan perintah ini

git cherry-pick master~2 master~0

Perintah di atas akan menggabungkan tiga commit terakhir dari 1 menjadi 3

Jika Anda ingin melakukan ini untuk komit tunggal cukup hapus opsi terakhir

git cherry-pick master~2

Dengan cara ini Anda akan menggabungkan komit ke-3 dari ujung master.

Tagihan
sumber
Ini membingungkan. Saya pikir di sini Anda berada di cabang selain tuan, kan? Dan ketika Anda menyebutkan dua commit, Anda merujuk ke <from> dan <to> berkomitmen untuk menentukan rentang yang ingin Anda pilih. Benar? Akan sangat membantu jika skenario dijelaskan. Tambahan yang bagus. Terima kasih.
Saurabh Patil
6

Ini akan menerapkan komit tertentu ke cabang Anda saat ini.

Ini berarti :

  • semua file yang ditambahkan oleh komit ini akan ditambahkan
  • semua file yang dihapus oleh komit ini akan dihapus
  • semua file yang dimodifikasi oleh komit ini akan digabung. Ini berarti seluruh file dari komit, tidak hanya perubahan dari komit ini!

Mis: Pertimbangkan komit A

added newFileA
modified main:
+ import './newFileA'

komit B

added newFileB
modified main:
+ import './newFileB'

Jika Anda memilih cheri komit B di cabang lain, Anda akan berakhir dengan:

/newFileB
/main :
   import './newFileA'
   import './newFileB'

karena commit B mengandung newFileB dan main , tetapi tidak ada newFileA , menghasilkan bug, jadi gunakan dengan hati-hati.

mandelf
sumber
0

Kutipan dari dokumen resmi:

Diberi satu atau lebih komitmen yang ada, terapkan perubahan yang diperkenalkan masing-masing, dengan mencatat komitmen baru untuk masing-masing. Ini mengharuskan pohon kerja Anda bersih (tidak ada modifikasi dari komit HEAD).

Ketika tidak jelas cara menerapkan perubahan, hal berikut terjadi:

  1. Cabang saat ini dan penunjuk HEAD tetap pada komit terakhir berhasil dibuat.

  2. Ref CHERRY_PICK_HEAD diatur ke titik di komit yang memperkenalkan perubahan yang sulit diterapkan.

  3. Jalur di mana perubahan yang diterapkan bersih diperbarui di file indeks dan di pohon kerja Anda.

  4. Untuk jalur yang bertentangan, file indeks merekam hingga tiga versi, seperti yang dijelaskan di bagian "TRUE MERGE" pada git-merge. File pohon kerja akan menyertakan deskripsi konflik yang ditandai oleh penanda konflik biasa <<<<<<< dan >>>>>>>.

Tidak ada modifikasi lain yang dilakukan.

Baca lebih banyak...

Saikat
sumber