Mengatasi konflik Git dengan file biner

464

Saya telah menggunakan Git di Windows (msysgit) untuk melacak perubahan untuk beberapa pekerjaan desain yang telah saya lakukan.

Hari ini saya telah bekerja pada PC yang berbeda (dengan repo jarak jauh brian) dan saya sekarang mencoba untuk menggabungkan pengeditan yang dilakukan hari ini kembali ke versi lokal saya yang biasa pada laptop saya.

Di laptop saya, saya biasa git pull brian mastermenarik perubahan ke versi lokal saya. Semuanya baik-baik saja terlepas dari dokumen InDesign utama - ini menunjukkan sebagai konflik.

Versi pada PC ( brian) adalah yang terbaru yang ingin saya pertahankan tetapi saya tidak tahu perintah apa yang memberitahu repo untuk menggunakan yang ini.

Saya mencoba menyalin file langsung ke laptop saya tetapi ini tampaknya memecah seluruh proses penggabungan.

Adakah yang bisa mengarahkan saya ke arah yang benar?

Kevin Wilson
sumber

Jawaban:

854

git checkoutmenerima --oursatau --theirsopsi untuk kasus-kasus seperti ini. Jadi, jika Anda memiliki konflik gabungan, dan Anda tahu Anda hanya ingin file dari cabang tempat Anda bergabung, Anda bisa melakukannya:

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

untuk menggunakan versi file tersebut. Demikian juga, jika Anda tahu Anda menginginkan versi Anda (bukan yang digabungkan), Anda dapat menggunakannya

$ git checkout --ours -- path/to/conflicted-file.txt
mipadi
sumber
47
Saya harus menjalankan 'git reset path HEAD / ke / konflik-file.txt' pada file sebelum menggunakan --our, jika tidak sepertinya tidak berpengaruh.
Zitrax
6
@Zitrax Apakah Anda berbeda file setelah menjalankan git checkout --ours? Halaman manual menyarankan (IMHO) bahwa checkout --kita / - milik mereka akan menghapus perubahan dari daftar "keduanya dimodifikasi, perlu digabung" dan menambahkannya ke indeks, dan saya pikir itu tidak benar. Saya yakin Anda harus berlari git addsetelah checkout.
Tim Keating
15
Catatan: Anda masih ingin melakukan "git add konflik-file.txt " dan "git commit". Dengan mudah, ketika saya mencobanya, pesan komit telah diisi sebelumnya dengan catatan tentang konflik.
Edward Falk
2
frase "cabang tempat Anda bergabung" sangat berbahaya bagi "cabang tempat Anda bergabung", saya pikir bahwa dengan membatalkan preposisi akan lebih baik: "cabang tempat Anda menggabungkan", yang akan mencerminkan perintah git juga (yaitu git merge branch_name).
andrybak
13
Beberapa poin penting yang selalu hilang dalam penjelasan topik ini. Saat melakukan rebase alih-alih penggabungan, arti dari --theirdan --oursditukar, yaitu --their == cabang yang sedang diperiksa dan - kami adalah cabang, biasanya cabang jarak jauh, atau jalur spesifikasi yang Anda coba gabungkan menjadi arus cabang. The [space]--[space]pilihan disambiguates ke jalan spesifikasi antara nama cabang dan jalur spec yang baik terjadi ada dengan nama yang sama (misalnya nama cabang yang ada adalah "abc" dan direktori eksis disebut "abc").
BoiseBaked
147

Anda harus menyelesaikan konflik secara manual (menyalin file lebih) dan kemudian melakukan file (tidak masalah jika Anda menyalinnya atau menggunakan versi lokal) seperti ini

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

Git biasanya dikomit secara otomatis setelah bergabung, tetapi ketika mendeteksi konflik, ia tidak dapat menyelesaikannya dengan sendirinya, ia menerapkan semua tambalan yang ditemukannya dan membiarkan sisanya untuk Anda selesaikan dan komit secara manual. The Git Gabung Man Halaman , yang Crash Course Git-SVN atau ini blog mungkin titik terang tentang bagaimana seharusnya bekerja.

Sunting: Lihat posting di bawah ini, Anda sebenarnya tidak perlu menyalin file sendiri, tetapi dapat menggunakan

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

untuk memilih versi file yang Anda inginkan. Menyalin / mengedit file hanya akan diperlukan jika Anda ingin campuran kedua versi.

Harap tandai jawaban mipadis sebagai jawaban yang benar.

VolkA
sumber
1
Terima kasih untuk itu. Saya tidak yakin apakah ada semacam cara untuk menandai file sebagai yang 'benar'. Menjelaskan mengapa saya tidak dapat menemukan perintah yang tidak ada!
Kevin Wilson
Yap, itu agak tidak intuitif - sesuatu seperti tekad git akan menyenangkan, tetapi juga akan menjadi langkah ekstra ...
VolkA
120

