Гит

Интерактивный ребейз. Редактируем историю коммитов

Ситуация в репозитории: вы закинули коммит в ветку, но он не прошёл линтинг.

Если это что-то обыденное — скажем, Stylelint ругается на порядок стилей — можно исправить стилистические ошибки в коммите с заголовком style:

style: group styles by semantic categories

Но что, если изменений много и они однотипные?

chore: fix typo
style: remove an empty line
chore: fix typo again

Ещё хуже — что, если один из коммитов не прошёл валидацию commitlint, и это никак не поправить следующими коммитами?

refactor: use native `img` tag to allow changes without modifying `CommonImage` component and eliminate deep selector
✖   body's lines must not be longer than 100 characters [body-max-line-length]

Чтобы не засорять историю коммитов, разработчики используют force-push и интерактивное перебазирование.

Допустим, проблема появилась пять коммитов назад. Откатимся на пять коммитов:

git rebase -i HEAD~5

В редакторе появится файл git-rebase-todo, в котором описаны будущие действия над коммитами:

pick ef913a5 feat: add new cool feature
pick cfa9220 chore: fix typo
pick ba334f2 style: remove an empty line
pick 9c13f61 chore: fix typo again
pick 0e2392e refactor: use native `img` tag to allow changes without modifying `CommonImage` component and eliminate deep selector

Вот основные команды:

  • pick оставляет коммит как есть.
  • reword позволяет переформулировать описание коммита.
  • edit позволяет вручную изменить что-то в коммите.
  • squash объединяет коммит с предыдущим, сохраняя их описание.
  • fixup делает то же, но стирает описание коммита, помеченного fixup.

Прочие команды смотрите в самом файле.

Отредактируем наши коммиты:

pick ef913a5 feat: add new cool feature
fixup cfa9220 chore: fix typo
fixup ba334f2 style: remove an empty line
fixup 9c13f61 chore: fix typo again
reword 0e2392e refactor: use native `img` tag to allow changes without modifying `CommonImage` component and eliminate deep selector

Гит предложит исправить текст коммита. В итоге получаем такую историю:

feat: add new cool feature
refactor: use native img tag to avoid modifying image component

feature теперь включает все исправления опечаток, а описание refactor стало короче, и линтер больше на него не ругается.

Чтобы перезаписать историю, форс-пушнем изменения:

git push --force

Must Watch

В курсе Ильи Кантора по Гиту есть серия уроков по редактированию коммитов. Здесь объясняется, например, как в процессе ребейза разбить один коммит на два:

Больше пользы — в плейлисте:

Курс по Гиту

💡 Подсказка: если вы работаете в VS Code, настройте, чтобы гитовские файлы открывались прямо в нём, а не где-нибудь в терминале:

git config --global core.editor "code --wait"