Одним из преимуществ использования DVCS является рабочий процесс edit-commit-merge (по сравнению с edit-merge-commit, часто применяемый CVCS). Благодаря тому, что каждое уникальное изменение записывается в хранилище независимо от слияний, DAG точно отражает истинную родословную проекта.
Почему так много веб-сайтов говорят о желании «избежать коммитов слияния»? Разве слияние до фиксации или повторное изменение после слияния не затрудняет изоляцию регрессий, возврат прошлых изменений и т. Д.?
Уточнение: поведение по умолчанию для DVCS - создание коммитов слияния. Почему так много мест говорят о желании увидеть историю линейного развития, которая скрывает эти коммиты слияния?
version-control
git
dvcs
merging
Джейс Браунинг
источник
источник
git pull
)? Я понимаю, почему это может быть проблематично, но мой вопрос касается всех коммитов слияния.git pull --rebase == svn up
(свободные-равные, а не строгие-равные)Ответы:
Люди хотят избежать коммитов слияния, потому что это делает журнал красивее. Шутки в сторону. Похоже на централизованные журналы, с которыми они выросли, и локально они могут делать всю свою разработку в одной ветке. Нет никакой выгоды, кроме этой эстетики, и нескольких недостатков в дополнение к тем, которые вы упомянули, например, создание склонности к конфликтам при извлечении напрямую из коллеги без прохождения через «центральный» сервер.
источник
В двух словах:
git bisect
Линейная история позволяет вам точно определить источник ошибки.
Пример. Это наш начальный код:
Ветвь 1 выполняет некоторый рефакторинг, который
arg
больше не действует:В Branch 2 появилась новая функция, которую необходимо использовать
arg
:Не будет конфликтов слияния, однако была введена ошибка. К счастью, этот конкретный будет пойман на этапе компиляции, но нам не всегда так везет. Если ошибка проявляется как неожиданное поведение, а не ошибка компиляции, мы можем не найти ее в течение недели или двух. В этот момент
git bisect
на помощь!О дерьмо. Вот что он видит:
Поэтому, когда мы отправляемся,
git bisect
чтобы найти коммит, который нарушил сборку, он точно определит коммит слияния. Ну, это немного помогает, но по сути это указывает на пакет коммитов, а не на один. Все предки зеленые. С другой стороны, с перебазированием вы получаете линейную историю:Теперь,
git bisect
укажем на точный коммит, который сломал сборку. В идеале, сообщение о фиксации объяснит, что было задумано достаточно хорошо, чтобы выполнить другой рефакторинг и сразу же исправить ошибку.Эффект усугубляется только в больших проектах, когда сопровождающие не написали весь код, поэтому они не обязательно помнят, почему был сделан какой-либо конкретный коммит / для чего была создана каждая ветка. Таким образом, точное определение точного коммита (а затем возможность исследовать коммиты вокруг него) является большой помощью.
Тем не менее, я (в настоящее время) все еще предпочитаю слияние. Перебазирование в ветку релиза даст вам линейную историю для использования с
git bisect
сохранением истинной истории для повседневной работы.источник
gitk --all
чрезвычайно полезна (тем более, что у меня обычно есть 3-х веточные ветки в любой момент времени, и я переключаюсь между ними каждый день в зависимости от моего настроения в время).bisect
. Достаточно легко найти отдельные коммиты сblame
или другим,bisect
если вы хотите копать глубже. С линейной историей, слияние выполняется вне книги, поэтому вы больше не можете сказать, что проблема была в плохом слиянии. Это выглядит как идиот, использующий аргумент, который не существует, особенно если аргумент был удален несколькими коммитами ранее. Пытаться выяснить, почему он это сделал, гораздо сложнее, когда вы уничтожаете историю.Короче говоря, потому что слияние часто является другим местом для того, чтобы что-то пошло не так, и нужно всего лишь один раз пойти не так, чтобы люди очень боялись снова с этим сталкиваться (один раз укушенный дважды, если хотите).
Итак, допустим, мы работаем над новым экраном управления учетной записью, и оказывается, что в рабочем процессе «Новая учетная запись» обнаружена ошибка. Хорошо, мы выбираем два разных пути - вы заканчиваете управление учетными записями, а я исправляю ошибку с новыми учетными записями. Поскольку мы оба имеем дело с учетными записями, мы работали с очень похожим кодом - возможно, нам даже пришлось настраивать одни и те же фрагменты кода.
Сейчас у нас есть две разные, но полностью работающие версии программного обеспечения. Мы оба выполнили фиксацию наших изменений, мы оба должным образом протестировали наш код, и независимо друг от друга мы уверены, что проделали отличную работу. Что теперь?
Что ж, пришло время слиться, но ... дерьмо, что теперь происходит? Мы могли бы очень хорошо перейти от двух рабочих наборов программного обеспечения к одному, унифицированному, ужасно сломанному куску недавно ошибочного программного обеспечения, в котором ваше Управление учетными записями не работает, а Новые учетные записи повреждены, и я даже не знаю, сохранилась ли старая ошибка. ,
Возможно, программное обеспечение было умным, и в нем говорилось о конфликте, и настаивали на том, чтобы мы давали ему указания. Ну, дерьмо - я сажусь, чтобы сделать это, и вижу, что вы добавили какой-то сложный код, который я не сразу понимаю. Я думаю, что это противоречит внесенным мною изменениям ... Я спрашиваю вас, и когда у вас появляется минутка, вы проверяете и видите мой код, который вы не понимаете. Один или оба из нас должны занять время, чтобы сесть, составить правильное слияние и, возможно, перепроверить всю эту чертову вещь, чтобы убедиться, что мы ее не сломали.
Тем временем 8 других парней пишут код, как и садисты, я сделал несколько небольших исправлений ошибок и отправил их, прежде чем узнал, что у нас конфликт слияния, и, кажется, настало время сделать перерыв, и, возможно, вы выходной или застрял на собрании или что-то еще. Может, мне просто взять отпуск? Или сменить карьеру.
И вот, чтобы избежать этого кошмара, некоторые люди стали очень бояться обязательств (что еще нового, не так ли?). Мы, естественно, рискуем избегать подобных сценариев - если только мы не думаем, что мы отстой и не собираемся все испортить, и в этом случае люди начинают действовать с опрометчивой энергией. вздох
Итак, поехали. Да, современные системы спроектированы так, чтобы облегчить эту боль, и предполагается, что она сможет легко отступать, перебазировать, обесценивать, freebase, hanglide и все такое.
Но это все больше работы, и мы просто хотим нажать кнопку на микроволновой печи и приготовить обед из 4 блюд, прежде чем мы успеем найти вилку, и все это кажется очень неэффективным - код это работа, он продуктивен, его значимое, но изящное управление слиянием просто не считается.
Программистам, как правило, приходится создавать отличную рабочую память, а затем иметь тенденцию сразу же забывать все эти ненужные и переменные имена и области видимости, как только они закончили проблему, и обрабатывать конфликт слияния (или, что еще хуже, ошибочно обработанное слияние) - это напоминание о вашей смертности.
источник
Перебазирование обеспечивает подвижную точку ветвления, которая упрощает процесс возврата изменений к базовой линии. Это позволяет обрабатывать ветку с длительным сроком действия так, как если бы это было локальное изменение. Без перебазирования ветви накапливают изменения от базовой линии, которые будут включены в изменения, сливаемые назад с базовой линией.
Слияние оставляет вашу базовую линию в исходной точке ветвления. Если вы объединяете несколько недель изменений из линии, от которой вы ответвились, у вас теперь есть много изменений из вашей точки ветвления, многие из которых будут в вашей базовой линии. Это затрудняет выявление ваших изменений в вашей ветке. Выдвижение изменений обратно к базовой линии может привести к конфликтам, не связанным с вашими изменениями. В случае конфликтов возможно продвижение противоречивых изменений. Текущие слияния требуют усилий для управления, и относительно легко потерять изменения.
Rebase перемещает точку ветвления к последней редакции вашей базовой линии. Все конфликты, с которыми вы столкнетесь, будут касаться только ваших изменений. Продвигать изменения намного проще. Конфликты рассматриваются в локальной ветке путем дополнительной перебазировки. В случае противоречивых толчков, последний, кто подтолкнет их изменение, должен будет решить проблему с их изменением.
источник
Автоматизированные инструменты улучшают то, что код слияния будет компилироваться и выполняться, таким образом избегая синтаксических конфликтов , но они не могут гарантировать отсутствие логических конфликтов, которые могут возникнуть при слияниях. Таким образом, «успешное» слияние дает вам чувство ложной уверенности, когда на самом деле оно ничего не гарантирует, и вы должны повторить все свои испытания.
Реальная проблема с ветвлением и слиянием, на мой взгляд, состоит в том, что он пинает банку пословиц в будущем. Это позволяет вам говорить «Я просто буду работать в своем маленьком мире» в течение недели и решать любые возникающие проблемы позже. Но исправлять ошибки всегда быстрее / дешевле, когда они свежие. К тому времени, когда все ветви кода начнут объединяться, вы уже можете забыть некоторые нюансы того, что было сделано.
Возьмите две вышеупомянутые проблемы вместе, и вы можете оказаться в ситуации, когда проще и проще заставить всех работать из одной линии и постоянно разрешать конфликты по мере их возникновения, даже если они делают активную разработку немного медленнее.
источник
Еще один важный момент: с помощью перебазирования я могу легко выбрать или отменить функцию в моей ветке релизов.
источник
git cherry-pick -x <commit>
для применения к ветке релиза. Или мы могли бы отменить что-то для релиза, сgit revert <commit>
. Если<commit>
это слияние, оно становится волосатым. Это является возможным, насколько я знаю, но не так легко сделать. При использовании rebase каждое «слияние» представляет собой один гигантский, но регулярный коммит, легко выбираемый через черри и обратимый.Три вещи не были сказаны ни в одном из ответов:
Разница внутри ветки:
Объединение одного элемента за раз:
Очистка перед нажатием:
источник