Git dosyalarını ikili dosyalarla çözme


464

Yaptığım bazı tasarım çalışmalarındaki değişiklikleri izlemek için Git'i Windows'ta (msysgit) kullanıyorum.

Bugün farklı bir bilgisayarda çalışıyorum (uzaktan repo ile brian) ve şimdi bugün yaptığım düzenlemeleri dizüstü bilgisayarımdaki normal yerel sürümümle birleştirmeye çalışıyorum.

Dizüstü bilgisayarımda git pull brian masterdeğişiklikleri yerel sürümüme alırdım. Ana InDesign belgesinden ayrı olarak her şey iyiydi - bu bir çelişki olarak görünüyor.

PC'deki sürüm ( brian) tutmak istediğim en son sürümdür, ancak hangi komutların repoya bunu kullanmasını söylediğini bilmiyorum.

Dosyayı doğrudan dizüstü bilgisayarıma kopyalamayı denedim, ancak bu tüm birleştirme sürecini bozuyor gibi görünüyor.

Birisi beni doğru yöne yönlendirebilir mi?

Yanıtlar:


854

git checkoutbu gibi durumlar için bir --oursveya --theirsseçeneği kabul eder . Birleştirme çakışmanız varsa ve yalnızca birleştirmekte olduğunuz şubedeki dosyayı istediğinizi biliyorsanız, şunları yapabilirsiniz:

$ git checkout --theirs -- path/to/conflicted-file.txt

dosyanın o sürümünü kullanmak için. Aynı şekilde, sürümünüzü (birleştirilen sürümü değil) istediğinizi biliyorsanız,

$ git checkout --ours -- path/to/conflicted-file.txt

47
Ben --ours kullanmadan önce dosya üzerinde 'git reset HEAD yol / / / çakışan dosya.txt' çalıştırmak zorunda kaldı, aksi takdirde hiçbir etkisi var gibiydi.
Zitrax

6
@Zitrax Dosyayı çalıştırdıktan sonra fark ettiniz mi git checkout --ours? Adam sayfası (IMHO), ödeme --Ours / - onların "her ikisi de değiştirilmiş, birleştirme gerekir" listesinden kaldırmak ve dizine eklemek önerir ve bu doğru olmadığını düşünüyorum. git addÖdeme bittikten sonra kaçman gerekeceğine inanıyorum .
Tim Keating

15
Not: yine de "git add anlaşmalı dosya.txt ekle " ve "git commit" yapmak istiyorsunuz . Handily, denediğimde, taahhüt mesajı çatışma hakkında bir notla önceden dolduruldu.
Edward Falk

2
"birleştirdiğiniz dal" ifadesi tehlikeli bir şekilde "birleştirdiğiniz dal" a yakındır, sadece edatın bırakılmasının daha iyi olacağını düşünüyorum: "birleştirdiğiniz dal", git komutunu da yansıtır (yani git merge branch_name).
andrybak

13
Bu konunun açıklamalarında her zaman eksik olan birkaç önemli nokta. Birleştirme yerine rebase yaparken, anlamı --theirve --oursdeğiştirilir, yani --their == şu anda kullanıma alınmış dal ve - bizimki dal, genellikle uzak dal veya akımla birleştirmeye çalıştığınız yol özelliğidir. dalı. Bu [space]--[space]seçenek, şube adı ile her ikisi de aynı adla var olan yol belirtimi arasındaki yol belirtimini belirsizleştirir (örneğin, varolan bir şube adı "abc" ve "abc" adlı bir dizin var).
BoiseBaked

147

Çakışmayı manuel olarak çözmeniz (dosyayı kopyalamanız) ve ardından dosyayı (kopyalamanız veya yerel sürümü kullanmanız farketmeden) bu şekilde işlemeniz gerekir

git commit -a -m "Fix merge conflict in test.foo"

Git normalde birleştirme işleminden sonra otomatik olarak devreye girer, ancak kendi kendine çözemediği çakışmaları tespit ettiğinde, çözdüğü tüm yamaları uygular ve geri kalanını manuel olarak çözmeniz ve uygulamanız için bırakır. Git Birleştirme Man Sayfa , Git-SVN Crash Course veya bu blog girişi o işe gerekiyordu konusunda bazı ışık tutacak.

Düzenleme: Aşağıdaki gönderiye bakın, dosyaları kendiniz kopyalamanız gerekmez, ancak kullanabilirsiniz

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

istediğiniz dosyanın sürümünü seçin. Dosyayı kopyalamak / düzenlemek yalnızca her iki sürümün bir karışımını istiyorsanız gereklidir.

Lütfen mipadis cevabını doğru cevap olarak işaretleyin.


1
Bunun için teşekkürler. Bir dosyayı 'doğru' olarak işaretlemek için bir tür yerleşik yol olup olmadığından emin değildim. Neden varolmayan komutu bulamadığımı açıklıyor!
Kevin Wilson

Evet, bu biraz kasıtsız - git çözmek gibi bir şey güzel olurdu, ama aynı zamanda ekstra bir adım olurdu ...
VolkA

120

