Что значит Cherry Picking в тестировании
Когда это происходит: в том случае, если разработчам удалось создать большое количество новых фич, но менеджмент считает, что не стоит выкатывать сразу все.
Почему бы не выложить сразу все фичи:
git cherry-pick
В git существует команда
Прочитать спецификацию можно здесь
git cherry-pick-это мощная команда, которая позволяет выбирать произвольные коммиты Git по ссылке и добавлять их к текущей рабочей головке.
git cherry-pick может быть полезен для отмены изменений.
Например, предположим, что коммит случайно сделан не в ту ветвь.
Вы можете переключиться на правильную ветвь и выбрать фиксацию там, где она должна быть.
Когда использовать git cherry pick
git cherry-pick-полезный инструмент, но не всегда лучшая практика.
Сбор вишни может привести к дублированию коммитов, и во многих сценариях, где сбор вишни будет работать, вместо этого предпочтительны традиционные слияния.
С учетом сказанного git cherry-pick-это удобный инструмент для нескольких сценариев.
Командное сотрудничество.
Часто команда находит отдельных членов, работающих в одном и том же коде или вокруг него.
Возможно, новая функция продукта имеет бэкэнд и фронтенд-компонент.
Возможно, существует некоторый общий код между двумя секторами продукта.
Возможно, бэкэнд-разработчик создает структуру данных, которую также должен будет использовать фронтэнд.
Фронтенд-разработчик может использовать git cherry-pick для выбора коммита, в котором была создана эта гипотетическая структура данных.
Этот выбор позволит разработчику frontend продолжить работу над своей частью проекта.
Исправления ошибок
При обнаружении ошибки важно как можно быстрее доставить исправление конечным пользователям.
Например,предположим, что разработчик начал работу над новой функцией.
Во время разработки этой новой функции они выявляют уже существующую ошибку.
Разработчик создает явную фиксацию исправления этой ошибки.
Эта новая фиксация патча может быть выбрана непосредственно в главной ветви, чтобы исправить ошибку, прежде чем она повлияет на большее количество пользователей.
Отмена изменений и восстановление потерянных коммитов
Иногда ветвь функции может устареть и не слиться с мастером.
Иногда запрос на вытягивание может быть закрыт без слияния.
Git никогда не теряет эти коммиты, и с помощью таких команд, как git log и git reflog, их можно найти и вернуть к жизни.
Как использовать git cherry pick
Чтобы продемонстрировать, как использовать git cherry-pick, предположим, что у нас есть репозиторий со следующим состоянием ветви:
использование git cherry-pick является прямым и может быть выполнено следующим образом:
git cherry-pick commitSha
Нужную commit reference можно найти с помощью git log.
В этом примере мы хотим черрипикнуть commit `f` в master.
Сначала мы удостоверяемся, что работаем над master.
git checkout master
Затем мы выполняем cherry-pick следующей командой:
После выполнения наша git history будет выглядеть так:
Коммит f был успешно черрипикнут в главную ветвь
Примеры git cherry pick
git cherry pick также может выполнен с различными опциями:
В дополнение к этим полезным опциям git cherry-pick также принимает различные варианты стратегии слияния.
Подробнее об этих параметрах читайте в документации git merge strategies.
Резюме
Коммиты — это снимки, а не различия
Git имеет репутацию запутывающего инструмента. Пользователи натыкаются на терминологию и формулировки, которые вводят в заблуждение. Это более всего проявляется в «перезаписывающих» историю командах, таких как git cherry-pick или git rebase. По моему опыту, первопричина путаницы — интерпретация коммитов как различий, которые можно перетасовать. Однако коммиты — это не различия, а снимки! Я считаю, что Git станет понятным, если поднять занавес и посмотреть, как он хранит данные репозитория. Изучив модель хранения данных мы посмотрим, как новый взгляд помогает понять команды, такие как git cherry-pick и git rebase.
Если хочется углубиться по-настоящему, читайте главу о внутренней работе Git (Git internals) книги Pro Git. Я буду работать с репозиторием git/git версии v2.29.2. Просто повторяйте команды за мной, чтобы немного попрактиковаться.
Хеши — идентификаторы объектов
Самое важное, что нужно знать о Git-объектах, — это то, что Git ссылается на каждый из них по идентификатору объекта (OID для краткости), даёт объекту уникальное имя.
Мы привыкли к тому, что OID даны в виде укороченной шестнадцатеричной строки. Строка рассчитана так, чтобы только один объект в репозитории имел совпадающий с ней OID. Если запросить объект слишком коротким OID, мы увидим список соответствующих подстроке OID.
Блобы — это содержимое файлов
На нижнем уровне объектной модели блобы — содержимое файла. Чтобы обнаружить OID файла текущей ревизии, запустите git rev-parse HEAD:
Если я отредактирую файл README.md на моём диске, то git status предупредит, что файл недавно изменился, и хэширует его содержимое. Когда содержимое файла не совпадает с текущим OID в HEAD:README.md, git status сообщает о файле как о «модифицированном на диске». Таким образом видно, совпадает ли содержимое файла в текущей рабочей директории с ожидаемым содержимым в HEAD.
Деревья — это списки каталогов
Обратите внимание, что блобы хранят содержание файла, но не его имя. Имена берутся из представления каталогов Git — деревьев. Дерево — это упорядоченный список путей в паре с типами объектов, режимами файлов и OID для объекта по этому пути. Подкаталоги также представлены в виде деревьев, поэтому деревья могут указывать на другие деревья!
Воспользуемся диаграммами, чтобы визуализировать связи объектов между собой. Красные квадраты — наши блобы, а треугольники — деревья.
Деревья дают названия каждому подпункту и также содержат такую информацию, как разрешения на файлы в Unix, тип объекта (blob или tree) и OID каждой записи. Мы вырезаем выходные данные из 15 верхних записей, но можем использовать grep, чтобы обнаружить, что в этом дереве есть запись README.md, которая указывает на предыдущий OID блоба.
При помощи путей деревья могут указывать на блобы и другие деревья. Имейте в виду, что эти отношения идут в паре с именами путей, но мы не всегда показываем эти имена на диаграммах.
Само дерево не знает, где внутри репозитория оно находится, то есть указывать на дерево — роль объектов. Дерево, на которое ссылается ^
Коммиты — это снапшоты
Коммит — это снимок во времени. Каждый содержит указатель на своё корневое дерево, представляющее состояние рабочего каталога на момент снимка.
В коммите есть список родительских коммитов, соответствующих предыдущим снимкам. Коммит без родителей — это корневой коммит, а коммит с несколькими родителями — это коммит слияния.
Коммиты также содержат метаданные, которые описывают снимки, например автора и коммиттера (включая имя, адрес электронной почты и дату) и сообщение о коммите. Сообщение о коммите для автора коммита — это возможность описать цель коммита по отношению к родителям.
Например, коммит в v2.29.2 в Git-репозитории описывает этот релиз, также он авторизован, а его автор — член команды разработки Git.
Заглянув немного дальше в историю при помощи git log, мы увидим более подробное сообщение о коммите, оно рассказывает об изменении между этим коммитом и его родителем.
Круги на диаграммах будут представлять коммиты:
Квадраты — это блобы. Они представляют содержимое файла.
Треугольники — это деревья. Они представляют каталоги.
Круги — это коммиты. Снапшоты во времени.
Ветви — это указатели
В Git мы перемещаемся по истории и вносим изменения, в основном не обращаясь к OID. Это связано с тем, что ветви дают указатели на интересующие нас коммиты. Ветка с именем main — на самом деле ссылка в Git, она называется refs/heads/main. Файлы ссылок буквально содержат шестнадцатеричные строки, которые ссылаются на OID коммита. В процессе работы эти ссылки изменяются, указывая на другие коммиты.
Это означает, что ветки существенно отличаются от Git-объектов. Коммиты, деревья и блобы неизменяемы (иммутабельны), это означает, что вы не можете изменить их содержимое. Изменив его, вы получите другой хэш и, таким образом, новый OID со ссылкой на новый объект!
Общая картина
Посмотрим на всю картину. Ветви указывают на коммиты, коммиты — на другие коммиты и их корневые деревья, деревья указывают на блобы и другие деревья, а блобы не указывают ни на что. Вот диаграмма со всеми объектами сразу:
Время на диаграмме отсчитывается слева направо. Стрелки между коммитом и его родителями идут справа налево. У каждого коммита одно корневое дерево. HEAD указывает здесь на ветку main, а main указывает на самый недавний коммит.
Корневое дерево у этого коммита раскинулось полностью под ним, у остальных деревьев есть указывающие на эти объекты стрелки, потому что одни и те же объекты доступны из нескольких корневых деревьев! Эти деревья ссылаются на объекты по их OID (их содержимое), поэтому снимкам не нужно несколько копий одних и тех же данных. Таким образом, объектная модель Git образует дерево хешей.
Рассматривая объектную модель таким образом, мы видим, почему коммиты — это снимки: они непосредственно ссылаются на полное представление рабочего каталога коммита!
Вычисление различий
Несмотря на то, что коммиты — это снимки, мы часто смотрим на коммит в его историческом представлении или видим его на GitHub как diff. На самом же деле сообщение о коммите часто ссылается на различие. генерируемое динамически из данных снимка путём сравнения корневых деревьев коммита и его родителя. Git может сравнить не только соседние снимки, но и два любых снимка вообще.
Чтобы сравнить два коммита, сначала рассмотрите их корневые деревья, которые почти всегда отличаются друг от друга. Затем в поддеревьях выполните поиск в глубину, следуя по парам, когда пути для текущего дерева имеют разные OID.
В примере ниже корневые деревья имеют разные значения для docs, поэтому мы рекурсивно обходим их. Эти деревья имеют разные значения для M.md, таким образом, два блоба сравниваются построчно и отображается их различие. Внутри docs N.md по-прежнему тот же самый, так что пропускаем их и возвращаемся к корневому дереву. После этого корневое дерево видит, что каталоги things имеют одинаковые OID, так же как и записи README.md.
На диаграмме выше мы заметили, что дерево things не посещается никогда, а значит, не посещается ни один из его достижимых объектов. Таким образом, стоимость вычисления различий зависит от количества путей с разным содержимым.
Теперь, когда понятно, что коммиты — это снимки, можно динамически вычислять разницу между любыми двумя коммитами. Почему тогда этот факт не общеизвестен? Почему новые пользователи натыкаются на идею о том, что коммит — это различие?
Одна из моих любимых аналогий — дуализм коммитов как дуализм частиц, при котором иногда коммиты рассматриваются как снимки, а иногда — как различия. Суть дела в другом виде данных, которые не являются Git-объектами — в патчах.
Подождите, а что такое патч?
Патч — это текстовый документ, где описывается, как изменить существующую кодовую базу. Патчи — это способ самых разрозненных команд делиться кодом без коммитов в Git. Видно, как патчи перетасовываются в списке рассылки Git.
Патч содержит описание изменения и причину ценности этого изменения, сопровождаемые выводом diff. Идея такова: некий разработчик может рассматривать рассуждение как оправдание применения патча, отличающегося от копии кода нашего разработчика.
Git может преобразовать коммит в патч командой git format-patch. Затем патч может быть применён к Git-репозиторию командой git apply. В первые дни существования открытого исходного кода такой способ обмена доминировал, но большинство проектов перешли на обмен коммитами непосредственно через пул-реквесты.
Самая большая проблема с тем, чтобы делиться исправлениями, в том, что патч теряет родительскую информацию, а новый коммит имеет родителя, который одинаков с вашим HEAD. Более того, вы получаете другой коммит, даже если работаете с тем же родителем, что и раньше, из-за времени коммита, но при этом коммиттер меняется! Вот основная причина, по которой в объекте коммита Git есть разделение на «автора», и «коммиттера».
Самая большая проблема в работе с патчами заключается в том, что патч трудно применить, когда ваш рабочий каталог не совпадает с предыдущим коммитом отправителя. Потеря истории коммитов затрудняет разрешение конфликтов.
Идея перемещения патчей с места на место перешла в несколько команд Git как «перемещение коммитов». На самом же деле различие коммитов воспроизводится, создавая новые коммиты.
Если коммиты — это не различия, что делает git cherry-pick?
Вычисляет разницу между коммита и его родителя.
Применяет различие к текущему HEAD.
Создаёт новый коммит, корневое дерево которого соответствует новому рабочему каталогу, а родитель созданного коммита — HEAD.
Перемещает ссылку HEAD в этот новый коммит.
Важно понимать, что мы не «перемещали» коммит так, чтобы он был поверх нашего текущего HEAD, мы создали новый коммит, и его вывод diff совпадает со старым коммитом.
А что делает git rebase?
Команда git rebase — это способ переместить коммиты так, чтобы получить новую историю. В простой форме это на самом деле серия команд git cherry-pick, которая воспроизводит различия поверх другого, отличного коммита.
Затем команда rebase просто переходит в местоположению и выполняет команды git cherry-pick в этом диапазоне коммитов, начиная со старых. В конце мы получили новый набор коммитов с разными OID, но схожих с первоначальным диапазоном.
Для примера рассмотрим последовательность из трёх коммитов в текущей ветке HEAD с момента разветвления target. При запуске git rebase target, чтобы определить список коммитов A, B, и C, вычисляется общая база P. Затем поверх target они выбираются cherry-pick, чтобы создать новые коммиты A’, B’ и C’.
Коммиты A’, B’ и C’ — это совершенно новые коммиты с общим доступом к большому количеству информации через A, B и C, но они представляют собой отдельные новые объекты. На самом деле старые коммиты существуют в вашем репозитории до тех пор, пока не начнётся сбор мусора.
С помощью команды git range-diff мы даже можем посмотреть на различие двух диапазонов коммитов! Я использую несколько примеров коммитов в репозитории Git, чтобы сделать rebase на тег v2.29.2, а затем слегка изменю описание коммита.
Обратите внимание: результирующий range-diff утверждает, что коммиты 17e7dbbcbc и 2aa8919906 «равны», а это означает, что они будут генерировать один и тот же патч. Вторая пара коммитов различается: показано, что сообщение коммита изменилось, есть правка в README.md, которой не было в исходном коммите.
Если пройти вдоль дерева, вы увидите, что история коммитов всё ещё существует у обоих наборов коммитов. Новые коммиты имеют тег v2.29.2 — в истории это третий коммит, тогда как старые имеют тег v2.28.0 — болеее ранний, а в истории он также третий.
Если коммиты – не отличия, тогда как Git отслеживает переименования?
Внимательно посмотрев на объектную модель, вы заметите, что Git никогда не отслеживает изменения между коммитами в сохранённых объектных данных. Можно задаться вопросом: «Откуда Git знает, что произошло переименование?»
Git не отслеживает переименования. В нём нет структуры данных, которая хранила бы запись о том, что между коммитом и его родителем имело место переименование.
Вместо этого Git пытается обнаружить переименования во время динамического вычисления различий. Есть два этапа обнаружения переименований: именно переименования и редактирования.
После первого вычисления различий Git исследует внутренние различия, чтобы обнаружить, какие пути добавлены или удалены. Естественно, что перемещение файла из одного места в другое будет выглядеть как удаление из одного места и добавление в другое. Git попытается сопоставить эти действия, чтобы создать набор предполагаемых переименований.
На первом этапе этого алгоритма сопоставления рассматриваются OID добавленных и удалённых путей и проверяется их точное соответствие. Такие точные совпадения соединяются в пары.
Вторая стадия — дорогая часть вычислений: как обнаружить файлы, которые были переименованы и отредактированы? Посмотреть каждый добавленный файл и сравните этот файл с каждым удалённым, чтобы вычислить показатель схожести в процентах к общему количеству строк. По умолчанию что-либо, что превышает 50 % общих строк, засчитывается как потенциальное редактирование с переименованием. Алгоритм сравнивает эти пары до момента, пока не найдёт максимальное совпадение.
Вы заметили проблему? Этот алгоритм прогоняет A * D различий, где A — количество добавлений и D — количество удалений, то есть у него квадратичная сложность! Чтобы избежать слишком долгих вычислений по переименованию, Git пропустит часть с обнаружением редактирований с переименованием, если A + D больше внутреннего лимита. Ограничение можно изменить настройкой опции diff.renameLimit в конфигурации. Вы также можете полностью отказаться от алгоритма, просто отключив diff.renames.
Я воспользовался знаниями о процессе обнаружения переименований в своих собственных проектах. Например, форкнул VFS for Git, создал проект Scalar и хотел повторно использовать большое количество кода, но при этом существенно изменить структуру файла. Хотелось иметь возможность следить за историей версий в VFS for Git, поэтому рефакторинг состоял из двух этапов:
, чтобы посмотреть историю переименовывания.
Я сократил вывод: два этих последних коммита на самом деле не имеют пути, соответствующего Scalar/CommandLine/ScalarVerb.cs, вместо этого отслеживая предыдущий путь GVSF/GVFS/CommandLine/GVFSVerb.cs, потому что Git распознал точное переименование содержимого из коммита fb3a2a36 [RENAME] Rename all files.
Не обманывайтесь больше
Теперь вы знаете, что коммиты — это снапшоты, а не различия! Понимание этого поможет вам ориентироваться в работе с Git.
И теперь мы вооружены глубокими знаниями объектной модели Git. Не важно, какая у вас специализация, frontend, backend, или вовсе fullstack — вы можете использовать эти знания, чтобы развить свои навыки работы с командами Git’а или принять решение о рабочих процессах в вашей команде. А к нам можете приходить за более фундаментальными знаниями, чтобы иметь возможность повысить свою ценность как специалиста или вовсе сменить сферу.
Узнайте, как прокачаться в других специальностях или освоить их с нуля:
Git. Урок 5.
Слияние изменений и продвинутая
работа с ветками.
Команды: merge, cherry-pick, rebase.
1. Что такое слияние и зачем оно нужно.
2. Слияние в Git. Команда git merge.
2.1 Явное слияние
2.2 Неявное слияние (fast-forward)
2.3 В чем разница между fast-forward и явным слиянием?
3. Разрешение конфликтов слияния.
3.1. Ручное разрешение конфликта
3.2. Выбор одного из двух файлов
3.3. Тонкости разрешения merge-конфликтов.
3.4. Инструменты для разрешения merge-конфликтов.
4. Еще один способ объединения изменений из разных веток. Команда git rebase.
5. Интерактивный git rebase. Редактирование коммитов любой давности.
6. Берем вишенку с торта. Команда git cherry-pick.
То есть общий ход нашей работы выглядит следующим образом:
1. Решили добавить новую функцию – создали отдельную ветку. Дальше работаем в новой ветке.
2. Написали функцию, протестировали ее работу, внесли все необходимые исправления, еще раз протестировали и убедились, что функция работает исправно и не привнесла ошибок в остальной код.
3. Теперь нужно как-то перенести изменения с тестовой ветки на основную – в продакшн. Тут нам на помощь и приходит слияние: мы просто сливаем (т.е. переносим) изменения с нашей тестовой ветки в основную.
Итак, дадим определения:
Команда git merge
—abort
Ключ, использующийся только при разрешении конфликтов. Позволяет прервать слияние и вернуть все к моменту начала операции.
—continue
Ключ, использующийся только при разрешении конфликтов. Позволяет продолжить слияние после разрешения всех конфликтов.
2. 1. Явное слияние
Допустим, у нас есть граф вида:
Флаг —no-ff в данной ситуации необходим, поскольку мы хотим выполнить именно явное слияние. Подробнее о смысле этого флага мы поговорим чуть позже.
2.2. Неявное слияние
Давайте рассмотрим пример. Допустим, у нас есть все тот же граф репозитория:
Очень часто во время слияния веток оказывается, что ваши изменения удаляют или переписывают информацию в уже существующих файлах. Такая ситуация называется файловым конфликтом. Git останавливает выполнение слияния, пока вы не разрешите конфликт.
По сути, Git сталкивается с проблемой: у него есть два файла с одним и тем же именем, и он не знает, какой из них взять. Поэтому обращается к нам за помощью.
Давайте сразу начнем с примера и по ходу будем учиться разрешению конфликтов. Так будет нагляднее. Итак, допустим есть следующий репозиторий:
3.1. Ручное разрешение конфликта
3.2. Выбор одного из двух файлов
Дальше все стандартно: откроется редактор сообщения коммита. В сообщении следует указать, какие ветки вы сливали, и вкратце перечислить внесенные изменения.
3.3. Тонкости разрешения merge-конфликтов.
Теперь мы имеем представление, как разрешать конфликты слияния, и пришло время углубиться в эту тему. Поговорим о тонкостях, которые помогут вам понять, как правильно разрешить конфликт. Подчеркиваем: «правильно», поскольку разрешить конфликт не составляет труда, но если сделать это неверно, можно потерять код, написанный другими разработчиками.
Видно, что файлы различаются, но из этого представления совсем непонятно, что именно должно войти в итоговый файл. Если бы это был ваш личный проект, вы бы прекрасно знали, какой из файлов выбрать, но это чужой репозиторий и цена ошибки велика. Конечно, можно потратить много времени, перебирая коммиты из обеих веток, разбираясь, как менялись файлы, чтобы понять, что должно быть в итоговом файле. Но можно поступить проще. Прежде всего, давайте изучим немного теории.
Итак, при слиянии двух веток используются четыре состояния, и три из них необходимы, чтобы разрешить конфликт правильно. Давайте разбираться, что это за состояния.
Эти состояния можно изобразить на диаграмме следующим образом.
Чтобы понять, что изображено на диаграмме, полезно будет вспомнить, что такое дельта.
Дельта – это разность каких-то двух состояний. То есть по сути это информация о том, какие изменения вы внесли в файлы с момента определенного коммита. Как мы помним из второго урока данного курса, коммиты хранят именно дельты, а не полностью файлы. Благодаря этому репозиторий Git занимает очень мало места.
На диаграмме выше Дельта-1 – это разность текущего состояния ветки main и базы слияния. Аналогично Дельта-2 – это разность текущего состояния ветки develop и базы слияния.
Результат слияния нам как раз и нужно получить. Git пытается получить его автоматически, совмещая Дельту-1 и Дельту-2, но если эти дельты задевают одни и те же части одного и того же файла, возникает конфликт. При возникновении конфликта Git просит нас сравнить Дельту-1 и Дельту-2, чтобы составить из них третье состояние – результат слияния.
3.4. Инструменты для разрешения merge-конфликтов.
Использование графических утилит особенно удобно при сравнении больших файлов: почти во всех есть подсветка внесенных изменений, что поможет вам не запутаться в файле. Тем не менее при сравнении маленьких файлов часто можно обойтись одной консолью. Кстати, большинство IDE имеет встроенную утилиту для разрешения конфликтов, что сделает вашу работу с кодом еще более удобной.
Если говорить кратко, git rebase переносит коммиты текущей ветки на вершину переданной. Но перед тем, как перейти непосредственно к команде, давайте разберем принцип ее действия на примере. Пусть у нас есть репозиторий со следующим графом.
Команда git rebase
-i
—interative
Эти ключи позволяют нам делать rebase в интерактивном режиме. Мы будем активно пользоваться ими при редактировании старых коммитов.
—abort
Ключ, использующийся только при разрешении конфликтов. Позволяет прервать ребейз и вернуть все к моменту до начала операции.
—continue
Ключ, использующийся только при разрешении конфликтов. Позволяет продолжить ребейз после разрешения всех конфликтов.
—skip
Ключ, использующийся только при разрешении конфликтов. Позволяет пропустить текущий коммит.
После выполнения всех вышеуказанных операций, граф репозитория будет выглядеть так.
В предыдущем уроке мы с вами разобрали, помимо прочего, как можно объединить несколько последовательных коммитов в один и как редактировать содержимое и сообщение последнего коммита ветки. Но что если мы хотим отредактировать более ранний коммит? Git предоставляет нам и такую возможность. Правда тут мы воспользуемся небольшой хитростью.
На самом деле git rebase можно выполнять для одной и той же ветки. В обычном режиме это нам ничего не даст, но вот в интерактивном режиме мы сможем поменять сообщения, содержимое и вообще манипулировать коммитами, как нам только вздумается, вплоть до удаления. Давайте на примере разберем, как происходит изменение коммитов. Итак, допустим у нас есть репозиторий, граф которого выглядит так:
Команда git cherry-pick
-e
—edit
С этим ключом вы сможете отредактировать сообщение коммита.
-n
—no-commit
С этим ключом команда не создаст коммит на вашей ветке, а только скопирует все изменения в вашу рабочую копию. То есть с этим ключом данная команда идентичная git checkout *
—abort
Ключ, использующийся только при разрешении конфликтов. Позволяет прервать операцию и вернуть все к моменту до начала операции.
—continue
Ключ, использующийся только при разрешении конфликтов. Позволяет продолжить операцию после разрешения всех конфликтов.
Берет переданный коммит и создает в текущей ветке его точную копию.
Также в команду можно передать первый и последний коммит последовательности, тогда та же операция будет выполнена для всех коммитов последовательности.
1. Случай первый. Работа в команде.
Этот случай был описан во введении к данной части. Часто в команде несколько разработчиков работают над одним и тем же участком кода, но каждый – в своей ветке. Соответственно могут возникать ситуации, когда одному из разработчиков для реализации своей части задачи потребуется часть кода, написанная другим разработчиком. Merge в данном случае делать нерационально, поскольку ни одна из веток не пришла к своему логическому завершению, а вот cherry-pick – то, что надо.
2. Случай второй. Быстрые исправления багов.
Если в коде был обнаружен баг, очень важно как можно быстрее донести исправления до конечного пользователя. В таком случае, разработчик, обнаруживший ошибку, срочно создает коммит, в котором исправляет ее. Этот коммит может быть перенесен в основную ветку с помощью cherry-pick, чтобы не задерживать исправление бага слияниями в различные пре-релизные ветки.



















