Karena percabangan murah dengan Git, mengapa tidak melakukan checkout salinan dan kemudian Anda tidak perlu melakukan dry run? Anda bisa membuang salinannya sesudahnya.
Ini bagus, tetapi masih akan mengubah copy pekerjaan Anda. Jika repo Anda adalah server web langsung, maka Anda bisa menyajikan file dengan konflik di.
dave1010
21
Anda tidak bisa benar-benar melakukan penggabungan tanpa memengaruhi copy pekerjaan.
mipadi
55
Benar, tetapi sesuatu seperti git merge --only-if-there-wont-be-any-conflictsatau git diff --show-conflicts <commit>akan sangat berguna. Malu itu belum mungkin, atau apakah saya kehilangan sesuatu?
dave1010
344
@ dave1010 Anda seharusnya tidak pernah menangani penggabungan pada server web langsung !!! Untuk itulah kotak pengembangan Anda! Perbaiki cabang "prod" dan kemudian dorong ke server web nyata.
jpswain
52
Jika Anda bekerja di server langsung / produksi, Anda tidak ingin melakukan apa pun kecuali git pull --ff-only!
ThiefMaster
237
Saya hanya perlu mengimplementasikan metode yang secara otomatis menemukan konflik antara repositori dan remote-nya. Solusi ini melakukan penggabungan dalam memori sehingga tidak akan menyentuh indeks, atau pohon yang berfungsi. Saya pikir ini adalah cara teraman yang mungkin Anda bisa menyelesaikan masalah ini. Begini cara kerjanya:
Ambil remote ke repositori Anda. Sebagai contoh:
git fetch origin master
Jalankan git merge-tree: git merge-tree mergebase master FETCH_HEAD( mergebase adalah id heksadesimal yang digabungkan-basis dicetak pada langkah sebelumnya)
Sekarang anggaplah Anda ingin menggabungkan master jarak jauh dengan master lokal Anda, tetapi Anda bisa menggunakan cabang apa pun. git merge-treeakan menjalankan gabungan dalam memori dan mencetak hasilnya ke output standar. Grep untuk polanya <<atau >>. Atau Anda dapat mencetak output ke file dan memeriksanya. Jika Anda menemukan garis yang dimulai dengan 'diubah di keduanya' maka kemungkinan besar akan ada konflik.
Jawaban ini diremehkan, IMHO, karena ini solusi bersih tanpa menyentuh copy pekerjaan atau indeks.
sschuberth
23
BTW, langkah 2 dan 3 dapat digabung menjadi satu langkah, menggunakan operator backtick dari konsol Linux, yang mengevaluasi di tempat isinya:git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
jakub.g
15
Tambahkan ke [alias] di .gitconfig: dry = "! F () {git merge-tree` git merge-base $ 2 $ 1` $ 2 $ 1;}; f "# tandai bagaimana penggabungan dev menjadi master akan berjalan: git dry dev master
Noel
8
Baris GIT favorit saya: Luar git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"biasa! +100
Rudie
4
Dalam pengujian ini, saya menemukan grepping untuk penggabungan flag 'perubahan di kedua' di mana kedua cabang memodifikasi file yang sama, bahkan jika keduanya tidak menghasilkan konflik penggabungan. Untuk mengidentifikasi hanya konflik yang sebenarnya, saya merasa perlu untuk melakukan grep untuk markup konflik yang dimulai seperti ini:, +<<<<<<< .ourjadi saya menggunakan ekspresi grep sepertigrep -q '^+<* \.our$'
Guy
55
Solusi brute force sederhana saya untuk ini adalah:
Buat cabang "pra-master" (dari master tentu saja)
Gabungkan semua hal yang Anda inginkan ke dalam pre-master ini.
Kemudian Anda bisa melihat bagaimana penggabungan terjadi tanpa menyentuh master.
Gabungkan pre-master menjadi master ATAU
Gabungkan semua cabang yang dirilis wannabe menjadi master
Bagaimanapun, saya akan mengikuti saran @ orange80.
Saya suka solusi @akostajti, tapi ini adalah pilihan lain yang diremehkan. Sebenarnya saya lebih suka bersikap defensif dan membuat cabang temp baru (tentu saja hanya ketika saya mengharapkan konflik, kalau tidak akan menjadi berlebihan), dan jika ada yang salah, cukup hapus saja.
jakub.g
1
tidak tahu apakah ini solusi "kotor" atau tidak, tetapi itu benar-benar berhasil. Saya suka itu! (Y)
sara
3
Ini harus menjadi solusi yang diterima, imo. Cepat, mudah, aman, dapat dibalik, intuitif, dan selama tidak ada perubahan yang tidak dikomit sebelum Anda mulai, itu tidak akan memiliki efek samping.
Bob Ray
3
Solusi ini memberi tahu Anda tidak mengerti cara kerja git. Branch hanya pointer dan Anda hanya membuat pointer yang redundan. Anda memiliki firasat buruk bahwa Anda entah bagaimana bisa melukai penggabungan cabang Anda tetapi Anda tidak bisa. Anda selalu dapat melakukannya git merge --abortjika ada konflik, git reset --hard HEAD~1apakah ada gabungan atau git reset --hard origin/master. Menciptakan cabang lain memberi Anda perasaan aman, tetapi jika Anda mempelajari cara kerja git, Anda akan mengerti bahwa itu adalah ketakutan yang salah tempat. Ketika kekhawatiran tentang tidak mengubah copy pekerjaan, ini tidak menawarkan solusi.
Thibault D.
@ thibault-d Pikirkan tentang betapa rumitnya solusinya saat Anda tidak memulai dengan cabang yang bersih. git merge --no-committidak akan membatalkan penggabungan jika itu dapat diteruskan dengan cepat. git merge --aborttidak berfungsi jika digabung. Jika Anda ingin menulis ini sebagai skrip, ini aneh, karena git mergetidak membalas dengan kode kesalahan yang cukup baik untuk menjelaskan berbagai jenis konflik. Bekerja dengan cabang baru mencegah skrip rusak meninggalkan repo Anda dalam keadaan yang memerlukan intervensi manual. Tentu Anda tidak bisa kehilangan apapun. Tetapi lebih mudah untuk membangun sebaliknya.
Erik Aronesty
47
Mengurungkan penggabungan dengan git sangat mudah sehingga Anda tidak perlu khawatir tentang dry run:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
SUNTING: Seperti disebutkan dalam komentar di bawah ini, jika Anda memiliki perubahan dalam direktori kerja Anda atau area pementasan Anda mungkin ingin menyimpannya sebelum melakukan hal di atas (jika tidak mereka akan menghilang mengikuti yang di git resetatas)
Cukup memeriksa apakah penggabungan akan maju cepat (FF) adalah masalah memeriksa daftar git branch --contains HEADatau bahkan lebih langsung, cukup gunakangit merge --ff-only
Brian Phillips
7
git reset --hard adalah salah satu dari sedikit perintah penghapusan informasi tanpa backout yang dimiliki git, jadi harus digunakan dengan sangat hati-hati. Dengan demikian, -1
Kzqai
8
@Tchalvak masih ada reflog.
Kissaki
3
--dry-runtidak akan "cukup memeriksa apakah penggabungan akan maju cepat". Itu akan mengembalikan output yang tepat bahwa penggabungan akan: file, konflik dll. Apakah akan ff tidak benar-benar menarik, bukan?
Hanya beda cabang Anda saat ini dengan cabang jarak jauh, ini akan memberi tahu Anda apa yang akan berubah ketika Anda melakukan tarikan / penggabungan.
#see diff between current master and remote branch
git diff master origin/master
Ide yang menarik. Bagaimana saya melihat output itu dan menentukan apakah penggabungan akan berfungsi atau tidak?
MatrixFrog
6
Ini tidak akan memberi tahu Anda jika ada konflik akan terjadi ... tetapi itu akan memberi Anda gambaran umum tentang apa yang akan terjadi jika Anda melakukan penarikan / penggabungan.
timh
10
Ini hanya akan memberi tahu Anda perbedaan antara dua cabang, itu tidak akan memberi tahu Anda apa hasil dari penggabungan akan. Ini adalah perbedaan penting karena penggabungan akan dalam beberapa kasus secara otomatis mengambil perubahan dari cabang yang berbeda tergantung pada kapan mereka berkomitmen. Jadi pada dasarnya, melakukan diff mungkin membuat Anda berpikir beberapa perubahan Anda akan dikembalikan ketika dalam kenyataannya, proses penggabungan akan secara otomatis mengambil perubahan yang lebih baru daripada yang lebih lama. Harapan itu masuk akal.
markquezada
3
Untuk membangun komentar @ mirthlab, akan ada perbedaan yang signifikan antara diff dan penggabungan jika seseorang sebelumnya melakukan penggabungan dengan strategi penggabungan "milik kami" (atau beberapa perbaikan penggabungan manual lainnya); diff juga akan menunjukkan kepada Anda perbedaan yang sudah dihitung sebagai "digabung".
Tao
21
Saya menggunakan perintah request-pull git untuk melakukannya. Ini memungkinkan Anda untuk melihat setiap perubahan yang akan terjadi saat penggabungan, tetapi tanpa melakukan apa pun di repositori lokal atau jauh Anda .
Misalnya, bayangkan Anda ingin menggabungkan cabang bernama "fitur-x" ke cabang master Anda
git request-pull master origin feature-x
akan menunjukkan kepada Anda ringkasan tentang apa yang akan terjadi (tanpa melakukan apa pun):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Jika Anda menambahkan -pparameter, Anda juga akan mendapatkan teks tambalan lengkap, persis seperti jika Anda melakukan git diff pada setiap file yang diubah.
Anda bisa membuatnya lebih jelas dengan menambahkan apa masterdan originlakukan di opsi baris perintah, dan bagaimana jika saya misalnya pada lokal branch1dan ingin melakukan request-pullpada cabang fitur lokal branch2? Apakah saya masih membutuhkan origin? Tentu saja, orang selalu dapat membaca dokumentasi.
Ela782
Sayangnya perintah ini hanya berfungsi jika Rev # 2 adalah nama cabang, itu tidak bekerja untuk hash: /
Jared Grubb
20
Saya terkejut belum ada yang menyarankan untuk menggunakan tambalan.
Katakanlah Anda ingin menguji gabungan dari your_branchke master(aku asumsi Anda telah mastermemeriksa):
error: patch failed: test.txt:1
error: test.txt: patch does not apply
itu berarti bahwa tambalan tidak berhasil dan penggabungan akan menghasilkan konflik. Tidak ada output berarti patch bersih dan Anda dapat dengan mudah menggabungkan cabang
Perhatikan bahwa ini tidak akan benar - benar mengubah pohon kerja Anda (selain membuat file tambalan tentu saja, tetapi Anda dapat dengan aman menghapusnya setelah itu). Dari dokumentasi git-apply:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Catatan untuk siapa saja yang lebih pintar / lebih berpengalaman dengan git daripada saya: tolong beri tahu saya jika saya salah di sini dan metode ini memang menunjukkan perilaku yang berbeda dari gabungan biasa. Tampaknya aneh bahwa dalam 8+ tahun bahwa pertanyaan ini telah ada, tidak seorang pun akan menyarankan solusi yang tampaknya jelas ini.
Metode ini adalah jawaban yang diterima untuk pertanyaan ini dan ada beberapa peringatan dalam komentar seperti "git tidak dapat menggunakan strategi penggabungan 'rekursif'" dan "file tambalan memberikan kesalahan untuk file baru". Kalau tidak, sepertinya hebat.
neno
1
Cara yang lebih pendek tanpa membuat file patch sementara: git diff master your_branch | git apply --check.
ks1322
9
Ini mungkin menarik: Dari dokumentasi:
Jika Anda mencoba gabungan yang mengakibatkan konflik kompleks dan ingin memulai kembali, Anda dapat memulihkan dengan git merge --abort .
Tapi Anda juga bisa melakukannya dengan cara naif (tapi lambat):
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Catatan: Ini tidak akan berfungsi hanya mengkloning ke / tmp, Anda akan memerlukan salinan, untuk memastikan bahwa perubahan yang tidak dikomit tidak akan bertentangan).
Menolak untuk menggabungkan dan keluar dengan status bukan nol kecuali KEPALA saat ini sudah mutakhir atau penggabungan dapat diselesaikan sebagai fast-forward.
Melakukan hal ini akan mencoba untuk menggabungkan dan memajukan, dan jika tidak dapat membatalkan dan meminta Anda bahwa memajukan tidak dapat dilakukan, tetapi membiarkan cabang kerja Anda tidak tersentuh. Jika itu bisa maju cepat, maka itu akan melakukan penggabungan pada cabang kerja Anda. Opsi ini juga tersedia di git pull. Dengan demikian, Anda dapat melakukan hal berikut:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Itu akan melakukan penggabungan jika dapat dilakukan dengan fast forward yang bukan yang saya inginkan dalam pertanyaan awal. Saya pikir jawaban yang diterima memiliki setengah lainnya yang memperbaikinya.
Otto
Namun sungguh, git mewah meminta meniadakan kebutuhan saya untuk hal semacam ini.
Otto
2
Itu tidak benar-benar sama. Keluar dengan status tidak nol karena penggabungan tidak dapat diselesaikan karena fast-forward tidak berarti ada konflik . Itu hanya berarti sejarah telah berbeda dan komit gabungan diperlukan.
ADTC
7
Saya menggunakan git log untuk melihat apa yang telah berubah pada cabang fitur dari cabang utama
Jika Anda ingin memajukan dari B ke A, maka Anda harus memastikan bahwa git log B..A tidak menunjukkan apa-apa kepada Anda, yaitu A tidak memiliki apa pun yang tidak dimiliki B. Tetapi bahkan jika B..A memiliki sesuatu, Anda mungkin masih dapat bergabung tanpa konflik, jadi hal di atas menunjukkan dua hal: bahwa akan ada fast-forward, dan dengan demikian Anda tidak akan mendapatkan konflik.
Anda akan melihat apakah ada konflik dan dapat merencanakan bagaimana menyelesaikannya.
Setelah itu Anda dapat membatalkan penggabungan melalui git merge --abort, atau (jika tidak ada konflik dan penggabungan telah terjadi) kembalikan ke komit sebelumnya melaluigit reset --hard HEAD~1
Jawaban:
Seperti disebutkan sebelumnya, berikan
--no-commit
flag, tetapi untuk menghindari fast-forward commit, ikut juga--no-ff
, seperti:Untuk memeriksa perubahan bertahap:
Dan Anda bisa membatalkan penggabungan, bahkan jika itu adalah penggabungan maju-cepat:
sumber
git merge --only-if-there-wont-be-any-conflicts
ataugit diff --show-conflicts <commit>
akan sangat berguna. Malu itu belum mungkin, atau apakah saya kehilangan sesuatu?git pull --ff-only
!Saya hanya perlu mengimplementasikan metode yang secara otomatis menemukan konflik antara repositori dan remote-nya. Solusi ini melakukan penggabungan dalam memori sehingga tidak akan menyentuh indeks, atau pohon yang berfungsi. Saya pikir ini adalah cara teraman yang mungkin Anda bisa menyelesaikan masalah ini. Begini cara kerjanya:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( mergebase adalah id heksadesimal yang digabungkan-basis dicetak pada langkah sebelumnya)Sekarang anggaplah Anda ingin menggabungkan master jarak jauh dengan master lokal Anda, tetapi Anda bisa menggunakan cabang apa pun.
git merge-tree
akan menjalankan gabungan dalam memori dan mencetak hasilnya ke output standar. Grep untuk polanya<<
atau>>
. Atau Anda dapat mencetak output ke file dan memeriksanya. Jika Anda menemukan garis yang dimulai dengan 'diubah di keduanya' maka kemungkinan besar akan ada konflik.sumber
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
biasa! +100+<<<<<<< .our
jadi saya menggunakan ekspresi grep sepertigrep -q '^+<* \.our$'
Solusi brute force sederhana saya untuk ini adalah:
Buat cabang "pra-master" (dari master tentu saja)
Gabungkan semua hal yang Anda inginkan ke dalam pre-master ini.
Kemudian Anda bisa melihat bagaimana penggabungan terjadi tanpa menyentuh master.
Bagaimanapun, saya akan mengikuti saran @ orange80.
sumber
git merge --abort
jika ada konflik,git reset --hard HEAD~1
apakah ada gabungan ataugit reset --hard origin/master
. Menciptakan cabang lain memberi Anda perasaan aman, tetapi jika Anda mempelajari cara kerja git, Anda akan mengerti bahwa itu adalah ketakutan yang salah tempat. Ketika kekhawatiran tentang tidak mengubah copy pekerjaan, ini tidak menawarkan solusi.git merge --no-commit
tidak akan membatalkan penggabungan jika itu dapat diteruskan dengan cepat.git merge --abort
tidak berfungsi jika digabung. Jika Anda ingin menulis ini sebagai skrip, ini aneh, karenagit merge
tidak membalas dengan kode kesalahan yang cukup baik untuk menjelaskan berbagai jenis konflik. Bekerja dengan cabang baru mencegah skrip rusak meninggalkan repo Anda dalam keadaan yang memerlukan intervensi manual. Tentu Anda tidak bisa kehilangan apapun. Tetapi lebih mudah untuk membangun sebaliknya.Mengurungkan penggabungan dengan git sangat mudah sehingga Anda tidak perlu khawatir tentang dry run:
SUNTING: Seperti disebutkan dalam komentar di bawah ini, jika Anda memiliki perubahan dalam direktori kerja Anda atau area pementasan Anda mungkin ingin menyimpannya sebelum melakukan hal di atas (jika tidak mereka akan menghilang mengikuti yang di
git reset
atas)sumber
git branch --contains HEAD
atau bahkan lebih langsung, cukup gunakangit merge --ff-only
--dry-run
tidak akan "cukup memeriksa apakah penggabungan akan maju cepat". Itu akan mengembalikan output yang tepat bahwa penggabungan akan: file, konflik dll. Apakah akan ff tidak benar-benar menarik, bukan?git stash; git reset --hard
? @BrianPhillipsSaya membuat alias untuk melakukan ini dan bekerja seperti pesona, saya melakukan ini:
Sekarang saya hanya menelepon
Untuk mengetahui apakah ada konflik.
sumber
Hanya beda cabang Anda saat ini dengan cabang jarak jauh, ini akan memberi tahu Anda apa yang akan berubah ketika Anda melakukan tarikan / penggabungan.
sumber
Saya menggunakan perintah request-pull git untuk melakukannya. Ini memungkinkan Anda untuk melihat setiap perubahan yang akan terjadi saat penggabungan, tetapi tanpa melakukan apa pun di repositori lokal atau jauh Anda .
Misalnya, bayangkan Anda ingin menggabungkan cabang bernama "fitur-x" ke cabang master Anda
akan menunjukkan kepada Anda ringkasan tentang apa yang akan terjadi (tanpa melakukan apa pun):
Jika Anda menambahkan
-p
parameter, Anda juga akan mendapatkan teks tambalan lengkap, persis seperti jika Anda melakukan git diff pada setiap file yang diubah.sumber
master
danorigin
lakukan di opsi baris perintah, dan bagaimana jika saya misalnya pada lokalbranch1
dan ingin melakukanrequest-pull
pada cabang fitur lokalbranch2
? Apakah saya masih membutuhkanorigin
? Tentu saja, orang selalu dapat membaca dokumentasi.Saya terkejut belum ada yang menyarankan untuk menggunakan tambalan.
Katakanlah Anda ingin menguji gabungan dari
your_branch
kemaster
(aku asumsi Anda telahmaster
memeriksa):Itu harus melakukan trik.
Jika Anda mendapatkan kesalahan seperti
itu berarti bahwa tambalan tidak berhasil dan penggabungan akan menghasilkan konflik. Tidak ada output berarti patch bersih dan Anda dapat dengan mudah menggabungkan cabang
Perhatikan bahwa ini tidak akan benar - benar mengubah pohon kerja Anda (selain membuat file tambalan tentu saja, tetapi Anda dapat dengan aman menghapusnya setelah itu). Dari dokumentasi git-apply:
Catatan untuk siapa saja yang lebih pintar / lebih berpengalaman dengan git daripada saya: tolong beri tahu saya jika saya salah di sini dan metode ini memang menunjukkan perilaku yang berbeda dari gabungan biasa. Tampaknya aneh bahwa dalam 8+ tahun bahwa pertanyaan ini telah ada, tidak seorang pun akan menyarankan solusi yang tampaknya jelas ini.
sumber
git diff master your_branch | git apply --check
.Ini mungkin menarik: Dari dokumentasi:
Tapi Anda juga bisa melakukannya dengan cara naif (tapi lambat):
(Catatan: Ini tidak akan berfungsi hanya mengkloning ke / tmp, Anda akan memerlukan salinan, untuk memastikan bahwa perubahan yang tidak dikomit tidak akan bertentangan).
sumber
cp -r repository/.git /tmp/repository/.git
,cd /tmp/repository
,git reset --hard
,git add --all
,git reset --hard
(untuk mengukur baik),git status
(untuk memeriksa bahwa itu bersih).Saya sadar bahwa ini adalah pertanyaan lama, tetapi ini adalah pertanyaan pertama yang muncul di pencarian Google.
Git memperkenalkan opsi --ff-only saat penggabungan.
Melakukan hal ini akan mencoba untuk menggabungkan dan memajukan, dan jika tidak dapat membatalkan dan meminta Anda bahwa memajukan tidak dapat dilakukan, tetapi membiarkan cabang kerja Anda tidak tersentuh. Jika itu bisa maju cepat, maka itu akan melakukan penggabungan pada cabang kerja Anda. Opsi ini juga tersedia di
git pull
. Dengan demikian, Anda dapat melakukan hal berikut:sumber
Saya menggunakan git log untuk melihat apa yang telah berubah pada cabang fitur dari cabang utama
mis - untuk melihat komit apa yang ada dalam cabang fitur yang telah / belum digabungkan untuk dikuasai:
sumber
Jika Anda ingin memajukan dari B ke A, maka Anda harus memastikan bahwa git log B..A tidak menunjukkan apa-apa kepada Anda, yaitu A tidak memiliki apa pun yang tidak dimiliki B. Tetapi bahkan jika B..A memiliki sesuatu, Anda mungkin masih dapat bergabung tanpa konflik, jadi hal di atas menunjukkan dua hal: bahwa akan ada fast-forward, dan dengan demikian Anda tidak akan mendapatkan konflik.
sumber
Solusi saya adalah menggabungkan kembali.
Daripada menggabungkan cabang Anda ke cabang "target" yang jauh, gabungkan cabang itu ke cabang Anda.
Anda akan melihat apakah ada konflik dan dapat merencanakan bagaimana menyelesaikannya.
Setelah itu Anda dapat membatalkan penggabungan melalui git
merge --abort
, atau (jika tidak ada konflik dan penggabungan telah terjadi) kembalikan ke komit sebelumnya melaluigit reset --hard HEAD~1
sumber
Buat salinan sementara dari copy pekerjaan Anda, kemudian gabungkan menjadi itu, dan bedakan keduanya.
sumber