Разное

Эффективное слияние с использованием Git

Автор: Laura McKinney
Дата создания: 5 Апрель 2021
Дата обновления: 11 Май 2024
Anonim
7.1 Git – Слияние – "Истинное" слияние и разрешение конфликтов в git merge
Видео: 7.1 Git – Слияние – "Истинное" слияние и разрешение конфликтов в git merge

Содержание

Майк Шумейк был успешным разработчиком программного обеспечения в течение 20 лет, создавая качественные приложения и высокоэффективные команды разработчиков.

Расцвет Git

Похоже, что Git захватывает мир в том, что касается систем контроля версий. Десять лет назад наш интерес привлекла именно Subversion (красная линия ниже). Теперь Git (синяя линия) полностью контролирует ситуацию.

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


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

Риски, присущие Git Merges

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

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


Человек за занавеской: как работает Git?

Вы можете думать о слиянии Git как о перетасовке колоды карт. Git берет две отдельные колоды карт и сплетает их в одну колоду, подбрасывая дополнения при обнаружении дубликатов.

Пример: слияние коммитов

Рассмотрим пример ниже:

Это простой файл класса Groovy, который ничего не делает, кроме вызовов println (). Теперь два разработчика, Джим и Фред, изменили этот файл одновременно, и для разрешения этого потребуется слияние.

Каждый создал ветку, которая представляет собой просто имя, с которым может быть связана серия коммитов. Ветвь (то есть имя) напрямую связана с самой последней фиксацией, поэтому, когда выполняется новая фиксация, имя ветки перемещается на новое. Каждая фиксация указывает на своего предшественника (предшественников) - они никогда не указывают вперед.


Вот коммит Джима:

Обратите внимание, что Джим отредактировал строку 21, чтобы добавить комментарий, и Git рассматривает это как одно непрерывное изменение, которое включает удаление и добавление.

А вот и коммит Фреда:

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

Чтобы получить предварительный просмотр слияния, мы можем выделить оба коммита в SourceTree, щелкнуть исходный файл и просмотреть полученную разницу.

Когда выбраны оба коммита, мы видим разницу ниже:

Конфликты слияния

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

В этом примере мы уже видим, где будут возникать конфликты слияния:

  • строка 5
  • строка 21

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

Что происходит при слиянии

Вот результат фактического слияния:

Как видите, конфликты слияния проявились там, где их ожидали. Строки 29 и 30 считаются одним непрерывным изменением и поэтому вместе включаются в конфликт слияния. Поскольку другие изменения не перекрываются, Git может определить правильный порядок, а все остальное сделает за вас.

Акула в воде: Git помогает или больно?

Git определенно помогает нам в разрешении конфликтов. Разработчикам нравится эта функция! Многие из нас сильно полагаются на возможность автоматического слияния Git, как если бы Git - это футуристический андроид с безумными навыками программирования, который заботится о нашей легкой работе, поэтому нам не нужно ее беспокоить. И все же Git ничего не знает о контексте. Он не выполняет семантический синтаксический анализ и не может определить, действительно ли изменения из двух исходных файлов слияния принадлежат друг другу или являются взаимоисключающими.

Пример 2: ошибки при слиянии

Рассмотрим пример ниже:

Это очень простой исходный файл на Groovy с методом multiply (int, int) и основным методом, вызывающим multiply (). На самом деле это код, который находится во главе основной ветки ниже.

Фред добавил новый вызов метода multiply ():

Без ведома Фреда Джим решил отказаться от метода умножения, удалив его и зависимые от него вызовы методов.

Конечный результат слияния (показанный ниже) включает вызов метода multiply (), но теперь этот метод больше не существует.

Ошибка, которую трудно найти

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

Динамические языки (например, Groovy, Javascript, Python, Ruby и многие другие) особенно подвержены этой проблеме из-за ограниченной проверки во время компиляции. Хотя надежное покрытие модульных / интеграционных тестов, безусловно, полезно для выявления проблем, которые могут возникнуть в результате этого, команды часто не имеют покрытия, необходимого для защиты от вреда.

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

Вывод: проблемы с филиалами

