Bagaimana cara mengelola konflik dengan submodul git?

127

Saya memiliki proyek super git yang mereferensikan beberapa submodul dan saya mencoba mengunci alur kerja agar anggota proyek saya lainnya dapat bekerja di dalamnya.

Untuk pertanyaan ini, katakanlah superproject saya dipanggil superydan submodulnya dipanggil subby. (Kemudian adalah penyederhanaan dari apa yang saya coba lakukan ... Saya sebenarnya tidak menggunakan cabang untuk versi, tapi saya pikir akan lebih mudah untuk meletakkan sebagai pertanyaan.)

Cabang master saya superymemiliki tag v1.0proyek git yang subbydirujuk sebagai submodul. Cabang superyyang disebut one.onedan mengubah referensi submodule ke titik ke tag v1.1dari subby.

Saya dapat bekerja di dalam masing-masing cabang ini tanpa hambatan, tetapi jika saya mencoba memperbarui one.onecabang dengan perubahan dari mastercabang, saya menerima beberapa konflik dan saya tidak tahu bagaimana menyelesaikannya.

Pada dasarnya setelah menjalankan beberapa git pull . mastersaat di subbycabang, sepertinya itu membuat submodul tambahan.

Sebelum tarik / gabung, saya mendapatkan respons yang diinginkan git submoduledari one.onecabang:

$ git checkout master
$ git submodule
qw3rty...321e subby (v1.0)
$ git checkout one.one
$ git submodule
asdfgh...456d subby (v1.1)

Tapi setelah ditarik, itu menambahkan submodul tambahan saat saya menjalankan git submodule:

$ git pull . master
Auto-merged schema
CONFLICT (submodule): Merge conflict in subby - needs qu3rty...321e
Automatic merge failed; fix conflicts and then commit the results.

$ git submodule
qw3rty...321e subby (v1.0)
asdfgh...456d subby (v1.1)
zxcvbn...7890 subby (v1.1~1)

Bagaimana cara menghapus / mengabaikan referensi submodule yang tidak diinginkan dan melakukan konflik dan perubahan saya? Atau apakah ada parameter yang dapat saya gunakan dengan dokumen asli saya git pullyang akan mengabaikan submodul saya?

Tyler
sumber

Jawaban:

23

Saya belum pernah melihat kesalahan persis seperti itu sebelumnya. Tapi saya punya perkiraan tentang masalah yang Anda hadapi. Sepertinya karena masterdan one.onecabang superyberisi referensi berbeda untuk subbysubmodul, saat Anda menggabungkan perubahan dari mastergit tidak tahu referensi mana - v1.0atau v1.1- yang harus disimpan dan dilacak oleh one.onecabang supery.

Jika demikian, Anda perlu memilih ref yang Anda inginkan dan melakukan perubahan itu untuk menyelesaikan konflik. Itulah yang Anda lakukan dengan perintah reset .

Ini adalah aspek rumit dalam melacak berbagai versi submodul di berbagai cabang proyek Anda. Tapi ref submodule sama seperti komponen lain dari proyek Anda. Jika dua cabang yang berbeda terus melacak masing-masing submodul ref yang sama setelah penggabungan berturut-turut, maka git harus dapat mengerjakan pola tanpa menimbulkan konflik penggabungan di penggabungan mendatang. Di sisi lain, jika Anda sering mengganti submodule refs, Anda mungkin harus menghadapi banyak penyelesaian konflik.

Jesse Hallett
sumber
1
Terima kasih telah menjelaskan pertanyaan ini. Itu sangat masuk akal bagi saya sekarang dan perintah reset berfungsi dengan sempurna untuk situasi saya di atas. Tapi apa perintah untuk menerima submodule ref dari cabang master dan membuang ref ke submodul cabang saat ini? Saya tahu bagaimana menangani konflik normal, tetapi setelah tiga hari menjelajahi web, saya tidak dapat menemukan satu contoh kode selain rm -r. Dan saya mulai berpikir bahwa ada alasan mengapa contoh tersebut tidak ada; submodule sejauh ini diabstraksi dari superproject yang harus Anda kelola setiap transisi.
Tyler
26
AKHIRNYA! Sebuah jawaban! Saya telah added by us: ../Mono.Cecilmasuk git statustetapi git adddan git rmgagal Mono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any fileskarena itu hanya folder kosong dan git hanya benar-benar menangani file. git checkoutmemberi saya Mono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updatememberi Skipping unmerged submodule Mono.Cecildan git checkout master Mono.CecilAKHIRNYA memperbaikinya. Masalah dasar: git statussaran salah, jadi pilih cabang dan ambil salinan foldernya dengan checkout!
IBBoard
6
Perintah @ IBBoard membantu saya dengan situasi ini - saya mencoba git checkout --ours SUBMODdan git add SUBMODdan lainnya, tetapi akhirnya git checkout master SUBMODmemperbaiki konflik. Komentar ini mungkin harus menjadi jawaban, bukan komentar ... :)
Colin D Bennett
89