Anda juga dapat mengatasi masalah ini dengan

git mergetool

yang menyebabkan gitmembuat salinan lokal dari biner yang berkonflik dan menelurkan editor default Anda pada mereka:

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

Jelas Anda tidak dapat mengedit file biner dalam editor teks. Alih-alih, Anda menyalin {conflicted}.REMOTEfile baru {conflicted}tanpa menutup editor. Kemudian ketika Anda menutup editor gitakan melihat bahwa copy pekerjaan yang tidak didekorasi telah diubah dan konflik gabungan Anda diselesaikan dengan cara biasa.

RobM
sumber
8
Jika file berukuran besar atau Anda tidak ingin mengambil risiko membuka biner di editor teks sama sekali, Anda dapat menekan ctrl + c pada prompt mergetool (" Hit return to start merge resolution tool") dan git akan membiarkan file tambahan di tempatnya. Kemudian Anda dapat memodifikasinya atau menggabungkannya dalam alat eksternal (berguna untuk format dokumen biner seperti LibreOffice / OpenOffice / MSWord) dan menyimpan hasilnya kembali ke nama file asli. Untuk memberi tahu git bahwa konflik telah diselesaikan, git addnama file aslinya, dan Anda kemudian dapat menyelesaikan komit gabungan.
Felix
18

Untuk mengatasinya dengan menyimpan versi di cabang Anda saat ini (abaikan versi dari cabang tempat Anda bergabung), cukup tambahkan dan komit file:

git commit -a

Untuk menyelesaikan dengan menimpa versi di cabang Anda saat ini dengan versi dari cabang yang Anda gabungkan, Anda harus mengambil versi itu ke direktori kerja Anda terlebih dahulu, dan kemudian tambahkan / komit:

git checkout otherbranch theconflictedfile
git commit -a

Dijelaskan lebih detail

Joshua Flanagan
sumber
1
Saya lebih suka varian ini daripada jawaban yang diterima, karena lebih intuitif, terutama mengingat bahwa arti dari "--our" dan "--theirs" mereka bertukar dalam kasus rebasing.
Antony Hatchkins
11

jawaban mipadi tidak bekerja untuk saya, saya perlu melakukan ini:

git checkout - jalur kami / ke / file.bin

atau, untuk menjaga versi digabungkan:

git checkout - jalur mereka / ke / file.bin

kemudian

git tambahkan path / ke / file.bin

Dan kemudian saya bisa melakukan "git mergetool" lagi dan melanjutkan ke konflik berikutnya.

keris
sumber
6

Dari git checkoutdokumen

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

--ours
--theirs
Saat memeriksa jalur dari indeks, periksa tahap # 2 ( ours) atau # 3 ( theirs) untuk jalur yang tidak digabungkan.

Indeks mungkin berisi entri yang tidak dihapus karena gabungan gagal sebelumnya. Secara default, jika Anda mencoba untuk memeriksa entri seperti itu dari indeks, operasi checkout akan gagal dan tidak ada yang akan diperiksa. Menggunakan -fakan mengabaikan entri yang tidak dihapus ini. Konten dari sisi tertentu dari gabungan dapat diperiksa dari indeks dengan menggunakan --oursatau --theirs. Dengan -m, perubahan yang dibuat pada file pohon kerja dapat dibuang untuk membuat kembali hasil gabungan yang konflik.

pengguna456814
sumber
4

Saya menemukan masalah yang sama (ingin menarik komit yang menyertakan beberapa file biner yang menyebabkan konflik ketika digabungkan), tetapi menemukan solusi yang berbeda yang dapat dilakukan sepenuhnya menggunakan git (yaitu tidak harus menyalin file secara manual). Saya pikir saya akan memasukkannya di sini sehingga paling tidak saya bisa mengingatnya saat berikutnya saya membutuhkannya. :) Langkah-langkahnya terlihat seperti ini:

% git fetch

Ini mengambil komit terbaru dari repositori jarak jauh (Anda mungkin perlu menentukan nama cabang jarak jauh, tergantung pada pengaturan Anda), tetapi tidak mencoba untuk menggabungkan mereka. Itu mencatat komit di FETCH_HEAD

% git checkout FETCH_HEAD stuff/to/update

Ini mengambil salinan file biner yang saya inginkan dan menimpa apa yang ada di pohon yang berfungsi dengan versi yang diambil dari cabang jarak jauh. git tidak mencoba melakukan penggabungan, jadi Anda hanya berakhir dengan salinan persis file biner dari cabang jarak jauh. Setelah selesai, Anda dapat menambah / mengkomit salinan baru seperti biasa.

Brian Webster
sumber
4

