Jika saya ingin bergabung menjadi cabang Git, perubahan hanya dilakukan pada beberapa file yang diubah dalam komit tertentu yang mencakup perubahan pada banyak file, bagaimana hal ini dapat dicapai?
Misalkan Git komit disebut stuff
memiliki perubahan ke file A
, B
, C
, dan D
tapi saya ingin menggabungkan hanya stuff
's perubahan ke file A
dan B
. Kedengarannya seperti pekerjaan git cherry-pick
tetapi cherry-pick
hanya tahu cara menggabungkan seluruh komit, bukan bagian dari file.
sumber
git checkout .
saya akan merekomendasikan jugagit clean -f
untuk menghapus file baru tapi tidak diinginkan yang diperkenalkan oleh komit pilihan ceri.git add -p
yang memungkinkan Anda memutuskan secara interaktif perubahan yang ingin Anda tambahkan ke indeks per filegit reset -p HEAD
. Ini sama denganadd -p
tetapi sangat sedikit yang tahu bahwa itu ada.Metode lain tidak berfungsi untuk saya karena komit memiliki banyak perubahan dan konflik ke banyak file lainnya. Apa yang saya pikirkan adalah sederhana
Sebenarnya bukan
add
file atau melakukan komit untuk Anda sehingga Anda mungkin perlu menindaklanjutinyaAtau jika Anda ingin melewatkan add Anda dapat menggunakan
--cached
argumen untukgit apply
Anda juga dapat melakukan hal yang sama untuk seluruh direktori
sumber
show SHA -- file | apply
pada dasarnya tidakkah melakukan hal yang samacheckout SHA -- file
seperti dalam jawaban Mark Longair ?checkout SHA -- file
akan checkout persis versi di SHA, sementarashow SHA -- file | apply
hanya akan menerapkan perubahan di SHA (seperti halnya cherry-pick). Itu penting jika (a) ada lebih dari satu komit yang mengubah file yang diberikan di cabang sumber, atau (b) ada komit yang mengubah file di cabang target Anda saat ini.git revert
membatalkan seluruh komit). Dalam hal ini gunakan sajagit show -R SHA -- file1.txt file2.txt | git apply -
git diff SHA -- file1.txt file2.txt | git apply -
berarti menerapkan semua perbedaan antara versi file saat ini dan versi di SHA ke versi saat ini. Pada dasarnya itu sama dengangit checkout SHA -- file1.txt file2.txt
. Lihat komentar saya sebelumnya untuk mengapa itu berbeda dengangit show
versi apa .git apply -3 -
bukan hanyagit apply -
, maka jika konflik terjadi, Anda dapat menggunakan teknik resolusi konflik standar Anda, termasuk menggunakangit mergetool
.Saya biasanya menggunakan
-p
bendera dengan checkout git dari cabang lain yang saya temukan lebih mudah dan lebih rinci daripada kebanyakan metode lain yang saya temui.Pada prinsipnya:
contoh:
Anda kemudian mendapatkan dialog yang menanyakan perubahan yang Anda inginkan di "gumpalan" ini cukup berhasil untuk setiap potongan perubahan kode kontinu yang kemudian Anda dapat memberi sinyal
y
(Ya)n
(Tidak) dll untuk setiap potongan kode.The
-p
ataupatch
pilihan bekerja untuk berbagai perintah dalam git termasukgit stash save -p
yang memungkinkan Anda untuk memilih apa yang ingin Anda menyimpan dari pekerjaan Anda saat iniSaya kadang-kadang menggunakan teknik ini ketika saya telah melakukan banyak pekerjaan dan ingin memisahkannya dan melakukan lebih banyak komit berdasarkan topik menggunakan
git add -p
dan memilih apa yang saya inginkan untuk setiap komit :)sumber
git-add -p
, tetapi saya tidak tahugit-checkout
juga memiliki-p
bendera - apakah itu memperbaiki masalah penggabungan yang dimiliki non--p
jawaban ?-p
akan memungkinkan untuk mengedit manual untuk bagian yang saling bertentangan, yangcherry-pick
mungkin juga akan menghasilkan pula. Saya akan menguji ini kali berikutnya saya membutuhkannya, pasti pendekatan yang menarikgit reset -p HEAD
juga memungkinkan-p
yang dapat berhenti berguna ketika Anda hanya ingin menghapus beberapa tambalan dari indeks.Mungkin keuntungan dari metode ini daripada jawaban Jefromi adalah bahwa Anda tidak harus mengingat perilaku reset git mana yang benar :)
sumber
cherry-pick
dan langsung menggunakangit checkout stuff -- A B
? Dan dengangit commit -C stuff
pesan komit akan tetap sama jugastuff
belum dimodifikasi pada cabang Anda saat ini atau di mana saja di antara leluhur umumHEAD
danstuff
dan ujungstuff
. Jika sudah, makacherry-pick
buat hasil yang benar (pada dasarnya hasil penggabungan), sementara metode Anda akan membuang perubahan di cabang saat ini, dan menjaga semua perubahan dari leluhur bersama hinggastuff
- tidak hanya yang di dalam komit tunggal.stuff
sehingga hasil dari cherry pick akan pergiA
danB
dengan konten yang berbeda dari konten mereka di komitstuff
. Namun, jika itu akan sama, Anda benar - Anda bisa melakukan apa yang Anda katakan.Cherry pick adalah untuk memilih perubahan dari "komit" tertentu. Solusi paling sederhana adalah dengan memilih semua perubahan file tertentu untuk digunakan
Sebagai contoh:
Sumber dan penjelasan lengkap http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
MEMPERBARUI:
Dengan metode ini, git tidak akan MERGE file, itu hanya akan mengesampingkan perubahan lain yang dilakukan pada cabang tujuan. Anda harus menggabungkan perubahan secara manual:
sumber
Situasi:
Anda berada di cabang Anda, katakanlah
master
dan Anda memiliki komitmen Anda pada cabang lain. Anda harus memilih hanya satu file dari komit tertentu.Pendekatan:
Langkah 1: Checkout di cabang yang diperlukan.
Langkah 2: Pastikan Anda telah menyalin hash komit yang diperlukan.
Langkah 3: Sekarang Anda memiliki perubahan file yang diperlukan pada cabang yang Anda inginkan. Anda hanya perlu menambahkan dan mengkomitnya.
sumber
Saya hanya akan memilih semuanya, lalu melakukan ini:
Lalu saya akan mengembalikan perubahan yang tidak saya inginkan, lalu membuat komit baru.
sumber
Gunakan
git merge --squash branch_name
ini akan mendapatkan semua perubahan dari cabang lain dan akan menyiapkan komitmen untuk Anda. Sekarang hapus semua perubahan yang tidak dibutuhkan dan tinggalkan yang Anda inginkan. Dan git tidak akan tahu bahwa ada penggabungan.sumber
Saya menemukan cara lain yang mencegah penggabungan yang saling bertentangan pada memetik ceri yang IMO agak mudah diingat dan dipahami. Karena Anda sebenarnya tidak memilih cherry pick, tetapi menjadi bagian darinya, Anda harus membaginya terlebih dahulu dan kemudian membuat commit yang sesuai dengan kebutuhan Anda dan memilih cherry-pick.
Pertama buat cabang dari komit yang ingin Anda bagi dan checkout:
Kemudian kembalikan komit sebelumnya:
Kemudian tambahkan file / perubahan yang ingin Anda pilih:
dan lakukan itu:
perhatikan hash komit, sebut saja PICK-SHA dan kembali ke cabang utama Anda, master misalnya memaksa checkout:
dan ceri-pilih komit:
sekarang Anda dapat menghapus cabang temp:
sumber
Gabungkan cabang menjadi yang baru (squash) dan hapus file yang tidak diperlukan:
sumber
Demi kelengkapan, yang terbaik bagi saya adalah:
Ia melakukan persis seperti yang diinginkan OP. Itu resolusi konflik ketika diperlukan, sama bagaimana
merge
melakukannya. Ituadd
tetapi tidakcommit
perubahan baru Anda.sumber
Kamu bisa menggunakan:
Notasi
<commit>^
menentukan induk (pertama) dari<commit>
. Oleh karena itu, perintah diff ini mengambil perubahan yang dilakukan<path>
dalam komit<commit>
.Perhatikan bahwa ini belum akan melakukan apa pun (seperti
git cherry-pick
halnya). Jadi jika Anda menginginkannya, Anda harus melakukan:sumber