Кнопка злиття pull request на GitHub має три варіанти, і вони по-різному формують історію main.
Create a merge commit (git merge --no-ff):
* Merge pull request #412 from acme/csv-export
|\
| * add tests
| * fix typo
| * export service
|/
* previous commit
- зберігаються всі коміти гілки й сам факт злиття;
- легко відкотити весь PR одним
git revert -m 1 <merge>; - історія з «fix typo» і «wip» потрапляє в
main.
Squash and merge:
* Експорт вакансій у CSV (#412)
* previous commit
- усі коміти PR стискаються в один новий коміт;
- лінійна чиста історія: один PR - один коміт, легко шукати й відкочувати;
- проміжні коміти автора губляться (лишаються на сторінці PR);
- автор після злиття не може просто продовжити роботу в тій самій гілці - коміт у
mainмає інший SHA, і наступний PR покаже старі зміни ще раз.
Rebase and merge:
- кожен коміт PR переноситься на
mainокремо, без коміту злиття - лінійна історія з усіма комітами; - GitHub завжди створює нові SHA й оновлює дані комітера, навіть якщо можна було б просто перемотати гілку, і відкидає порожні коміти;
- доречно, коли автор ретельно впорядкував коміти й кожен має сенс сам по собі.
Як обрати:
| Ситуація | Підходить |
|---|---|
| коміти в PR «брудні», потрібна чиста історія | Squash |
| коміти атомарні й осмислені | Rebase |
| важливо бачити межі PR у графі | Merge commit |
Політика команди: у налаштуваннях репозиторію можна залишити лише один дозволений спосіб, щоб історія була однорідною. Для squash варто налаштувати, що заголовок коміту береться із заголовка PR, - тоді якість історії залежить від якості заголовків PR.