Yah, ini tidak secara teknis mengelola konflik dengan submodul (yaitu: simpan ini tetapi bukan itu), tetapi saya menemukan cara untuk terus bekerja ... dan yang harus saya lakukan hanyalah memperhatikan git statusoutput saya dan mengatur ulang submodul:

git reset HEAD subby
git commit

Itu akan mengatur ulang submodul ke komit pra-tarik. Yang dalam hal ini persis seperti yang saya inginkan. Dan dalam kasus lain di mana saya membutuhkan perubahan yang diterapkan ke submodule, saya akan menangani mereka dengan alur kerja submodule standar (master checkout, tarik ke bawah tag yang diinginkan, dll).

Tyler
sumber
Bagi saya ini hanya tampaknya mengubah status modul yang bentrok dari "keduanya diubah" menjadi "dihapus".
Matt Zukowski
4
Anda mungkin ingin menyimpan submodul cabang yang digabungkan sebagai gantinya: git reset <merged-branch> subby
Edward Anderson
1
bekerja untuk saya seperti yang ditentukan dalam jawaban .. git reset HEAD path / to / submodule / dir
estoy
56

Saya sedikit kesulitan dengan jawaban atas pertanyaan ini dan tidak beruntung dengan jawaban di posting SO yang serupa . Jadi inilah yang berhasil untuk saya - mengingat bahwa dalam kasus saya, submodul dikelola oleh tim yang berbeda, sehingga konflik tersebut berasal dari versi submodule yang berbeda di master dan cabang lokal saya dari proyek yang saya kerjakan:

  1. Lari git status - catat folder submodule dengan konflik
  2. Setel ulang submodul ke versi yang terakhir kali dilakukan di cabang saat ini:

    git reset HEAD path/to/submodule

  3. Pada titik ini, Anda memiliki versi submodule bebas konflik yang sekarang dapat Anda perbarui ke versi terbaru di repositori submodul:

    cd path / ke / submodule
    git submodule foreach git pull asal SUBMODULE-CABANG-NAMA
  4. Dan sekarang Anda bisa melakukannya commitdan kembali bekerja.

Emma Burrows
sumber
16

Pertama, temukan hash yang Anda inginkan untuk referensi submodule Anda. lalu lari

~/supery/subby $ git co hashpointerhere
~/supery/subby $ cd ../
~/supery $ git add subby
~/supery $ git commit -m 'updated subby reference'

yang telah berhasil bagi saya untuk mendapatkan submodul saya ke referensi hash yang benar dan melanjutkan pekerjaan saya tanpa mendapatkan konflik lebih lanjut.

hellatan
sumber
1
atau Anda bisa melakukan git checkout --mereka (atau --ours) subby
Bachi
@Bachi: git checkout --theirs and --ours tidak berpengaruh pada submodul.
Edward Anderson
1
Meskipun hal ini menyelesaikan konflik, tidak mudah untuk menentukan <hashpointerhere>. Saya tidak tahu cara mudah untuk melihat komit submodul diperiksa di setiap sisi konflik. Komit apa pun yang Anda periksa di subby mungkin berbeda dari kedua sisi gabungan, yang tidak sesuai dalam komit gabungan.
Edward Anderson
@nilbus itu benar. Kami telah berhenti bekerja dengan git submodules karena itu adalah salah satu masalah yang kami miliki dan membuatnya sangat sulit untuk mengatakan komitmen mana yang sebenarnya Anda inginkan. Kami telah menggunakan komposer (php) sebagai manajer paket, yang sebenarnya saya sukai karena ini membuat file kunci yang mengunci repo ke hash tertentu. Namun, karena kami menggunakan node_modules dalam beberapa repo, kami akan mengalami modul yang bertentangan di sana-sini. Kami telah beralih ke npm untuk mengelola hal-hal ini tetapi itu juga semua cacing lainnya.
hellatan
12

Saya mengalami masalah ini dengan git rebase -i origin/masterke cabang. Saya ingin mengambil ref submodule versi master, jadi saya cukup melakukannya:

git reset master path/to/submodule

lalu

git rebase --continue

Itu memecahkan masalah saya.

maraton
sumber
3
Ini berhasil untuk saya. Saya masih memikirkan apa yang mereka lakukan untuk merusak submodul
Checo R
3

Mendapat bantuan dari diskusi ini. Dalam kasus saya,

git reset HEAD subby
git commit

bekerja untuk saya :)

Mithun Das
sumber
2

Di direktori induk saya, saya melihat:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

Jadi saya baru saja melakukan ini

git reset HEAD linux
Kjeld Flarup
sumber