Участвовать в проектах с открытым исходным кодом, отправив PR на Github, очень просто. Однако из-за высокой степени свободы самого Git некоторые PR, предлагаемые по желанию, на самом деле являются [грязными] PR, которые повлияют на историю проекта. Вот когда это происходит и как это улучшить с помощью рабочего процесса перебазирования.
Что такое грязный пиар
Мы знаем, что если вы хотите внести свой код в проект с открытым исходным кодом, общий процесс таков:
- форкнуть проект в собственный репозиторий.
- Зафиксируйте только что открытую ветку.
- Сделайте PR с просьбой к сопровождающему объединить вашу новую ветку с исходным проектом.
На последнем этапе ваш PR будет включать всю историю новой ветки. В настоящее время, если возникает одна из следующих ситуаций, здесь мы считаем этот PR [грязным] PR:
- Ветка PR и целевая ветка исходного репозиторияконфликт.
- PR содержит многоЗапись тривиальной фиксации,Такие как
fix bug
/add dev
и другие материалы, не имеющие практического значения. - PR содержит несколькоНенужные записи слияния. Вообще говоря, самый простой способ синхронизировать разветвленный склад с исходным складом — это
fetch
После того, как исходный склад будет HEADmerge
к текущей ветке. Каждый раз, когда эта операция выполняется, она оставляет похожийMerge xxx
запись фиксации. - PR содержитИзменения, не соответствующие теме, такие как оставление избыточных файлов журнала, добавление дополнительного кода отладки в другие модули и т. д.
Как справиться с грязным пиаром
внутренний проект
Вышеуказанные ситуации не являются проблемой при разработке внутренних проектов, размещенных на Stash или Gitlab, и есть очень простые решения:
- Конфликт? Тянуть главную ветку напрямую и тянуть вниз и менять, все равно все администраторы✌️
- Есть ли проблема с тем, как написать коммит? Разве это не просто время каждый день после работы?
- Проверьте наши
git log --graph
, как зрелищно! Все усердно работают, хорошо? - Просто делайте тест вовремя, плевать на эти детали🙄.
Не то чтобы с таким подходом были какие-то проблемы, особенно в бизнес-проектах с китайской спецификой, которые каждый день торопятся планировать, это в основном лучшая практика. Ниже мы сосредоточимся на способах повышения качества PR при более формальной подаче PR.
merge --squash
Github давно поддерживает принудительный сквош. Таким образом, сопровождающий исходного репозитория может сжать изменения в ветке, где был отправлен PR, в один коммит основного репозитория. Таким образом, какой бы грязной ни была ветка, создавшая PR, ее можно очистить при слиянии. Это примерно эквивалентно выполнению этого в командной строке:
git merge forked_lib/new_branch --squash
git commmit -m 'something from new_branch'
Это практика, официально поддерживаемая Github, но каковы ее ограничения? В основном эти два пункта:
- Для разрешения конфликтов и организации истории требуется первоначальный сопровождающий репозитория, а не PR-предлагатель.
- Несколько коммитов можно отсортировать только в один, а не в несколько.
Самая сложная проблема с этим подходом заключается в том, что он возлагает ответственность за редактирование истории коммитов на сопровождающего исходного репозитория, а коммиттер PR не может очистить историю перед фиксацией PR. Есть ли лучшее решение?
rebase
С помощью команды git rebase мы можем лучше контролировать историю коммитов git. Однако это также рискованная команда, поэтому рекомендуется немного понять ее принцип, прежде чем ее использовать.
Сначала предположим, что основной веткой проекта является master, а вы добавили в репозиторий из fork ветку dev. Вы начинаете с коммита m1 на master и делаете три коммита d1, d2 и d3 на dev. В это время мастер также дважды обновлял коммиты m2 и m3. На данный момент дерево версий примерно выглядит так:
m0 -- m1 -- m2 -- m3
|
d1 -- d2 -- d3
Тогда ваша цель состоит в том, чтобы зафиксировать три объединенных в новый devd
, чтобы история разработки выглядела так:
m0 -- m1 -- m2 -- m3 -- d
Для этого вы можете перебазировать dev на master:
git checkout dev
git rebase -i master
Принцип ребаза таков:
- Сначала найдите ближайшего общего предка m1 обеих ветвей (dev и master).
- Сравните предыдущие коммиты текущей ветки dev с m1, извлеките изменения и сохраните их как временные файлы.
- Укажите ветку на последний m3 от мастера.
- Примените изменения последовательно.
На этапе [Последовательное применение изменений] вы можете дополнительно выбрать, как обрабатывать сообщения фиксации d1, d2 и d3. в-i
После того, как параметр запустит интерактивную перебазировку, он войдет в интерфейс vim, и вы сможете выбрать, как работать с записью коммита на dev, которая выглядит так:
pick 91398f93 d1
pick 65efc762 d2
pick b82e050d d3
# Rebase 4652f96d..b82e050d onto 4652f96d (3 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Вы можете редактировать обработку этих коммитов в dev, например выбрать ввод для сохранения, ввод сквош для объединения содержимого коммита с предыдущим коммитом и т. д. После завершения выбора действия (здесь мы можем выбрать исправление d1 и d2 и переформулировать d3), введите:wq
Сохраните и выйдите, вы войдете в новое окно vim, где вы сможете дополнительно отредактировать новое сообщение коммита, а перебазирование вступит в силу после сохранения.Обратите внимание, что вам нужно выбрать хотя бы один коммит, который требует использования, иначе будет сообщено об ошибке.
После того, как ребаз вступит в силу, проверьте историю веток, не намного ли она чище? Отправьте более свежий PR в этом состоянии 😉
В качестве дополнительного напоминания: для репозиториев, которые разветвлялись несколько раз, перебазирование ствола исходного репозитория является опасной операцией. Кроме этого, безопасно использовать rebase для изменения истории частной ветки.
Оглядываясь назад на несколько проблем грязного пиара, как решить их с помощью rebase?
- При возникновении конфликта с удаленным главным репозиторием вы можете сначала получить удаленный репозиторий, а затем перебазировать свою ветку разработки на новый HEAD.
- Избыточные записи коммитов могут быть объединены непосредственно с помощью rebase.
- Как и в случае с 1, при перебазировании собственной ветки разработки в новую удаленную библиотеку HEAD не останется избыточных записей слияния.
- Отправьте новую фиксацию, чтобы исправить проблему, а затем перебазируйте.
На этом введение в rebase в целом закончено. Я надеюсь, что всем будет полезно лучше участвовать в проектах с открытым исходным кодом.
Ссылаться на: