Saya memiliki cabang yang disebut demo
yang perlu saya gabungkan dengan master
cabang. Saya bisa mendapatkan hasil yang diinginkan dengan perintah berikut:
git pull origin demo
git checkout master
git pull origin master
git merge demo
git push origin master
Satu-satunya kekhawatiran saya adalah, jika ada masalah penggabungan , saya ingin memberi tahu git
untuk menimpa perubahan di master
cabang tanpa memberi saya perintah penggabungan. Jadi pada dasarnya perubahan di demo
cabang harus secara otomatis menimpa perubahan di master
cabang.
Saya melihat sekeliling ada beberapa opsi tetapi saya tidak ingin mengambil risiko dengan penggabungan.
git push -f origin master
-f
opsi denganmerge
perintah dan bukan denganpush
perintahJawaban:
Tidak terlalu terkait dengan jawaban ini, tetapi saya akan membuang
git pull
, yang hanyagit fetch
diikuti olehgit merge
. Anda melakukan tiga penggabungan, yang akan membuat Git Anda menjalankan tiga operasi pengambilan, dan Anda hanya memerlukan satu pengambilan. Karenanya:Mengontrol penggabungan tersulit
Bagian yang paling menarik di sini adalah
git merge -X theirs
. Seperti yang dicatat root545 ,-X
opsi diteruskan ke strategi penggabungan, dan baikrecursive
strategi default maupunresolve
strategi alternatif mengambil-X ours
atau-X theirs
(satu atau yang lain, tetapi tidak keduanya). Namun, untuk memahami apa yang mereka lakukan, Anda perlu tahu bagaimana Git menemukan, dan memperlakukan, menggabungkan konflik .Konflik penggabungan dapat terjadi dalam beberapa file 1 ketika versi dasar berbeda dari versi saat ini (juga disebut lokal, HEAD, atau
--ours
) dan versi lain (juga disebut jarak jauh atau--theirs
) dari file yang sama. Artinya, penggabungan telah mengidentifikasi tiga revisi (tiga komit): basis, milik kita, dan milik mereka. Versi "base" adalah dari gabungan dasar antara komit kita dan komit mereka, seperti yang ditemukan di grafik komit (untuk lebih banyak lagi tentang ini, lihat posting StackOverflow lainnya). Git kemudian menemukan dua rangkaian perubahan: "apa yang kami lakukan" dan "apa yang mereka lakukan". Perubahan ini (secara umum) ditemukan baris demi baris, murni tekstualdasar. Git tidak benar-benar memahami isi file; itu hanya membandingkan setiap baris teks.Perubahan ini adalah apa yang Anda lihat dalam
git diff
keluaran, dan seperti biasa, mereka juga memiliki konteks . Mungkin saja hal-hal yang kita ubah berada pada baris yang berbeda dari hal-hal yang diubah, sehingga perubahan tersebut tampak seperti tidak akan bertabrakan, tetapi konteksnya juga telah berubah (misalnya, karena perubahan kita dekat dengan bagian atas atau bawah file, sehingga file tersebut habis dalam versi kami, tetapi dalam versi mereka, mereka juga menambahkan lebih banyak teks di bagian atas atau bawah).Jika perubahan terjadi di baris yang berbeda — misalnya, kami mengubah
color
kecolour
baris 17 dan berubahfred
kebarney
baris 71 - maka tidak ada konflik: Git hanya mengambil kedua perubahan tersebut. Jika perubahan terjadi pada baris yang sama, tetapi merupakan perubahan yang identik , Git akan mengambil satu salinan dari perubahan tersebut. Hanya jika perubahan berada pada baris yang sama, tetapi merupakan perubahan yang berbeda, atau kasus khusus dari konteks yang mengganggu, Anda mendapatkan konflik modifikasi / modifikasi.The
-X ours
dan-X theirs
pilihan memberitahu Git bagaimana menyelesaikan konflik ini, dengan memilih hanya salah satu dari dua perubahan: kita, atau mereka. Karena Anda mengatakan Anda menggabungkandemo
(milik mereka) kemaster
(milik kami) dan menginginkan perubahan daridemo
, Anda pasti menginginkannya-X theirs
.-X
Namun, penerapan secara membabi buta berbahaya. Hanya karena perubahan kami tidak bertentangan baris demi baris tidak berarti perubahan kami tidak benar-benar bertentangan! Satu contoh klasik terjadi dalam bahasa dengan deklarasi variabel. Versi dasar mungkin mendeklarasikan variabel yang tidak digunakan:Dalam versi kami, kami menghapus variabel yang tidak terpakai untuk membuat peringatan compiler pergi-dan mereka versi, mereka menambahkan satu lingkaran beberapa baris kemudian, menggunakan
i
sebagai loop counter. Jika kita menggabungkan dua perubahan tersebut, kode yang dihasilkan tidak lagi dapat dikompilasi. The-X
pilihan adalah tidak membantu di sini karena perubahan berada pada baris yang berbeda .Jika Anda memiliki rangkaian pengujian otomatis, hal terpenting yang harus dilakukan adalah menjalankan pengujian setelah penggabungan. Anda dapat melakukan ini setelah melakukan, dan memperbaikinya nanti jika diperlukan; atau Anda dapat melakukannya sebelum melakukan, dengan menambahkan
--no-commit
kegit merge
perintah. Kami akan menyerahkan detail untuk semua ini ke postingan lainnya.1 Anda juga bisa mendapatkan konflik sehubungan dengan operasi "file-wide", misalnya, mungkin kita memperbaiki ejaan kata dalam sebuah file (sehingga kita memiliki perubahan), dan mereka menghapus seluruh file (sehingga mereka memiliki menghapus). Git tidak akan menyelesaikan konflik ini dengan sendirinya, apa pun
-X
argumennya.Melakukan lebih sedikit penggabungan dan / atau penggabungan yang lebih cerdas dan / atau menggunakan rebase
Ada tiga penggabungan di kedua urutan perintah kami. Yang pertama adalah membawa
origin/demo
ke lokaldemo
(penggunaan Andagit pull
yang, jika Git Anda sangat tua, akan gagal diperbaruiorigin/demo
tetapi akan menghasilkan hasil akhir yang sama). Yang kedua adalahorigin/master
memasukkanmaster
.Tidak jelas bagi saya siapa yang memperbarui
demo
dan / ataumaster
. Jika Anda menulis kode Anda sendiri didemo
cabang Anda sendiri , dan orang lain menulis kode dan mendorongnya kedemo
cabangorigin
, maka penggabungan langkah pertama ini dapat menimbulkan konflik, atau menghasilkan penggabungan yang nyata. Lebih sering daripada tidak, lebih baik menggunakan rebase, daripada menggabungkan, untuk menggabungkan pekerjaan (memang, ini masalah selera dan pendapat). Jika demikian, Anda mungkin ingin menggunakannyagit rebase
. Di sisi lain, jika Anda tidak pernah melakukan komit Anda sendiri padademo
, Anda bahkan tidak perlu sebuahdemo
cabang. Atau, jika Anda ingin mengotomatiskan banyak hal ini, tetapi dapat memeriksa dengan cermat ketika ada commit yang dibuat oleh Anda dan orang lain, Anda mungkin ingin menggunakannya.git merge --ff-only origin/demo
: ini akan mempercepat Andademo
untuk mencocokkan yang diperbaruiorigin/demo
jika memungkinkan, dan langsung gagal jika tidak (pada titik mana Anda dapat memeriksa dua set perubahan, dan memilih penggabungan nyata atau rebase yang sesuai).Logika yang sama berlaku untuk
master
, meskipun Anda melakukan merge padamaster
, sehingga Anda pasti membutuhkanmaster
. Namun, lebih mungkin Anda ingin penggabungan gagal jika tidak dapat dilakukan sebagai fast-forward non-merge, jadi ini mungkin juga harus dilakukangit merge --ff-only origin/master
.Katakanlah Anda tidak pernah melakukan komitmen Anda sendiri
demo
. Dalam hal ini kita dapat membuang namademo
seluruhnya:Jika Anda sedang melakukan sendiri
demo
komit cabang, ini tidak membantu; Anda mungkin juga mempertahankan penggabungan yang ada (tetapi mungkin menambahkan--ff-only
tergantung pada perilaku apa yang Anda inginkan), atau beralih ke melakukan rebase. Perhatikan bahwa ketiga metode mungkin gagal: penggabungan mungkin gagal dengan konflik, penggabungan dengan--ff-only
mungkin tidak dapat maju cepat, dan rebase mungkin gagal dengan konflik (rebase bekerja dengan, pada dasarnya, melakukan pengambilan ceri , yang menggunakan penggabungan mesin dan karenanya bisa mendapatkan konflik gabungan).sumber
Saya mengalami masalah serupa, di mana saya perlu mengganti file apa pun yang mengalami perubahan / konflik dengan cabang yang berbeda secara efektif.
Solusi yang saya temukan adalah menggunakan
git merge -s ours branch
.Perhatikan bahwa opsi ini
-s
dan tidak-X
.-s
menunjukkan penggunaanours
sebagai strategi penggabungan tingkat atas,-X
akan menerapkanours
opsi kerecursive
strategi penggabungan, yang bukan yang saya (atau kami) inginkan dalam kasus ini.Langkah, di mana
oldbranch
cabang yang ingin Anda timpanewbranch
.git checkout newbranch
periksa cabang yang ingin Anda pertahankangit merge -s ours oldbranch
bergabung di cabang lama, tetapi menyimpan semua file kami.git checkout oldbranch
memeriksa cabang yang ingin Anda timpaget merge newbranch
bergabung di cabang baru, menimpa cabang lamasumber
Pendekatan penggabungan ini akan menambahkan satu komit di atasnya
master
yang menempel di apa pun yang ada di dalamnyafeature
, tanpa mengeluh tentang konflik atau omong kosong lainnya.Sebelum Anda menyentuh apapun
Sekarang persiapkan tuan
Dapatkan
feature
semua berpakaianPergi untuk membunuh
sumber
Changes from the other tree that do not conflict with our side are reflected in the merge result
. Itu tidak berhasil untuk saya, karena saya telah menggabungkan komit dengan rapi di cabang saya yang sedang ditimpa. Apakah ada cara lain?Anda dapat mencoba opsi "milik kami" di git merge,
sumber
demo
versinya lebih disukai meskipun dia bergabungmaster
. Ada-X theirs
juga, tetapi tidak jelas apakah ini yang sebenarnya diinginkan OP.ours
dilakukan saat menggunakan di backend dengan-s
opsi. Saat menggunakanours
dengan-X
: Ini membuang semua yang pohon lain lakukan, menyatakan sejarah kita berisi semua yang terjadi di dalamnya. sumberKetika saya mencoba menggunakan
-X theirs
dan sakelar perintah terkait lainnya, saya terus mendapatkan komit gabungan. Saya mungkin tidak memahaminya dengan benar. Salah satu alternatif yang mudah dipahami adalah menghapus cabang tersebut lalu melacaknya lagi.Ini sebenarnya bukan "penggabungan", tetapi inilah yang saya cari ketika saya menemukan pertanyaan ini. Dalam kasus saya, saya ingin menarik perubahan dari cabang jarak jauh yang didorong secara paksa.
sumber