Ayrıca bu sorunun üstesinden gelebilirsiniz.

git mergetool

bu gitda çakışan ikilinin yerel kopyalarını oluşturmanıza ve bunlarda varsayılan düzenleyicinizi oluşturmanıza neden olur :

  • {conflicted}.HEAD
  • {conflicted}
  • {conflicted}.REMOTE

Açıkçası, bir metin düzenleyicisinde ikili dosyaları yararlı bir şekilde düzenleyemezsiniz. Bunun yerine , düzenleyiciyi kapatmadan yeni {conflicted}.REMOTEdosyayı kopyalayın {conflicted}. Ardından, editörü kapattığınızda, gitdekore edilmemiş çalışma kopyasının değiştiğini ve birleştirme çakışmalarınızın olağan şekilde çözüldüğünü görecektir.


8
Dosyalar büyükse veya bir metin düzenleyicide ikili açılma riskini almak istemiyorsanız, birleştirme komut isteminde (" Hit return to start merge resolution tool") ctrl + c tuşlarına basabilirsiniz ve git fazladan dosyaları yerinde bırakacaktır. Daha sonra bunları değiştirebilir veya harici bir araçta (LibreOffice / OpenOffice / MSWord gibi ikili belge formatları için faydalı) birleştirebilir ve sonucu orijinal dosya adına geri kaydedebilirsiniz. Git'e çakışmanın çözüldüğünü bildirmek git addiçin orijinal dosya adı ve birleştirme işlemini tamamlayabilirsiniz.
Felix

18

Sürümü geçerli dalınızda tutarak çözmek için (birleştirmekte olduğunuz daldan sürümü yoksayın), dosyayı eklemeniz ve uygulamanız yeterlidir:

git commit -a

Geçerli dalınızdaki sürümün, birleştirmekte olduğunuz daldaki sürümle üzerine yazarak çözümlemek için, önce bu sürümü çalışma dizininize almanız ve sonra eklemeniz / taahhüt etmeniz gerekir:

git checkout otherbranch theconflictedfile
git commit -a

Daha ayrıntılı olarak açıklanmıştır


1
Ben bu değişkeni kabul edilen cevaba tercih ederim, çünkü özellikle bu "- bizim" ve "- onların" anlamlarının yeniden basma durumunda yer değiştirdiği göz önüne alındığında daha sezgiseldir.
Antony Hatchkins

11

mipadi'nin cevabı benim için pek işe yaramadı, bunu yapmam gerekiyordu:

git checkout - / file.bin yolumuz

veya birleştirilen sürümü korumak için:

git checkout --the / to / file.bin yolu

sonra

git / file.bin dizinine yol ekle

Ve sonra tekrar "git mergetool" yapmayı ve bir sonraki çatışmaya devam etmeyi başardım.


6

Gönderen git checkoutdocs

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

--ours
--theirs
Dizinden yolları kontrol ederken # 2 ( ours) veya # 3 (theirs birleştirilmemiş yollar için ) 'e bakın.

Dizin, önceki başarısız birleştirme nedeniyle birleştirilmemiş girişler içerebilir. Varsayılan olarak, dizinden böyle bir girişi kontrol etmeye çalışırsanız, ödeme işlemi başarısız olur ve hiçbir şey teslim alınmaz. Kullanıldığında -fbu birleştirilmemiş girişler yok sayılır. Birleştirmenin belirli bir tarafından gelen içerik --oursveya kullanılarak dizin dışına alınabilir --theirs. İle -m, çalışma ağacı dosyasında yapılan değişiklikler, çakışan özgün birleştirme sonucunu yeniden oluşturmak için atılabilir.


4

Benzer bir sorunla karşılaştım (birleştirildiğinde çakışmalara neden olan bazı ikili dosyaları içeren bir taahhüdü çekmek istedim), ancak tamamen git kullanarak (yani dosyaları elle kopyalamak zorunda kalmadan) farklı bir çözümle karşılaştım. Buraya dahil edeceğimi düşündüm, en azından bir dahaki sefere ihtiyacım olduğunda hatırlayabiliyorum. :) Adımlar şöyle görünür:

% git fetch

Bu, uzak depodan en son taahhütleri alır (kurulumunuza bağlı olarak bir uzak dal adı belirtmeniz gerekebilir), ancak bunları birleştirmeye çalışmaz. FETCH_HEAD içindeki taahhüdü kaydeder

% git checkout FETCH_HEAD stuff/to/update

Bu, istediğim ikili dosyaların kopyasını alır ve uzak daldan getirilen sürümle çalışma ağacındakilerin üzerine yazar. git herhangi bir birleştirme yapmaya çalışmaz, bu nedenle uzak daldan ikili dosyanın tam bir kopyasını alırsınız. Bu yapıldıktan sonra, yeni kopyayı normal şekilde ekleyebilirsiniz / uygulayabilirsiniz.


4

