Самый быстрый путь в мире — быть приземленным, эта статья включена【Колонка архитектурных технологий】Подпишитесь на это место, которым вы хотели бы поделиться.
Введение
Я использую git для совместной разработки несколькими людьми около трех лет Команды git, используемые в большинстве сценариев, можно пересчитать чуть более чем одной рукой.
- git add
- git commit
- git push
- git merge
- git pull
- git log
Теоретически, пока можно разумно управлять ветвями проекта, этих команд достаточно для всех ежедневных работ по разработке. Но если мы время от времени смотрим на наш git-граф, Боже мой, почему он такой запутанный.
Из-за путаницы с управлением ветвями (или вообще без управления ветвями) мы часто сталкиваемся с некоторыми неожиданными проблемами, поэтому нам нужно использовать множество команд git для решения наших проблем, таких как git rebase, упомянутый в этой статье.
Разница между git rebase и git merge
Китайское название Git rebase — rebase, что означает изменение базы записи коммита. В этой ссылке мы могли бы также принять это предположение: git rebase ≈ git merge и использовать две команды для реализации одного и того же рабочего процесса, чтобы сравнить сходства и различия между ними.
Вспоминая наш ежедневный рабочий процесс, предположим, что a и b — это два человека, работающих вместе над разработкой, тремя ответвлениями: development, development_a, develop_b. Два человека занимаются ежедневной разработкой веток develop_a и develop_b соответственно и поэтапно сливаются в разработку.
Тогда с точки зрения a возможный рабочий процесс будет выглядеть так:
(1) Отдельные лица разрабатывают свои собственные функции в ветке develop_a
(2) В течение этого периода другие могут продолжать добавлять новые функции в разработку.
(3) После завершения развития личных функций функции, разработанные другими, сливаются посредством слияния.
git merge
На приведенном выше рисунке показан ежедневный рабочий процесс слияния, а соответствующие команды операций git выглядят следующим образом:
git checkout develop_a
// 本地功能开发...
git pull origin develop = git fetch origin develop + git merge develop
git rebase
После того же рабочего процесса, если мы используем git rebase для реализации, результаты будут следующими:
Перед git rebase, как показано на рисунке:
В git rebase, как показано на рисунке:
После git rebase, как показано на рисунке:
Соответствующие команды для операции git rebase следующие:
git checkout develop_a
// 本地功能开发...
git fetch origin develop
git rebase develop
git checkout develop
git merge develop_a
git br -d develop_a
Видно, что сходства и различия между git rebase и git merge заключаются в следующем:
(1) Оба могут использоваться для слияния нативного кода.
(2) git merge хранит записи реальных пользовательских коммитов, иНовый коммит генерируется при слиянии
(3) git rebase перезапишет исторические записи отправки. Перезапись здесь не ограничивается структурой дерева, и идентификатор фиксации узла в дереве не будет перезаписан. Поэтому e' на рисунках 3 и 4 представляет e' на рис. 2, и преимущество заключается в том, что он может гарантировать, что запись отправки будет очень чистой.
Как использовать git rebase -i для изменения коммитов истории
git rebase -i, китайское название — интерактивная перебазировка. Это означает, что в процессе ребазинга можноВключите взаимодействие с пользователемДа, с помощью интерактивного процесса мы можем активно переписывать исторические записи отправки, включая изменение, слияние и удаление. Мы берем запись фиксации, полученную после использования rebase выше, в качестве примера для изменения исторической записи фиксации.До модификации запись фиксации выглядит следующим образом.
Процесс использования git rebase -i для изменения исторических коммитов в основном состоит из трех шагов:
(1) Перечислите объем записей отправки и укажите, какие записи вам нужно внести, какие изменения в этом объеме
(2) Выполните вышеуказанные модификации одну за другой, если возникнет какой-либо конфликт, его необходимо разрешить.
(3) Завершите операцию перебазирования
Взяв в качестве примера запись фиксации на приведенном выше снимке экрана, чтобы изменить сообщение фиксации, отправленное в истории, выполните следующие действия:
// 查看最近6次提交记录,选择对哪一条记录进行修改
git rebase -i HEAD~6
После выполнения вышеуказанной команды файл будет открыт в режиме vim, и информация о последних 6 фиксациях будет отображаться в файле сверху вниз и от дальнего к ближнему.
Как вы можете видеть из комментариев ниже, мы можем изменять, объединять и удалять записи истории, изменяя пикировку перед каждой строкой на r, s и d соответственно.
Во-первых, мы пытаемся изменить информацию о представлении, изменить выбор перед второй строкой на r, сохранить и выйти. Когда текущая страница будет закрыта, откроется новая страница, позволяющая редактировать выбранную информацию о коммите.
После редактирования информации сохраните и выйдите, и изменение исторической записи отправки будет завершено. Глядя на следующий рисунок, можно обнаружить, что сообщение фиксации в записи фиксации для develop_a по-прежнему feat_c, но сообщение фиксации соответствующей записи фиксации в ветке разработки стало feat: c-update..
Здесь следует отметить, чтоИдентификатор коммита одного и того же коммита в ветках develop и develop_a изменился, о чем еще будет упомянуто позже.
Помимо изменения отправленного сообщения фиксации, мы также можем изменить изменения, отправленные оценкой, изменив выбор на e в сочетании с git reset --soft HEAD^.
Действия по слиянию и удалению исторических материалов аналогичны действиям по редактированию, вам нужно только изменить выбор на s и d соответственно, вы можете попробовать это сами. Если во время процесса перебазирования возникает конфликт, его необходимо разрешить вручную, а затем использовать git rebase --continue для завершения операции перебазирования.
Подсказка git rebase по-прежнему очень удобна, она расскажет вам, что нужно сделать, чтобы решить текущую проблему.
Каковы правила, которые необходимо соблюдать, чтобы использовать git rebase -i?
С точки зрения изменения истории записей коммитов интерактивная перебазировка — очень мощная функция. Но для использования этой функции необходимо следовать железному правилу:Не перебазируйте коммиты из онлайн-веток!
Цитата из официального руководящего документа git, вероятно, выглядит так:
Если вы будете следовать этому золотому правилу, вы не ошибетесь. В противном случае люди будут ненавидеть вас, а ваши друзья и семья будут смеяться над вами и отвергать вас.
Прежде чем мы поговорим о том, почему вы не можете выполнить интерактивную перебазировку в онлайн-коммите, давайте поговорим о том, что делать, если вы хотите сделать это в онлайн-функции.
Во-первых, вам нужно успешно выполнить локальную перебазировку, а затем использовать git push -f, чтобы принудительно отправить и перезаписать соответствующую удаленную ветку Причина, по которой вам нужно выполнить перезапись, заключается в том, что если вы не перезапишете, новая фиксация будет сгенерирована после текущая перебазировка будет объединена с удаленной веткой Merge, что сделает ваше локальное перебазирование бессмысленным.
Поскольку мы упоминали выше, идентификатор фиксации всех узлов после перебазирования изменится.
По той же причине, даже если вы используете git push -f для перебазирования удаленной ветки, если в ветке разработки вашего коллеги все еще есть ветки, на которые вы нацелились при выполнении операции перебазирования (будь то изменение, слияние или удаление), то когда ваш коллега сливает ваш коммит, все, что вы хотите изменить с помощью ребазинга, возвращается!
Как исправить, если вы нарушаете правила использования git rebase -i
Здесь мы пытаемся описать результаты онлайн-подачи и перебазирования и как избежать этого результата в виде ключевых моментов:
(1) Вы перебазировали некоторые онлайн-заявки локально. Мы называем эту часть отправки a, а идентификатор фиксации a изменился после перебазирования.
(2) Эти коммиты, которые вы изменили локально, могут существовать в ветке разработки ваших коллег, которую мы называем b, они имеют то же содержимое, что и a, но разные идентификаторы коммитов.
(3) Если вы принудительно отправляете результат перебазирования в удаленный репозиторий, когда ваш коллега выполняет git pull локально, a и b будут объединены, и оба появятся в исторической фиксации, что сделает ваше поведение перебазирования недействительным.
(4) Мы хотим, чтобы, когда ваш коллега загружает онлайн-код, пропустить слияние a и b и просто объединить новые изменения в его локальной ветке.
Сказав так много, окончательный вывод состоит в том, чтобы использовать rebase для решения проблем, вызванных rebase. То есть ваш коллега использует git rebase для перебазирования своих локальных изменений в удаленную ветку, где вы выполнили перебазирование.
Короче говоря, ваши коллеги используют git pull --rebase вместо git pull для извлечения удаленной ветки. В процессе этой операции git проверит информацию нескольких упомянутых выше пунктов и сольет изменения, которые действительно принадлежат локальным коллегам, в последний из удаленной ветки.
Текстовое описание может быть немного вялым, более подробную информацию можно найти здесь:git-triplegate.com/book/this/v2/…
Итак, как мы должны использовать git rebase
Ввиду возможных проблем git rebase, описанных выше, последний вопрос, на который нужно ответить, заключается в том, как мы должны использовать git rebase в нашей повседневной работе, также заимствуя предложение из официальной документации git:
Общий принцип заключается в том, чтобы выполнять операции перебазирования только для локальных изменений, которые не были отправлены или переданы другим пользователям, для очистки истории, никогда не выполнять операции перебазирования для коммитов, которые были отправлены в другое место, так что вы можете пользоваться двумя способами (перебазирование и слияние). ) удобство.
Оригинальный адрес:www.mdeditor.tw/pl/pMHD
Автор: DevUI Команда Huawei