Простая git концепция слияния - PullRequest
0 голосов
/ 02 мая 2020

Предположим, мне нужно объединить одну ветвь в другую.

Моя упрощенная концепция заключается в следующем:

  • git просматривает каждый файл в каждом конкретном пути и сравнивает два файла
    • git diffs файлы: если они похожи, все в порядке
    • , если нет, git пытается выполнить трехстороннее объединение с обоими файлами

Правильно ли это концептуально?

Ответы [ 2 ]

3 голосов
/ 02 мая 2020

Это в основном верно.

Во-первых, Git ищет базу слияния, которая обычно является последним общим коммитом между двумя коммитами, которые вы объединяете. Это то, с чем он сравнивает каждую из глав (коммитов, которые вы объединяете).

Затем он сравнивает один и тот же файл в каждом коммите. Если файл один и тот же (то есть его идентификатор объекта идентичен), то Git просто принимает это как результат, поскольку обе стороны имеют одно и то же.

Затем он ищет переименования, чтобы найти файлы, которые могли быть перемещены или скопированы. Поскольку мы ищем упрощенный ответ, мы пока проигнорируем их.

Если файлы не полностью идентичны, Git вычисляет различия между этим файлом в базе слияния и каждой головкой по очереди , Затем он создает файл с обоими наборами различий, который представляет собой трехстороннее слияние. Если он может сделать это успешно для каждого файла, то ваше слияние будет успешным. Если файл имеет разные изменения в одной и той же области с обеих сторон, возникает конфликт, который затем необходимо разрешить вручную.

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

1 голос
/ 02 мая 2020

Нет. Учитывая коммиты A и B для объединения, git не сравнивает A с B вообще. Что думает git, так это:

Учитывая, где делится история двух коммитов, что нужно, чтобы добраться от точки разделения до коммита А, и что нужно, чтобы добраться от точки разделения до совершить Б? Ну, если возможно, сделайте оба из этих вещей.

Другими словами, git находит коммит S, где истории A и B расходятся, и получает diff S -> A и diff S -> B и выполняет оба сравнения на S.

   diff1......
     /<------A
<- S 
     \<------B
   diff2......

Чтобы сделать это, он должен подумать о каждом файле в S и примените к нему два соответствующих diff-файла.

Результатом применения обоих diff-ов к S является новый коммит S ', родительские элементы которого A и B:

   diff1......
     /<------A <-\
<- S              S'
     \<------B <-/
   diff2......
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...