Перебазинг и что такое ребазинг на нажатых коммитах

109

Часто говорят, что не следует перебазировать уже отправленные коммиты. Что это могло значить?

Хемант Кумар
источник

Ответы:

80

В книге ProGit есть хорошее объяснение .

Конкретный ответ на ваш вопрос можно найти в разделе « Опасности ребазинга ». Цитата из этого раздела:

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

Обновление:
судя по вашему комментарию ниже, похоже, что у вас проблемы с рабочим процессом Git. Вот несколько ссылок, которые могут помочь:

Тим Хениган
источник
Спасибо за объяснение. Итак, чтобы мое понимание было более ясным, после того, как я git rebaseвнесу определенные изменения, я не должен использовать (--interactive?), Чтобы переписать эту историю, это верный рецепт неудачи. С другой стороны, если я переустановил определенные изменения в теме ветвь (из ветки X) и нажмите ее, совершенно нормально выполнить повторную переустановку после того, как другой разработчик изменит ветку темы. По сути, я использую mergeдовольно давно , но мы находимся в той же лодке, что и darwinweb.net/articles/86, и история практически не используется.
Хемант Кумар
@Hemant: Rebasing коммитов после публикации в публичном репо, как правило, плохая идея. При этом совет из статьи darwinweb, которую вы процитировали, звучит разумно, если ваш рабочий процесс похож на их. См. Мой обновленный ответ со списком других ссылок, которые могут помочь.
Тим Хениган
Пожалуйста , обновите ссылку на страницу «ProGit» о «Private Managed Team» в git-scm.com/book/en/...
Eimantas
Таким образом, технически коммиты git остаются неизменными, но «отказ от существующих коммитов и создание новых, похожих, но разных» - это один и тот же коммит с другим идентификатором sha1? что ж, это был бы единственный очевидный способ понять, почему соавторы должны заново объединять свои собственные работы!
Ciasto piekarz
@Ciastopiekarz, это потому, что вы переписываете историю в исходном репозитории, а в локальных репозиториях других разработчиков могут быть указатели на это. Теперь их указатели устарели: у клиента git нет альтернативы, кроме как использовать более старые указатели и полагаться на человека, чтобы разобраться с остальным. Это повторное слияние, и оно может быть ОЧЕНЬ запутанным с множеством запутанных изменений, которые необходимо разобрать вручную! Таким образом, рекомендация никогда не перебазировать что-либо, что уже было помещено в вышестоящее репо. Это хороший совет, и его не следует игнорировать, если вы не эксперт с глубокими знаниями.
Forbin
240

Чтобы понять это, нам нужно немного понять, как работает git. Репозиторий git - это древовидная структура, в которой узлы дерева фиксируются. Вот пример очень простого репозитория: Когда вы разветвляетесь

у него есть четыре коммита в главной ветке, и у каждого коммита есть идентификатор (в данном случае a, b, c и d). Вы заметите, что d в настоящее время является последней фиксацией (или HEAD) основной ветки. введите описание изображения здесь

Здесь у нас есть две ветки: master и my-branch. Вы можете видеть, что master и my-branch содержат коммиты a и b, но затем они начинают расходиться: master содержит c и d, а my-branch содержит e и f. b считается «базой слияния» моей ветки по сравнению с master - или, чаще, просто «базой». В этом есть смысл: вы можете видеть, что моя ветка была основана на предыдущей версии master.

Итак, предположим, что my-branch устарел, и вы хотите обновить его до последней версии master. Другими словами, my-branch должен содержать c и d. Вы можете выполнить слияние, но это приведет к тому, что ветка будет содержать странные коммиты слияния, которые значительно усложнят просмотр запроса на перенос. Вместо этого вы можете выполнить перебазирование.

введите описание изображения здесь

Когда вы перебазируете, git находит базу вашей ветки (в данном случае b), находит все коммиты между этой базой и HEAD (в данном случае e и f) и повторно воспроизводит эти коммиты в HEAD ветки. вы переустанавливаете на (в данном случае master). Git фактически создает новые коммиты, которые представляют, как ваши изменения выглядят поверх master: на диаграмме эти коммиты называются e ′ и f ′. Git не стирает ваши предыдущие коммиты: e и f остаются нетронутыми, и если что-то пойдет не так с перебазированием, вы можете вернуться к тому, как было раньше.

Когда много разных людей работают над проектом одновременно, запросы на вытягивание могут быстро устареть. «Устаревший» запрос на вытягивание - это запрос, который больше не соответствует основной линии разработки, и его необходимо обновить, прежде чем его можно будет объединить в проект. Наиболее распространенная причина, по которой запросы на вытягивание устаревают, связана с конфликтами: если два запроса на вытягивание изменяют аналогичные строки в одном файле, и один запрос на вытягивание объединяется, в несмешанном запросе на вытягивание теперь будет конфликт. Иногда запрос на вытягивание может устареть без конфликтов: возможно, изменения в другом файле в кодовой базе требуют соответствующих изменений в вашем запросе на вытягивание, чтобы соответствовать новой архитектуре, или, возможно, ветвь была создана, когда кто-то случайно слил неудачные модульные тесты с главная ветка. Независимо от причины,

псевдокодер
источник
68

Ребазинг переписывает историю. Если об этой истории никто не знает, то это прекрасно. Однако, если эта история общеизвестна, то переписывание истории в Git работает точно так же, как и в реальном мире: вам нужен заговор.

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

Обратите внимание , что есть примеры успешных заговоров: puфилиал мерзавец хранилища Junio C. Hamano ( в официальном репозитории в Git SCM) является нормированным часто. Это работает так, что почти все, кто использует pu, также подписаны на список рассылки разработчиков Git, а факт puперебазирования ветки широко освещается в списке рассылки и на веб-сайте Git.

Йорг В. Миттаг
источник
4
+1. Я думаю, что puветка git.git - чрезвычайно полезный пример того, как использовать rebase в (публичном) рабочем процессе. Для тех, кто не знаком с этим, общая идея состоит в том, чтобы перебазировать ветки темы, в которых нет каких-либо коммитов next(нестабильная ветка непосредственно перед слиянием с мастером), а затем перестроить puветку, выполнив сброс nextи слияние всех ветвей темы. (Источник: Documentation / howto / keep-git.txt git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/… )
Cascabel
25
+1 за «переписывание истории в Git работает так же, как и в реальном мире: вам нужен заговор»
Sleeper Smith
«Публичное объявление не требуется, поскольку pu - это одноразовая ветвь, как описано выше». git-scm.com/docs/gitworkflows Мы делаем что-то похожее на работе, "TEMP-something-latest" - это ветка для выброса, которая представляет собой комбинацию последних изменений, это может быть слияние нескольких веток функций, может быть удалено и воссоздан в любой момент времени и не должен развиваться.
pilkch
6

Перебазирование изменяет историю вашего репозитория. Если вы отправляете коммиты в мир, то есть делаете их доступными для других, а затем меняете свой взгляд на историю коммитов, становится трудно работать с кем-либо, у кого есть ваша старая история.

Считаю, что ребасе, считающееся вредным, - хороший обзор.

дсолимано
источник