Як мені керувати конфліктами з підмодулями git?


127

У мене є суперпроект git, який посилається на декілька підмодулів, і я намагаюся блокувати робочий процес для решти членів мого проекту, щоб працювати в межах.

Для цього питання, скажімо, називається мій суперпроект і називається superyпідмодуль subby. (Тоді є спрощення того, що я намагаюся зробити ... Я фактично не використовую гілки для версій, але я подумав, що це буде найпростіше викласти як питання.)

Мій головний відділ superyмає тег v1.0проекту git, позначений subbyяк підмодуль. Гілка superyназивається one.oneі змінила посилання підмодуля в точку тегом v1.1з subby.

Я можу працювати в межах кожної з цих гілок без перешкод, але якщо я спробую оновити one.oneгілку зі змінами в masterгілці, я отримую деякі конфлікти і не можу їх вирішити.

В основному після деякого пробігу git pull . masterу subbyвідділенні, схоже, це створює додаткові підмодулі.

Перед тягне / злиття, я отримую бажаний відгук git submoduleвід one.oneфілії:

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

Але після витягування він додає додаткові підмодулі під час запуску 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)

Як видалити / проігнорувати небажані посилання на підмодуль та здійснити свої конфлікти та зміни? Або є параметр, який я можу використовувати зі своїм оригіналом, git pullякий ігнорує мої підмодулі?

Відповіді:


23

Я не бачив такої точної помилки раніше. Але я здогадуюсь про проблему, з якою ви стикаєтесь. Це схоже на те, що masterі one.oneгілки superyмістять різні посилання на subbyпідмодуль, коли ви зливаєте зміни з mastergit, не знаєте, який ref - v1.0або v1.1- повинен зберігатися і відслідковуватися one.oneгілкою supery.

Якщо це так, то вам потрібно вибрати необхідний перелік та здійснити цю зміну для вирішення конфлікту. Це саме те, що ви робите з командою скидання .

Це складний аспект відстеження різних версій підмодуля в різних галузях вашого проекту. Але посилання на підмодуль - це як і будь-який інший компонент вашого проекту. Якщо дві різні гілки продовжують відслідковувати однакові відповідні підмодулі після послідовного злиття, то git має бути в змозі розробити схему, не викликаючи конфліктів злиття у майбутніх злиттях. З іншого боку, якщо підмодуль перемикається часто, то, можливо, доведеться змиритися з вирішенням багатьох конфліктів.


1
Дякуємо за пролиття трохи світла на питання. Це для мене зараз має повний сенс, і команда скидання відмінно працює в моїй ситуації вище. Але що було б командами прийняти ref підмодуля з ведучої гілки та відкинути ref до підмодулю поточної гілки? Я знаю, як впоратись із нормальними конфліктами, але після трьох днів чистки в Інтернеті я не можу знайти один приклад коду, крім rm -r. І я починаю думати, що прикладів для прикладів не існує; підмодуль настільки абстрагується від надпроекту, що вам доведеться керувати кожним переходом.
Тайлер

26
ОКОНЧНО! Відповідь! Я був added by us: ../Mono.Cecilв , git statusале git addі git rmзазнав невдачі з , Mono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesтому що це була просто порожня папка і мерзотник тільки дійсно працює з файлами. git checkoutдав мені Mono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updateдав Skipping unmerged submodule Mono.Cecilі git checkout master Mono.CecilНАРЕШНО це виправив. Основна проблема: git statusпропозиція неправильна, тому виберіть гілку та візьміть її копію папки checkout!
IBBoard

6
@ Команда IBBoard допомогла мені з цією ситуацією - я спробував git checkout --ours SUBMODі git add SUBMODта інші, але в кінці кінців Doing git checkout master SUBMODзафіксував конфлікт. Цей коментар, мабуть, повинен бути відповіддю, а не коментарем ... :)
Колін Д Беннетт

89

Ну, це технічно не керує конфліктами з підмодулями (тобто: зберігайте це, але не це), але я знайшов спосіб продовжувати роботу ... і все, що я повинен був зробити, це звернути увагу на свій git statusвихід та скинути підмодулі:

git reset HEAD subby
git commit

Це призведе до скидання підмодулю до попереднього виведення. Що в цьому випадку - саме те, що я хотів. І в інших випадках, коли мені потрібні зміни, застосовані до підмодулю, я оброблятиму їх із стандартними робочими процесами підмодуля (майстер оформлення замовлення, витягнути потрібний тег тощо).


Для мене це, здається, лише змінить стан конфліктуючого модуля з "обох модифікованих" на "видалених".
Метт Зуковський

4
Ви можете замість цього зберегти підмодуль об'єднаної гілки: підрозділ git reset <merged-branch>
Едвард Андерсон

1
працює для мене, як прописано у відповіді .. git reset HEAD path / to / submodule / dir
estoy

56

Я трохи боровся з відповідями на це питання, і мені не пощастило з відповідями в аналогічному дописі ЗП. Отже, це працювало для мене - маючи на увазі, що в моєму випадку підмодуль підтримував інша команда, тому конфлікт виходив з різних версій підмодуля в майстер і мій локальний відділ проекту, над яким я працював:

  1. Виконати git status- занотуйте папку підмодуля з конфліктами
  2. Скиньте підмодуль до версії, яка востаннє була здійснена в поточній гілці:

    git reset HEAD path/to/submodule

  3. На даний момент у вас є безконфліктна версія вашого підмодуля, яку тепер ви можете оновити до останньої версії в сховищі підмодуля:

    cd шлях / до / підмодуль
    git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
  4. А тепер ви можете commitце і повернутися до роботи.


16

Спочатку знайдіть хеш, який ви хочете, до свого підмодуля для посилання. потім біжи

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

що працювало для мене, щоб домогтися мого підмодуля до правильної хеш-посилання і продовжувати свою роботу, не отримуючи жодних подальших конфліктів.


1
або ви могли просто зробити git checkout --theirs (або --ours) subby
Бачі

@Bachi: git checkout --theirs and --ours не впливає на підмодулі.
Едвард Андерсон

1
Хоча це і вирішує конфлікт, визначити <hashpointerhere> непросто. Я не знаю простого способу побачити, як субмодуль перевіряється з кожної сторони конфлікту. Незалежно від здійснення комісії, яку ви перевіряєте в підзаголовку, це може відрізнятися від будь-якої сторони об'єднання, що не доречно в комісії злиття.
Едвард Андерсон

@nilbus це правда. Ми відмовилися від роботи з підмодулями git, тому що це було однією з проблем, і нам було дуже важко сказати, яку віддачу ви насправді хотіли. Ми використовували композитор (php) як менеджер пакунків, що мені насправді подобається, оскільки він створює файл блокування, який блокує репости до певного хешу. Однак, оскільки ми використовуємо node_modules в декількох репостах, ми стикаємося з конфліктуючими модулями тут і там. З тих пір ми перейшли на npm для управління цим матеріалом, але це також ціла інша банка глистів.
hellatan

12

У мене була ця проблема з git rebase -i origin/masterфілією. Я хотів взяти версію підмодулю для master, тому просто зробив:

git reset master path/to/submodule

і потім

git rebase --continue

Це вирішило для мене проблему.


3
Це працювало для мене. Я досі розгадую, що вони зробили, щоб пошкодити підмодуль
Checo R

3

Отримав допомогу в цій дискусії. У моєму випадку

git reset HEAD subby
git commit

працював на мене :)


2

Ну в моєму батьківському каталозі я бачу:

$ 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)

Тож я просто зробив це

git reset HEAD linux
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.