Prosedur ini adalah untuk menyelesaikan konflik file biner setelah Anda mengirimkan permintaan tarik ke Github:

  1. Jadi pada Github, Anda menemukan permintaan tarikan Anda memiliki konflik pada file biner.
  2. Sekarang kembali ke cabang git yang sama di komputer lokal Anda.
  3. Anda (a) membuat kembali / membangun kembali file biner ini, dan (b) mengkomit file biner yang dihasilkan ke cabang git yang sama ini.
  4. Kemudian Anda mendorong cabang git yang sama ini lagi ke Github.

Di Github, atas permintaan tarik Anda, konflik akan hilang.

david m lee
sumber
Ini persis prosedur yang saya butuhkan
Huifang Feng
2

Jika biner adalah sesuatu yang lebih dari dll atau sesuatu yang dapat diedit secara langsung seperti gambar, atau file campuran (dan Anda tidak perlu membuang / memilih satu file atau yang lain) gabungan nyata akan seperti:

Saya sarankan mencari alat diff yang berorientasi pada apa yang Anda file biner, misalnya ada beberapa yang gratis untuk file gambar misalnya

dan membandingkannya.

Jika tidak ada alat diff di luar sana untuk membandingkan file Anda, maka jika Anda memiliki generator asli dari file bin (yaitu, ada editor untuk itu ... seperti blender 3d, Anda kemudian dapat secara manual memeriksa file-file itu, juga lihat log, dan tanyakan pada orang lain apa yang harus Anda sertakan) dan lakukan output file dengan https://git-scm.com/book/es/v2/Git-Tools-Advanced-Merging#_manual_remerge

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

tyoc213
sumber
1

Saya telah menemukan dua strategi untuk mengelola file biner dengan Git di windows.

  1. Tortoise git memungkinkan Anda mengonfigurasi alat diff / menggabungkan untuk berbagai jenis file berdasarkan ekstensi file mereka. Lihat 2.35.4.3. Pengaturan Lanjutan Diff / Gabungkan http://tortoisegit.org/docs/tortoisegit/tgit-dug-settings.html . Strategi ini tentu saja mengandalkan alat diff / merge yang sesuai yang tersedia.

  2. Menggunakan atribut git Anda dapat menentukan alat / perintah untuk mengkonversi file biner Anda menjadi teks dan kemudian membiarkan alat diff / merge default Anda melakukan hal itu. Lihat http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes . Artikel ini bahkan memberikan contoh penggunaan data meta untuk gambar yang berbeda.

Saya mendapatkan kedua strategi untuk bekerja dengan file biner model perangkat lunak, tetapi kami menggunakan tortoise git karena konfigurasinya mudah.

BoJohDoh
sumber
0

Saya menggunakan Git Workflow untuk Excel - https://www.xltrail.com/blog/git-workflow-for-excel aplikasi untuk menyelesaikan sebagian besar file biner terkait masalah penggabungan. Aplikasi open-source ini membantu saya untuk menyelesaikan masalah secara produktif tanpa menghabiskan terlalu banyak waktu dan memungkinkan saya untuk memilih versi file yang tepat tanpa kebingungan.

Siddhartha Thota
sumber
0

kasing saya seperti bug .... menggunakan git 2.21.0

Saya melakukan penarikan ... itu mengeluh tentang file biner:

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.

Dan kemudian tidak ada jawaban apa pun di sini yang menghasilkan keluaran apa pun yang masuk akal.

Jika saya melihat file mana yang saya miliki sekarang ... itu yang saya edit. Jika saya melakukan keduanya:

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

Saya mendapatkan output:

Updated 0 paths from the index

dan saya masih memiliki versi file saya. Jika saya rm dan kemudian checkout, Ia akan mengatakan 1 sebagai gantinya, tetapi masih memberi saya versi file.

kata git mergetool

No files need merging

dan status git mengatakan

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

Salah satu pilihan adalah membatalkan komit ... tapi saya kurang beruntung dan saya punya banyak komitmen, dan yang buruk ini adalah yang pertama. Saya tidak ingin membuang waktu untuk mengulanginya.

jadi untuk mengatasi kegilaan ini:

Saya hanya berlari

git commit

yang kehilangan versi jarak jauh, dan mungkin membuang-buang ruang penyimpanan file biner tambahan ... lalu

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

yang memberi saya kembali versi jarak jauh

kemudian mengedit file lagi ... lalu komit dan tekan, yang lagi mungkin berarti membuang-buang ruang dengan salinan lain dari file biner.

Peter
sumber
Dalam kasus saya, setelah mencoba git checkout --ours <path>saya terima Updated 0 paths from the index . Saya sudah memperbaikinya dengan git add <path>perintah, yang melakukan hal yang sama.
Andriy