Saya sedang mencoba manuver git git cukup gemuk sekarang. Satu masalah yang saya temui adalah saya membuat beberapa perubahan pada beberapa kode di cabang saya, tetapi rekan saya memindahkan kode itu ke file baru di cabangnya. Jadi ketika saya melakukannya git merge my_branch his_branch
, git tidak memperhatikan bahwa kode pada file baru sama dengan yang lama, jadi tidak ada perubahan saya di sana.
Apa cara termudah untuk menerapkan perubahan saya lagi ke kode di file baru. Saya tidak akan memiliki terlalu banyak masalah mencari tahu komit yang perlu diterapkan kembali (saya hanya dapat menggunakan git log --stat
). Tapi sejauh yang saya tahu, tidak ada cara untuk mendapatkan git untuk mengajukan kembali perubahan ke file baru. Hal termudah yang saya lihat saat ini adalah secara manual mengajukan kembali perubahan, yang sepertinya bukan ide yang bagus.
Saya tahu bahwa git mengenali gumpalan, bukan file, jadi tentunya harus ada cara untuk mengatakannya, "terapkan perubahan kode persis ini dari komit ini, kecuali bukan di mana dulu tapi di mana sekarang berada di file baru ini".
--rename-threshold
opsi untuk mengubah jumlah kesamaan yang diperlukan.Jawaban:
Saya memiliki masalah serupa, dan saya mengatasinya dengan menghentikan pekerjaan saya agar sesuai dengan organisasi file target.
Katakanlah Anda memodifikasi
original.txt
pada cabang Anda (local
cabang), tetapi pada cabang master,original.txt
telah disalin ke yang lain, katakanlahcopy.txt
. Salinan ini telah dilakukan dalam komit yang kami beri nama komitCP
.Anda ingin menerapkan semua perubahan lokal Anda, melakukan
A
dan diB
bawah, yang dilakukan padaoriginal.txt
, ke file barucopy.txt
.Buat cabang sekali pakai
move
pada titik awal perubahan Anda dengangit branch move X
. Artinya, letakkanmove
cabang di komitX
, yang di depan komit yang ingin Anda gabungkan; kemungkinan besar, ini adalah komitmen tempat Anda bercabang untuk mengimplementasikan perubahan Anda. Seperti yang dilakukan oleh pengguna @digory doo di bawah ini, Anda dapat melakukannyagit merge-base master local
untuk menemukannyaX
.Di cabang ini, buat perintah penggantian nama berikut:
Ini mengganti nama file. Perhatikan bahwa
copy.txt
belum ada di pohon Anda pada saat ini.Komit perubahan Anda (kami beri nama komit ini
MV
).Anda sekarang dapat menyusun ulang pekerjaan Anda di atas
move
:Ini seharusnya bekerja tanpa masalah, dan perubahan Anda diterapkan
copy.txt
di cabang lokal Anda.Sekarang, Anda tidak perlu ingin atau perlu memiliki komit
MV
dalam sejarah cabang utama Anda, karena operasi pemindahan dapat menyebabkan konflik dengan operasi penyalinan saat komitCP
di cabang utama.Anda hanya perlu mengubah kembali pekerjaan Anda, membuang operasi pemindahan, sebagai berikut:
... di mana
CP
komit di manacopy.txt
diperkenalkan di cabang lain. Ini mengubah semua perubahancopy.txt
di atasCP
komit. Sekarang,local
cabang Anda persis seperti Anda selalu dimodifikasicopy.txt
dan tidakoriginal.txt
, dan Anda dapat terus bergabung dengan yang lain.Penting bahwa perubahan diterapkan
CP
atau tidakcopy.txt
akan ada dan perubahan akan diterapkan kembalioriginal.txt
.Semoga ini jelas. Jawaban ini datang terlambat, tetapi ini mungkin berguna bagi orang lain.
sumber
patch
(yang melibatkan juga banyak pekerjaan), dan itulah mengapa saya pikir mungkin menarik untuk menunjukkannya. Juga, perhatikan bahwa saya mengambil lebih banyak waktu untuk menulis jawaban daripada benar-benar menerapkan perubahan, dalam kasus saya. Pada langkah mana Anda akan merekomendasikan menggunakan penggabungan? dan mengapa? Satu-satunya perbedaan yang saya lihat adalah dengan rebasing, saya membuat komit sementara yang kemudian dibuang (komitMV
), yang tidak mungkin dengan penggabungan saja.Anda selalu dapat menggunakan
git diff
(ataugit format-patch
) untuk membuat tambalan, lalu pergi secara manual mengedit nama file di tambalan, dan menerapkannya dengangit apply
(ataugit am
).Singkatnya, satu-satunya cara itu akan bekerja secara otomatis adalah jika deteksi ganti nama git dapat mengetahui bahwa file lama dan baru adalah hal yang sama - yang sepertinya tidak benar-benar ada dalam kasus Anda, hanya sebagian saja. Memang benar bahwa git menggunakan gumpalan, bukan file, tetapi gumpalan hanyalah isi dari seluruh file, tanpa nama file dan metadata terlampir. Jadi, jika Anda memiliki sepotong kode yang dipindahkan di antara dua file, mereka tidak benar-benar gumpalan yang sama - sisa konten gumpalan itu berbeda, hanya potongan yang sama.
sumber
git format-patch
komit. Jika saya lakukangit format-patch SHA1
, itu menghasilkan sejumlah besar file tambalan untuk seluruh sejarah. Tapi saya kiragit show SHA1 > diff.patch
akan berhasil juga.-1
opsi. Mode operasi normal untuk format-patch adalah rentang revisi, sepertiorigin/master..master
, jadi Anda dapat dengan mudah menyiapkan seri tambalan.git apply
dangit am
terlalu pemilih, karena mereka ingin nomor baris yang sama. Tetapi saya saat ini sedang sukses denganpatch
perintah UNIX .Berikut adalah solusi penggabungan menghadapi konflik gabungan dengan penggantian nama dan edit serta menyelesaikannya dengan mergetool mengenali 3 file sumber gabungan yang benar.
Setelah penggabungan gagal karena 'file terhapus' yang Anda sadari telah diubah namanya dan diedit:
Walk-through:
Buat file.txt:
Buat cabang tempat Anda akan mengedit nanti:
Buat ganti nama dan edit pada master:
Tukar ke cabang, dan edit di sana juga:
Coba gabungkan master:
Perhatikan bahwa konflik tersebut sulit diselesaikan - dan file-file diubah namanya. Batalkan, meniru nama:
Coba gabungkan lagi:
Bagus! Menggabungkan menghasilkan konflik 'normal' yang dapat diselesaikan dengan mergetool:
sumber
B.txt -> C.txt
danA.txt -> B.txt
dengan git mv, dan git tidak dapat secara otomatis mencocokkan konflik gabungan dengan benar (mendapatkan konflik gabungan antara yang lamaB.txt
dan yang baruB.txt
). Dengan menggunakan metode ini, konflik gabungan sekarang berada di antara file yang benar.