Многие команды разработчиков приняли функциональные ветки как неотъемлемую часть своей модели ветвления. Функциональные ветки являются первоклассным гражданином популярного «GitFlow», и многие организации создали собственные модели ветвления, которые в значительной степени опираются на функциональные ветки. Ветви функций позволяют отдельным разработчикам работать изолированно до тех пор, пока их функция не будет завершена, поэтому на них не должны негативно повлиять чьи-то изменения. Некоторые организации заходят так далеко, что используют длинные ветки для изоляции целых команд, когда несколько команд работают с одной и той же кодовой базой. Другие используют их для изоляции нескольких выпусков, которые создаются одновременно.

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

Разработчиков учат, что давно работающие функциональные ветки - это нормально, если вы периодически объединяете новые изменения в целевой ветке (месте назначения для предстоящего слияния) в свою функциональную ветку. Это должно держать вас в соответствии со всеми остальными. К сожалению, это мираж. Если 5 разработчиков в команде работали над отдельными ветвями функций в течение некоторого времени, не имеет значения, как часто они объединяют целевую ветвь в свои соответствующие ветки. Они все еще не интегрированы. Произошло значительное количество изменений, которые никому не видны, потому что люди еще не готовы к объединению.

Что, если это не 5 разработчиков, а 25 или 75, работающих в одной кодовой базе? Эти слияния выполняются ближе к концу спринта, и на проверку того, что все было выполнено правильно, уходит очень много времени. Отсроченная интеграция всегда создает ненужный риск и часто прямо выражает его тогда, когда вы меньше всего этого хотите, - когда вы завершаете спринт или выпуск.

Магистральная разработка

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

Крупные функции разбиты на небольшие куски, и разработчики используют переключатель функций, чтобы скрыть свои изменения, пока не придет время для запуска. Это настоящая непрерывная интеграция, которая имеет для нас несколько важных последствий:

  • Нет функциональных веток, поэтому каждый разработчик строит сегодняшний код поверх кода, написанного вчера.
  • Никакого слияния ветвей - просто зафиксируйте и отправьте изменения в магистральную и обслуживающую ветки.
  • Ошибки, предназначенные для обслуживающей ветки, всегда сначала исправляются в основной ветви, а затем отбираются в обслуживаемой ветке (чтобы избежать проблем с регрессией).

Преимущества

  • Возможность конфликтов слияния резко сокращается. Меняется меньше кода, поэтому у нас мало возможностей для конфликта.
  • Частая фиксация в основной части заставляет разработчиков учитывать качество на протяжении всего цикла строительства, а не откладывать его до конца (небольшое изменение, тест, толчок; небольшое изменение, тест, толчок).
  • Конфликты выявляются на ранней стадии строительства, а не поздно во время слияния.
  • Непрерывная интеграция создает реальное окно в текущее состояние кода, выпуска и т. Д. Ничто не скрывается в тени.

Отложенная интеграция также может заставить вас стабилизировать один и тот же код несколько раз. Например, некоторые команды проводят тестирование и стабилизацию функций в ветке функций, чтобы ее можно было протестировать изолированно. Как только слияние действительно произойдет, вполне возможно, что функция дестабилизировалась, и теперь вам придется пройти этот процесс заново. Или вы можете предположить, что он стабилен, поскольку он работал в ветке функций, и просто позволить ему выйти за дверь таким образом. Всего этого можно было бы избежать, если бы мы просто интегрировались на ранней стадии.

Проблема не в Git; Как мы это используем

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

Эта статья точна и правдива, насколько известно автору. Контент предназначен только для информационных или развлекательных целей и не заменяет личного или профессионального совета по деловым, финансовым, юридическим или техническим вопросам.

Новые публикации

Увлекательные статьи

Запуск подкаста
Интернет

Запуск подкаста

Джон - заядлый писатель, геймер и любитель гитары. Бывший мастер по ремонту АКПП, сварщик и любитель игр.Подкасты - одна из самых привлекательных форм создания контента, возникающая из очага творчеств...
Обзор iClever Power Strip Tower: лучшая настольная зарядная станция
Компьютеры

Обзор iClever Power Strip Tower: лучшая настольная зарядная станция

Кшиштоф на всю жизнь увлечен технологиями будущего и расследует последние истории таких компаний, как Apple, am ung, Google и Amazon.Устройство защиты от перенапряжения iClever Power trip Tower - это ...