Bu yordam, Github'a bir çekme isteği gönderdikten sonra ikili dosya çakışmalarını gidermektir:

  1. Github'da, çekme isteğinizin ikili dosyada çakışma olduğunu buldunuz.
  2. Şimdi yerel bilgisayarınızda aynı git dalına geri dönün.
  3. (A) bu ikili dosyayı yeniden oluşturursunuz / yeniden oluşturursunuz ve (b) sonuçta ortaya çıkan ikili dosyayı aynı git dalına kaydedersiniz.
  4. Sonra aynı git dalını tekrar Github'a itersiniz.

Github'da, çekme talebiniz üzerine çatışma ortadan kalkmalıdır.


Bu tam olarak ihtiyacım olan prosedür
Huifang Feng

2

İkili bir dll veya doğrudan düzenlenebilir bir şey daha fazla bir şeyse bir görüntü veya bir karışım dosyası gibi (ve bir dosyayı veya diğerini çöp / seçmek gerekmiyorsa) gerçek bir birleştirme aşağıdaki gibi olabilir:

Ben ikili dosya neye yönelik bir fark aracı arama öneririz, örneğin görüntü dosyaları için bazı ücretsiz olanlar var

ve onları karşılaştırın.

Dosyalarınızı karşılaştırmak için herhangi bir fark aracı yoksa , bin dosyasının orijinal üreticisine sahipseniz (yani bunun için bir düzenleyici vardır ... blender 3d gibi, bu dosyaları manuel olarak da inceleyebilirsiniz. günlükleri görün ve diğer kişiye ne eklemeniz gerektiğini sorun) ve https://git-scm.com/book/es/v2/Git-Tools-Advanced-Merging#_manual_remerge ile dosyaların bir çıktısını alın

$ git show :1:hello.blend > hello.common.blend $ git show :2:hello.blend > hello.ours.blend $ git show :3:hello.blend > hello.theirs.blend


1

Windows'ta Git ile ikili dosyaların farkını / birleştirilmesini yönetmek için iki stratejiyle karşılaştım.

  1. Tortoise git, dosya uzantılarına göre farklı dosya türleri için fark / birleştirme araçlarını yapılandırmanıza olanak tanır. Bkz. 2.35.4.3. Farklı Ayarları Birleştir / Birleştir http://tortoisegit.org/docs/tortoisegit/tgit-dug-settings.html . Elbette bu strateji, mevcut uygun fark / birleştirme araçlarına dayanmaktadır.

  2. Git özniteliklerini kullanarak ikili dosyanızı metne dönüştürmek için bir araç / komut belirtebilir ve sonra varsayılan fark / birleştirme aracınızın bir şey yapmasına izin verebilirsiniz. Bkz. Http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes . Makale, farklı görüntülere meta veri kullanma örneği bile veriyor.

Her iki stratejiyi de yazılım modellerinin ikili dosyaları ile çalışmak için aldım, ancak yapılandırma kolay olduğu için kaplumbağa git ile gittik.


0

Excel için Git Workflow - https://www.xltrail.com/blog/git-workflow-for-excel uygulamasını birleştirme sorunlarıyla ilgili ikili dosyalarımın çoğunu çözmek için kullanıyorum . Bu açık kaynaklı uygulama, fazla zaman harcamadan sorunları verimli bir şekilde çözmeme yardımcı oluyor ve herhangi bir karışıklık olmadan dosyanın doğru sürümünü seçmeme izin veriyor.


0

benim durumum bir hata gibi görünüyor .... git 2.21.0 kullanarak

Bir çekiş yaptım ... ikili dosyalar hakkında şikayet etti:

warning: Cannot merge binary files: <path>
Auto-merging <path>
CONFLICT (content): Merge conflict in <path>
Automatic merge failed; fix conflicts and then commit the result.

Ve sonra buradaki cevapların hiçbirinde hiçbir şey anlamlı olmayan herhangi bir çıktı ile sonuçlanmadı.

Şimdi hangi dosyaya baktığımda ... düzenlediğim dosya. Ben de:

git checkout --theirs -- <path>
git checkout --ours -- <path>

Çıktı alıyorum:

Updated 0 paths from the index

ve hala dosya sürümüm var. Eğer rm ve sonra ödeme, bunun yerine 1 diyecek, ama yine de bana dosya sürümümü veriyor.

git mergetool diyor

No files need merging

ve git durumu diyor

    All conflicts fixed but you are still merging.
    (use "git commit" to conclude merge)

Bir seçenek taahhüdü geri almaktır ... ama şanssızdım ve birçok taahhüdüm vardı ve bu kötü olan ilkti. Bunu tekrarlayarak zaman kaybetmek istemiyorum.

bu çılgınlığı çözmek için:

Yeni koştum

git commit

Bu da uzak sürümü kaybeder ve muhtemelen ekstra bir ikili dosya depolamak için biraz yer harcar ...

git checkout <commit where the remote version exists> <path>

bu da bana uzak versiyonu geri veriyor

daha sonra dosyayı yeniden düzenledi ... ve sonra taahhüt et ve it, bu da muhtemelen ikili dosyanın başka bir kopyasıyla yer israfı anlamına geliyor.


Benim durumumda, denedikten sonra git checkout --ours <path>aldım Updated 0 paths from the index . Bunu git add <path>aynı komutla düzelttim .
Andriy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.