Я скажу, что я делаю в таком случае. Этот подход очень практичен и, вероятно, разные люди имеют разные личные предпочтения.
Я также, как и вы, стараюсь раздавить коммиты на 1 коммит в PR.
Итак, скажем, есть ветвь dev
.
Когда я запускаю ветвь функции, я делаю:
>> git checkout dev
>> git pull
>> git checkout -b feature_branch
>> commitA
>> commitB
>> git push -u origin feature_branch // now there is origin/feature_branch available to everyone
>> and create a PR when I'm ready
Теперь процесс идет так:
Люди проверяют мою работу и комментируют, я делаю свои изменения и фиксирую. Это своего рода петля,
это заканчивается, где все мы удовлетворены этими изменениями и готовы объединить вещи
>> commitC
>> commitD
Итак, теперь я готов "раздавить мои коммиты в один". Итак, я делаю:
>> // make sure I'm on feature_branch
>> git rebase -i HEAD~4
>> // at this point I have one 'beautiful' commit, lets_call it commit_TO_GO
>> git push -f //forcefully push my commits by overriding the current state of a remote branch in PR, this is not really important, only if I want to "preserve this state for backup or something
Пока эта ветвь не слита, я не против, это не имеет значения.
Давайте представим, что этот процесс занял некоторое время, а между тем в ветке origin/dev
(commitX, commitY и commitZ) были сделаны новые коммиты, выполненные другими товарищами по команде.
Итак, теперь я могу сделать следующее:
Слияние путем применения обычного трехстороннего слияния, если возникнут конфликты, я, конечно, сначала должен их разрешить.
Однако, поскольку я обеспокоен историей коммитов (как и вы), я делаю следующее:
>> git fetch --all
>> git rebase origin/dev
>> // at this point The my commit_TO_GO is applied on top of commitX,commitY,commitZ.
>> // technically it has a different sha1 now, but it's not really important, its
>> still my own branch, I do whatever I want there :)
>> git push -f // again forcefully push to origin/feature_branch
После этого шага origin/feature_branch
- это FF из origin/dev
, что круто, потому что я могу применить слияние, и оно будет в режиме FF, даже коммит слияния не будет создан.
Конечно, если есть конфликты, перебазирование не будет работать, сначала мне придется разрешить конфликты. Я делаю это в своей IDE, а затем продолжаю ребазирование (git rebase --continue
), но разрешение конфликта выходит за рамки этого вопроса
Теперь я готов объединить мои изменения с origin/dev
Обычно я делаю это в интерфейсе bitbucket / github.
После слияния история в origin/dev
выглядит красиво:
commitX->commitY->commitZ->commit_TO_GO
Результат: никаких слияний вообще нет, мой единственный коммит применяется последним
Одна точка для рассмотрения:
Его ничего не стоит перебирать из ветки dev даже во время разработки (пока вы работаете над feature_branch), просто чтобы убедиться, что он содержит последние изменения. Таким образом, вы можете проходить цикл столько раз, сколько захотите:
>> git fetch --all
>> git rebase origin/dev
Я понимаю, что, вероятно, у Git больше «быстрых команд» в рукавах, и, возможно, это объяснение было слишком подробным.