[Git] Хватит копировать, пора сливаться. Часть 1. Конфликт слияний (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Несмотря на распространённость операции git cherry-pick (копирование коммитов) в Git, обычно это не самое лучшее решение. Иногда это меньшее из двух зол, но я ещё не видел ситуации, где оно было бы целесообразно.
Это первая часть из серии статей, которые начинаются объяснением почему копирование это плохо, продолжаются рассказом почему это ужасно, а затем описывают как получить тот же результат, применяя слияние (merge). Я покажу как применить эту технику в случае, когда вам нужно сделать слияние со старыми коммитами (retroactive merge) и когда вы хотите исправить копирование на слияние пока не случилось чего-нибудь плохого.
В копировании задействованы две ветки: донорская (откуда берётся коммит) и принимающая (куда он копируется). Давайте назовём их соответственно master и feature. Для простоты предположим, что копируемый коммит содержит изменение только в одной строке единственного файла. На данной диаграмме каждый коммит помечен содержанием этой строки, а штрихованная стрелка означает само копирование (операцию git cherry-pick).
Имейте ввиду, что штрихованная стрелка не существует физически в репозитории, она только у нас в головах чтобы отслеживать хронологию.
Есть какой-то общий предок А с коммитом строки "apple". Далее ветки расходятся, коммит F1 лежит в ветке feature, а M1 в master. Эти коммиты не затрагивают рассматриваемую строку, поэтому они всё ещё помечены "apple". Затем мы фиксируем F2 в ветку feature, меняющую содержимое нашей строки на "berry", а затем копируем F2 в ветку master с названием M2.
Пока ничего необычного не происходит.
Время идёт, дерево репозитория обогащается новыми коммитами:
Мы зафиксировали М3 в ветку master и F3 в feature. Оба коммита обходят стороной нашу строку, поэтому она всё ещё равна "berry".
Пришло время слить feature в master. Так как строка одна и та же в обоих ветках, конфликтов не происходит, результат слияния всё ещё "berry".
Это лучший случай, но происходит он редко, особенно в репозиториях, над которыми активно работают много людей.
Давайте рассмотрим другой вариант. После копирования F2 мы фиксируем М3 в master и F3 в feature, но на этот раз F3 меняет нашу строку на "cherry". Такое может быть если программист, работающий над веткой feature, нашёл улучшение в коде, или менеджмент резко потребовал перевести весь проект на "cherry". Какова бы ни была причина, теперь дерево репозитория выглядит вот так:
На этот раз при слиянии feature в master происходит конфликт. Основание трехстороннего слияния (three-way merge) содержит "apple", входящая ветка feature содержит "cherry", а текущая — "berry".
<<<<<<<<<< HEAD (master)
berry
||||||||| merged common ancestors
apple
=========
cherry
>>>>>>>>>> feature
Конфликт возникает потому, что скопированные изменения затёрлись новыми, а сама информация о копировании не сохранилась. Вспомним, что штрихованная стрелка только у нас в голове.
Можно понадеяться на программиста, разрешающего конфликт, что он помнит историю изменений, или спросит команду чтобы понять что верным решением будет принять изменения из feature.
В случае только двух веток шансы на корректное разрешение довольно хорошие (коллизий не так много, программист не сильно устал и т.п). Но что будет если взять три ветки?
Снова начинаем с коммита А, где наша строка равна "apple". Сразу создаём ветку victim на основе A и фиксируем изменения в V1, не охватывающие нашу строку. Из V1 создаём третью ветку feature с той же историей: коммит F1 не охватывает рассматриваемую строку, поэтому пока она везде равна "apple". Тем временем в ветке master появляется новый коммит М1, который тоже не трогает нашу строку.
Продолжаем веселье. В ветке feature фиксируем изменение нашей строки на "berry" как F2, и копируем его в master под именем M2. Затем снова меняем нашу строку уже на "cherry" в feature и фиксируем это как F3. В master появляется новый коммит М3, который не трогает нашу строку, поэтому в master она пока равна "berry".
Тем временем ветка victim и знать не знает про наши "шуры-муры" с копированием из feature в master. В ней фиксируются два новых изменения V2 и V3, оставляющих нашу строку девственно равной "apple".
Всё хорошее должно когда-то заканчиваться, ветка feature сливается в victim, производя на свет фиксацию V4 с нашей строкой, равной "cherry" благодаря наследию из feature.
Расплачиваться за "непотребство" с копированием придётся ветке victim, когда в неё сливают master. Бум! Впервые возникает конфликт: "благородное" изменение F2 встречает своего клонированного двойника M2. Бедняга программист, разрешающий эту коллизию, не имеет понятия о копировании, к тому же он скорее всего уже устал от других (обоснованных) конфликтов, поэтому вряд ли сможет корректно разрешить и этот.
Вкратце, проблема: при git cherry-pick в дереве появляются две копии одного коммита. Если хотя бы одна из его строк поменяется до слияния её копий, то возникнет невынужденная коллизия. Причём это может произойти и через неделю, и через год. Это значит, что тот, кто будет её разрешать, может попросту не иметь ресурсов для принятия правильного решения (не он копировал, команда полностью поменялась и проч).
Однако, вся эта Санта-Барбара может стать ещё хуже если конфликта не произойдёт!
Почему? Читайте в следующей части.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Raymond Chen
===========Похожие новости:
- [Открытые данные, GitHub, Реверс-инжиниринг, Игры и игровые приставки] Разработчики закончили реверс-инжиниринг GTA III и Vice City и выпустили порты для разных платформ
- [Go, GitHub] Публикация Go приложения в GitHub
- Проект Tor представил систему анонимных тикетов для GitLab
- Проект SDL переходит на Git и GitHub
- [Open source, Git, Системы управления версиями, Системы сборки, DevOps] Вышел релиз GitLab 13.8 с редактором конвейеров и первой из метрик DORA (перевод)
- [Open source, Git, DevOps] GitLab oпрос — ждем Bаших предложений
- [INFOLUST, IT-стандарты, Социальные сети и сообщества] Почему я по-прежнему пользуюсь RSS (перевод)
- [Python, Big Data, GitHub] Я спарсил больше 1000 топовых Github-профилей по машинному обучению и вот что я узнал (перевод)
- [Open source, Разработка мобильных приложений, GitHub, Софт] На GitHub предлагают запустить каталог мобильных приложений
- [Git, GitHub] GIT для новичков (часть 1)
Теги для поиска: #_git, #_git_workflow, #_git, #_git
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 05:30
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Несмотря на распространённость операции git cherry-pick (копирование коммитов) в Git, обычно это не самое лучшее решение. Иногда это меньшее из двух зол, но я ещё не видел ситуации, где оно было бы целесообразно. Это первая часть из серии статей, которые начинаются объяснением почему копирование это плохо, продолжаются рассказом почему это ужасно, а затем описывают как получить тот же результат, применяя слияние (merge). Я покажу как применить эту технику в случае, когда вам нужно сделать слияние со старыми коммитами (retroactive merge) и когда вы хотите исправить копирование на слияние пока не случилось чего-нибудь плохого. В копировании задействованы две ветки: донорская (откуда берётся коммит) и принимающая (куда он копируется). Давайте назовём их соответственно master и feature. Для простоты предположим, что копируемый коммит содержит изменение только в одной строке единственного файла. На данной диаграмме каждый коммит помечен содержанием этой строки, а штрихованная стрелка означает само копирование (операцию git cherry-pick). Имейте ввиду, что штрихованная стрелка не существует физически в репозитории, она только у нас в головах чтобы отслеживать хронологию. Есть какой-то общий предок А с коммитом строки "apple". Далее ветки расходятся, коммит F1 лежит в ветке feature, а M1 в master. Эти коммиты не затрагивают рассматриваемую строку, поэтому они всё ещё помечены "apple". Затем мы фиксируем F2 в ветку feature, меняющую содержимое нашей строки на "berry", а затем копируем F2 в ветку master с названием M2. Пока ничего необычного не происходит. Время идёт, дерево репозитория обогащается новыми коммитами: Мы зафиксировали М3 в ветку master и F3 в feature. Оба коммита обходят стороной нашу строку, поэтому она всё ещё равна "berry". Пришло время слить feature в master. Так как строка одна и та же в обоих ветках, конфликтов не происходит, результат слияния всё ещё "berry". Это лучший случай, но происходит он редко, особенно в репозиториях, над которыми активно работают много людей. Давайте рассмотрим другой вариант. После копирования F2 мы фиксируем М3 в master и F3 в feature, но на этот раз F3 меняет нашу строку на "cherry". Такое может быть если программист, работающий над веткой feature, нашёл улучшение в коде, или менеджмент резко потребовал перевести весь проект на "cherry". Какова бы ни была причина, теперь дерево репозитория выглядит вот так: На этот раз при слиянии feature в master происходит конфликт. Основание трехстороннего слияния (three-way merge) содержит "apple", входящая ветка feature содержит "cherry", а текущая — "berry". <<<<<<<<<< HEAD (master)
berry ||||||||| merged common ancestors apple ========= cherry >>>>>>>>>> feature Конфликт возникает потому, что скопированные изменения затёрлись новыми, а сама информация о копировании не сохранилась. Вспомним, что штрихованная стрелка только у нас в голове. Можно понадеяться на программиста, разрешающего конфликт, что он помнит историю изменений, или спросит команду чтобы понять что верным решением будет принять изменения из feature. В случае только двух веток шансы на корректное разрешение довольно хорошие (коллизий не так много, программист не сильно устал и т.п). Но что будет если взять три ветки? Снова начинаем с коммита А, где наша строка равна "apple". Сразу создаём ветку victim на основе A и фиксируем изменения в V1, не охватывающие нашу строку. Из V1 создаём третью ветку feature с той же историей: коммит F1 не охватывает рассматриваемую строку, поэтому пока она везде равна "apple". Тем временем в ветке master появляется новый коммит М1, который тоже не трогает нашу строку. Продолжаем веселье. В ветке feature фиксируем изменение нашей строки на "berry" как F2, и копируем его в master под именем M2. Затем снова меняем нашу строку уже на "cherry" в feature и фиксируем это как F3. В master появляется новый коммит М3, который не трогает нашу строку, поэтому в master она пока равна "berry". Тем временем ветка victim и знать не знает про наши "шуры-муры" с копированием из feature в master. В ней фиксируются два новых изменения V2 и V3, оставляющих нашу строку девственно равной "apple". Всё хорошее должно когда-то заканчиваться, ветка feature сливается в victim, производя на свет фиксацию V4 с нашей строкой, равной "cherry" благодаря наследию из feature. Расплачиваться за "непотребство" с копированием придётся ветке victim, когда в неё сливают master. Бум! Впервые возникает конфликт: "благородное" изменение F2 встречает своего клонированного двойника M2. Бедняга программист, разрешающий эту коллизию, не имеет понятия о копировании, к тому же он скорее всего уже устал от других (обоснованных) конфликтов, поэтому вряд ли сможет корректно разрешить и этот. Вкратце, проблема: при git cherry-pick в дереве появляются две копии одного коммита. Если хотя бы одна из его строк поменяется до слияния её копий, то возникнет невынужденная коллизия. Причём это может произойти и через неделю, и через год. Это значит, что тот, кто будет её разрешать, может попросту не иметь ресурсов для принятия правильного решения (не он копировал, команда полностью поменялась и проч). Однако, вся эта Санта-Барбара может стать ещё хуже если конфликта не произойдёт! Почему? Читайте в следующей части. =========== Источник: habr.com =========== =========== Автор оригинала: Raymond Chen ===========Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 05:30
Часовой пояс: UTC + 5