Saya memiliki tata letak repositori berikut:
- cabang utama (produksi)
- integrasi
- kerja
Apa yang ingin saya capai adalah memilih serangkaian komitmen dari cabang kerja dan menggabungkannya ke cabang integrasi. Saya cukup baru untuk git dan saya tidak tahu bagaimana tepatnya melakukan ini (memetik ceri rentang komit dalam satu operasi bukan penggabungan) tanpa mengacaukan repositori. Adakah petunjuk atau pemikiran tentang hal ini? Terima kasih!
git
git-merge
git-cherry-pick
orang gila
sumber
sumber
Jawaban:
Ketika datang ke berbagai komitmen, memetik ceri
adalahadalah tidak praktis.Seperti yang disebutkan di bawah oleh Keith Kim , Git 1.7.2+ memperkenalkan kemampuan untuk memilih cherry-pick sejumlah komitmen (tetapi Anda masih perlu menyadari konsekuensi memetik cherry untuk penggabungan di masa depan )
komentar damian dan memperingatkan kita:
Jika Anda ingin memilih kisaran
B
melaluiD
(inklusif) yang akanB^..D
.Lihat " Git membuat cabang dari rentang komit sebelumnya? " Sebagai ilustrasi.
Seperti Jubobs menyebutkan dalam komentar :
Catatan: pada Git 2.9.x / 2.10 (Q3 2016), Anda dapat memilih berbagai komit langsung pada cabang yatim (kepala kosong): lihat " Bagaimana membuat cabang yang ada menjadi yatim di git ".
Jawaban asli (Januari 2010)
A
rebase --onto
akan lebih baik, di mana Anda memutar ulang rentang komit yang diberikan di atas cabang integrasi Anda, seperti dijelaskan Charles Bailey di sini .(juga, cari "Inilah cara Anda mentransplantasikan cabang topik berdasarkan satu cabang ke cabang lain" di halaman manual git rebase , untuk melihat contoh praktis dari
git rebase --onto
)Jika cabang Anda saat ini adalah integrasi:
Itu akan memutar ulang semuanya antara:
first_SHA-1_of_working_branch_range
(karenanya~1
): komit pertama yang ingin Anda putar ulangintegration
" (yang menunjuk ke komit terakhir yang ingin Anda putar ulang, dariworking
cabang)ke "
tmp
" (yang menunjuk ke tempatintegration
menunjuk sebelumnya)Jika ada konflik ketika salah satu dari komitmen itu diputar ulang:
git rebase --continue
".git rebase --skip
"git rebase --abort
" (dan meletakkan kembaliintegration
cabang ditmp
cabang)Setelah itu
rebase --onto
,integration
akan kembali pada komit terakhir dari cabang integrasi (yaitutmp
cabang + "semua komitmen yang diputar ulang)Dengan memetik ceri atau
rebase --onto
, jangan lupa itu memiliki konsekuensi pada penggabungan berikutnya, seperti dijelaskan di sini .cherry-pick
Solusi " " murni dibahas di sini , dan akan melibatkan sesuatu seperti:Tapi bagaimanapun, ketika Anda perlu "memutar ulang" serangkaian commit, kata "replay" akan mendorong Anda untuk menggunakan fitur "
rebase
" Git.sumber
-m
opsi, bagaimana Anda menangani komitmen tersebut? Atau adakah cara untuk menyaring komitmen ini?-m
seharusnya menangani mereka untuk Anda, dengan memilih jalur utama yang dirujuk oleh-m
parameter yang telah Anda pilih untuk memetik ceri ini.-m
opsi hanya ketika hits komitmen orangtua ketika memilih berbagai komitmen melakukan ceri? Sekarang jika saya lulus-m
sepertigit cherry-pick a87afaaf..asfa789 -m 1
itu berlaku untuk semua komit dalam jangkauan.error: Commit 8fcaf3b61823c14674c841ea88c6067dfda3af48 is a merge but no -m option was given.
saya benar-benar menyadari bahwa Anda bisa sajagit cherry-pick --continue
dan itu akan baik-baik saja (tapi itu tidak termasuk komitmen orang tua)Pada git v1.7.2 cherry pick dapat menerima serangkaian commit:
sumber
cherry-pick A..B
tidak akan mendapatkan komit A (Anda akan perluA~1..B
untuk itu), dan jika ada konflik git tidak akan secara otomatis melanjutkan seperti rebase tidak (setidaknya pada 1.7.3.1)git cherry-pick A..B C
tidak berfungsi seperti yang Anda harapkan, secara naif. Itu tidak akan memilih semuanya dalam jangkauanA..B
dan berkomitmenC
! Untuk melakukan ini, Anda perlu dipecah menjadi dua baris, pertamagit cherry-pick A..B
dan kemudiangit cherry-pick C
. Jadi, setiap kali Anda memiliki jangkauan, Anda harus menjalankannya secara terpisah.Asumsikan bahwa Anda memiliki 2 cabang,
"branchA": termasuk komit yang ingin Anda salin (dari "commitA" ke "commitB"
"branchB": cabang yang Anda inginkan komit ditransfer dari "branchA"
1)
2) dapatkan ID dari "commitA" dan "commitB"
3)
4)
5) Jika Anda memiliki konflik, pecahkan dan ketik
untuk melanjutkan proses memetik ceri.
sumber
Anda yakin tidak ingin benar-benar menggabungkan cabang? Jika cabang kerja memiliki beberapa komitmen terbaru yang tidak Anda inginkan, Anda bisa membuat cabang baru dengan HEAD pada titik yang Anda inginkan.
Sekarang, jika Anda benar-benar ingin memilih berbagai komitmen, untuk alasan apa pun, cara yang elegan untuk melakukan ini adalah dengan hanya menarik tambalan dan menerapkannya ke cabang integrasi baru Anda:
Ini pada dasarnya adalah apa yang dilakukan git-rebase, tetapi tanpa perlu bermain game. Anda dapat menambahkan
--3way
untukgit-am
jika Anda perlu bergabung. Pastikan tidak ada file * .patch lain yang sudah ada di direktori tempat Anda melakukan ini, jika Anda mengikuti petunjuk secara verbatim ...sumber
A^
disertakanA
.Saya membungkus kode VonC menjadi skrip bash pendek
git-multi-cherry-pick
,, agar mudah dijalankan:Saya saat ini menggunakan ini ketika saya membangun kembali sejarah sebuah proyek yang memiliki kode pihak ketiga dan kustomisasi dicampur bersama dalam batang svn yang sama. Saya sekarang memisahkan kode inti pihak ke-3, modul-modul pihak ke-3, dan penyesuaian ke cabang git mereka sendiri untuk pemahaman yang lebih baik tentang penyesuaian yang akan dilakukan.
git-cherry-pick
membantu dalam situasi ini karena saya memiliki dua pohon di repositori yang sama, tetapi tanpa leluhur bersama.sumber
Semua opsi di atas akan meminta Anda untuk menyelesaikan konflik penggabungan. Jika Anda menggabungkan perubahan yang dilakukan untuk suatu tim, sulit untuk menyelesaikan konflik gabungan dari pengembang dan melanjutkan. Namun, "git merge" akan melakukan penggabungan dalam satu kesempatan tetapi Anda tidak dapat melewati berbagai revisi sebagai argumen. kita harus menggunakan perintah "git diff" dan "git apply" untuk melakukan penggabungan berbagai revs. Saya telah mengamati bahwa "git apply" akan gagal jika file patch memiliki diff untuk terlalu banyak file, jadi kita harus membuat patch per file dan kemudian menerapkan. Perhatikan bahwa skrip tidak akan dapat menghapus file yang dihapus di cabang sumber. Ini adalah kasus yang jarang terjadi, Anda dapat menghapus file seperti itu secara manual dari cabang target. Status keluar dari "git apply" bukan nol jika tidak dapat menerapkan tambalan,
Di bawah ini adalah skripnya.
sumber
Saya telah mengujinya beberapa hari yang lalu, setelah membaca penjelasan yang sangat jelas tentang Vonc.
Langkah saya
Mulailah
dev
: ABCDEFGHIJtarget
: ABCDE
atauH
Langkah-langkah untuk menyalin fitur tanpa langkah E dan H di cabang
dev_feature_wo_E_H
git checkout dev
git checkout -b dev_feature_wo_E_H
git rebase --interactive --rebase-merges --no-ff D
tempat saya meletakkandrop
depanE
danH
di editor rebasecommit
Langkah-langkah untuk menyalin cabang
dev_feature_wo_E_H
pada target.git checkout target
git merge --no-ff --no-commit dev_feature_wo_E_H
commit
Beberapa komentar
cherry-pick
pada hari-hari sebelumnyagit cherry-pick
kuat tetapi sederhanamerge
saya harus menyelesaikan konflik komit awal dan duplikat komit, jadi untuk satu atau duacherry-pick
, tidak apa-apa untuk "memetik ceri" tetapi untuk lebih banyak itu terlalu bertele-tele dan cabang akan menjadi terlalu kompleksgit rebase --onto
sumber
Pilihan lain mungkin untuk menggabungkan dengan strategi kita untuk komit sebelum rentang dan kemudian gabungan 'normal' dengan komit terakhir dari rentang itu (atau cabang ketika itu adalah yang terakhir). Jadi anggaplah hanya 2345 dan 3456 komit master yang akan digabung menjadi cabang fitur:
di cabang fitur:
sumber