Является ли раздача коммитами в одну лучшую практику (для этого конкретного рабочего процесса)?
У меня есть следующий рабочий процесс git
:
- Создать новую ветку функций
- Работа с веткой функций
- Часто фиксировать
- Как только функция будет завершена, объединитесь в
master
branch
- Промыть и повторить
Однако иногда мне приходится возвращать целую функцию от мастера. Это может быть связано с большим количеством revert
ing. (Причина необходимости возврата функции - у меня есть веб-сайт, который работает с одним репо. Оттуда мы используем script, который развертывает сайт либо на нашем производственном сайте, либо на промежуточном сайте. Оба выполняются из нашей главной ветки Не спрашивайте, это то, с чем мне пришлось работать. Иногда я работаю над чем-то, что я ставил, но затем нужно немедленно внести изменения, поэтому мне нужно было каким-то образом изменить мои чтобы очистить репо.)
Я думаю, что самый простой способ сделать это - если каждая ветвь функции имеет только одну фиксацию. Тогда я мог бы revert
совершить. Поэтому, естественно, я думаю о том, чтобы сжать все фиксации ветки признака в одну, до слияния ее с master
.
Итак, теперь мой рабочий процесс будет выглядеть так:
- Создать новую ветку функций
- Работа с веткой функций
- Часто фиксировать
- После завершения функции git rebase -i HEAD ~ number_of_commits (или если удаленная ветка доступна, origin/feature_branch)
Есть ли проблемы с этой логикой? Это противоречит лучшим методам? Я сам тестировал себя, и весь рабочий процесс, по-видимому, прошел гладко и решает мою проблему, но я хотел запустить эту идею другими (более умными) Git -er, чтобы убедиться, что с этим что-то не так.
Спасибо!
Ответы
Ответ 1
Вы должны посмотреть на использование возможности слияния сквоша git i.e. git merge --squash
, чтобы вы не переписывали историю без необходимости.
Оба git merge --squash
и git rebase --interactive
могут использоваться для создания сжатого фиксации с тем же результирующим деревом, но они предназначены для выполнения двух совершенно разных целей. В обоих случаях ваше дерево в конечном итоге выглядит разным.
Исходное дерево:
a -- b -- c -- d master
\
\-- e -- f feature1
После git checkout master; git merge --squash feature1; git commit
:
a -- b -- c -- d -- F master
\
\-- e -- f feature1
После git checkout master; git rebase -i feature1
и выбрав pick c
и squash d
:
a -- b /-- F master
\ /
\-- e -- f feature1
Как вы можете видеть из разницы, вы не переписываете историю любой ветки при использовании git merge --squash
, но в результате вы переписываете историю master
при использовании git rebase -i
.
Также обратите внимание, что фактические фиксации (для тех, которые были раздавлены) будут присутствовать в вашей истории git в обоих случаях только до тех пор, пока у вас есть ссылка на ветку или тег, через которые эти коммиты достижимы.
Другими словами, в приведенном выше примере, если вы удалите feature1
после выполнения merge --squash
, вы не сможете фактически просмотреть коммиты e
или f
в будущем (особенно после 90 дней период рефлекса). То же самое относится к коммитам c
и d
в примере rebase
.
Ответ 2
Один из недостатков вашего подхода заключается в том, что он значительно снижает полезность git bisect
при отслеживании ошибок в вашем коде.
Тем не менее, если вы обнаружите, что достаточно часто возвращаете всю функцию, чтобы найти способы оптимизации этого процесса, вы можете спросить себя, слишком ли сливаетесь в master
. Возможно, вам захочется рассмотреть несколько длинных ветвей, чтобы настроить рабочий процесс, который лучше подходит для вашего проекта.