мерзавец: объедините два ответвления: какое направление?

У нас есть следующая ситуация:

             A --- B --- C --- ... --- iphone
           /
  ... --- last-working --- ... --- master

Между последней работой и iPhone, были сделаны 32 фиксации. Между последней работой и ведущим устройством, было сделано много фиксаций.

Что я хочу, теперь новое ответвление, где у меня есть iPhone и текущее ведущее устройство, объединенное вместе. И в некоторое более позднее время, это должно быть объединено в ведущее устройство.

Во-первых, я запланировал сделать:

git checkout iphone -b iphone31
git merge master

Но затем я думал, если будет лучше сделать:

git checkout master -b iphone31
git merge iphone

Теперь я задаюсь вопросом. Каково было бы различие в результате? Слияние вело бы себя отличающееся?

Я уже попробовал обоих и как я ожидал, я получил много конфликтов, потому что iPhone действительно стар по сравнению с ведущим устройством. Теперь интересно о самом легком способе объединить их.

Возможно, даже запуск с ведущего устройства и слияние каждой единственной фиксации iPhone в него были бы легче? Как выполнение этого:

git checkout master -b iphone31
git merge A
git merge B
git merge C
...
git merge iphone

В самом конце, когда это слияние сделано (т.е. все конфликты разрешены и это работает), я хочу сделать это:

git checkout master
git merge iphone31
61
задан Albert 2 March 2010 в 13:32
поделиться

3 ответа

Наилучший подход действительно зависит от того, есть ли у других людей удаленные копии вашего кода. Если ветка master находится только на вашем локальном компьютере, вы можете использовать команду rebase для интерактивного применения коммитов из ветки функции в master:

git checkout master -b iphone-merge-branch
git rebase -i iphone

Обратите внимание, что это изменяет историю фиксации вашего нового ] iphone-merge-branch ветвь, которая может вызвать проблемы у всех, кто позже попытается перенести ваши изменения в свою кассу. Напротив, команда слияния применяет изменения как новую фиксацию, что более безопасно при совместной работе, поскольку не влияет на историю веток. См. в этой статье несколько полезных советов по использованию rebase.

Если вам нужно синхронизировать историю коммитов, лучше выполнить слияние. Вы можете использовать git mergetool для интерактивного устранения конфликтов один за другим с помощью инструмента визуального сравнения (учебное пособие по этому вопросу можно найти здесь ):

git checkout master -b iphone-merge-branch
git merge iphone
git mergetool -t kdiff3

Третий вариант, если если вам нужен полный контроль над процессом, можно использовать git cherry-pick . Вы можете использовать gitk (или вашу любимую программу просмотра истории), чтобы просмотреть хэши коммитов в ветке iphone, записать их и выбрать их по отдельности в ветке слияния, устраняя конфликты по ходу дела. Объяснение этого процесса можно найти здесь . Этот процесс будет самым медленным, но может быть лучшим вариантом, если другие методы не сработают:

gitk iphone
<note down the 35 commit SHA hashes in this branch>
git checkout master -b iphone-merge-branch
git cherry-pick b50788b
git cherry-pick g614590
...
6
ответ дан 24 November 2019 в 17:24
поделиться

Что касается альтернатив

git checkout iphone -b iphone31
git merge master

и

git checkout master -b iphone31
git merge iphone

, они будут иметь одинаковую легкость или сложность, это все равно что спорить, наполовину полон стакан или наполовину пуст.

Восприятие дерева версий

То, как мы смотрим на деревья версий, в некотором смысле просто наше произвольное восприятие. Допустим, у нас есть дерево версий, подобное следующему:

    A----------+
    |          |
    |          |
   \_/        \_/
    B          X
    |          |
    |          |
   \_/        \_/
    C          Y
    |
    |
   \_/
    D
    |
    |
   \_/
    E

И допустим, что мы хотим сделать новую версию Z извлеченной из Y на основе изменений с C на E, но не включая изменения, сделанные с A до C.

"О, это будет сложно, потому что нет общей отправной точки. " Ну, не совсем. Если мы просто разместим объекты немного по-другому в графическом макете, как этот

      /
    C+---------+
    | \        |
    |          |
   \_/         |
    D          B
    |         / \
    |          |
   \_/         |
    E          A
               |
               |
              \_/
               X
               |
               |
              \_/
               Y

, то теперь все станет выглядеть многообещающе. Обратите внимание, что здесь я не менял никаких взаимосвязей, все стрелки указывают так же, как на предыдущем рисунке, и версия A по-прежнему является общей базой. Только макет изменено.

Но теперь тривиально представить себе другое дерево

    C'---------+
    |          |
    |          |
   \_/        \_/
    D          B'
    |          |
    |          |
   \_/        \_/
    E          A
               |
               |
              \_/
               X
               |
               |
              \_/
               Y

, где задача состояла бы в обычном слиянии версии E.

Таким образом, вы можете объединить все, что захотите, единственное, что влияет на легкость или сложность, - это совокупность изменений, сделанных между тем местом, где вы выбираете в качестве отправной точки или общей основы, и тем, где вы объединить с. Вы не ограничены использованием естественной отправной точки, которую предлагает ваш инструмент управления версиями.

Это может быть непросто с некоторыми системами / инструментами контроля версий, но если все остальное не помогает, ничто не мешает вам сделать это вручную, проверяя версию C и сохраните файл как file1, извлеките версию E и сохраните файл как file2, извлеките версию Y и сохраните файл как file3, и запустите kdiff3 -o merge_result файл1 файл2 файл3 .

Ответ

Теперь для вашей конкретной ситуации трудно точно сказать, какая стратегия вызовет наименьшее количество проблем, но если есть много изменений, которые создают какие-то конфликт , вероятно, легче разделить и объединить более мелкие части.

Я предлагаю , поскольку между последней работающей и iphone 32 фиксации, вы можете, например, начать с разветвления мастера, а затем выполнить слияние в первом 16 коммитов. Если окажется, что слишком много проблем, вернитесь и попробуйте объединить 8 первых коммитов. И так далее. В худшем случае вы закончите слияние каждого из 32 коммитов один за другим, , но это, вероятно, будет проще, чем обрабатывать все накопленные конфликты за одну операцию слияния (и {{1 }} в этом случае вы работаете с действительно расходящейся кодовой базой).

Советы:

Нарисуйте на бумаге дерево версий и отметьте стрелками, что вы хотите объединить. Вычеркивайте вещи по мере их выполнения, если вы разделите процесс на несколько этапов. Это даст вам более четкое представление о том, чего вы хотите достичь, что вы уже сделали и что осталось.

Я действительно могу порекомендовать KDiff3 , это отличный инструмент для сравнения / слияния.

43
ответ дан 24 November 2019 в 17:24
поделиться

Вы говорите:

ветка iphone очень старая по сравнению с главной

Вы действительно хотите объединить их обе в новую ветку?

Назначение веток master и iphone теперь было бы совсем другим (потому что iphone очень старый). Было бы лучше создать новую ветку, объединяющую iphone с предком мастера ? Подумай об этом.

Я настоятельно рекомендую вам прочитать Забавы со слиянием и назначением веток .

Если после прочтения этой статьи вы все еще чувствуете, что хотите объединить iphone и master, @seanhodges объяснит, как действительно хорошо справляться с конфликтами.

2
ответ дан 24 November 2019 в 17:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: