Иногда так хочетсябыстро закоммитить изменения с commit message «Remove debug log», «fix» или «fix fix fix»? Такие коммиты как грязные носки под кроватью: их не видно, пока не придёт ревьюер с пристальным взглядом или, что еще хуже, потенциальный работодатель, решивший посмотреть на ваш github.
К счастью, Git предлагает два супер-инструмента для того, чтобы история коммитов выглядела так, будто ты всегда знаешь, что делаешь: git commit --fixup
и git rebase --autosquash
. И сегодня мы разберем на практике как это применять.
Важно! Не надо применять rebase в main или stable-ветках, если не хотите, чтобы коллеги сделали вам больно.
Использование fixup и autosquash
1. Что делает fixup?
Команда git commit --fixup <commit>
говорит Git: «Я накосячил, но давай сделаем вид, что этого никогда не было». Она автоматически помечает коммит как исправление указанного коммита, чтобы позже их можно было объединить.
2. Как работает autosquash?
Команда git rebase -i --autosquash
делает всю грязную работу: находит fixup-коммиты и запихивает их обратно в родительский коммит, словно ничего и не происходило.
Практический пример
1. Делаем коммиты (как обычно, неидеально)
Представьте, что вы работаете в своей фича-ветке mvp-server
и делаете пару новых коммитов.
$ git add main.go
$ git commit -m "feat: listen port 8080"
[mvp-server dc4efa9] feat: listen port 8080
1 file changed, 1 insertion(+)
$ git add main.go
$ git commit -m "feat: added handlers"
[mvp-server ab604f9] feat: added handlers
1 file changed, 1 insertion(+), 1 deletion(-)
2. Упс… нашлась ошибка в первом коммите
Оказывается, в коммите с feat: listen port 8080
была опечатка, и теперь сервер запускается не на 8080
, а на 808
порту. Не беда, просто делаем fixup
. Но для начала надо найти тот коммит, который будем фиксить. В нашем случае это будет dc4efa9
.
$ git log --oneline
ab604f9 (HEAD -> mvp-server) feat: added handlers
dc4efa9 feat: listen port 8080
df9f0ae (main) mvp
$ git add main.go
$ git commit --fixup dc4efa9
[mvp-server 62e7318] fixup! feat: listen port 8080
Git сам добавляет fixup!
перед сообщением, как бы говоря: «Да‑да, я понял, ты хотел исправить, но давай замнем эту тему».
Если же настроен
git hook
(например, для добавления в начало commit message ID-таска), то можно воспользоваться --no-verify
, чтобы временно отключить хуки. В противном случае придется при rebase
руками прописывать fixup
для коммита-исправления при запуске интеграктивного ребейза с автосквошем.
$ git commit --no-verify --fixup <commit_hash>
3. Проверяем, что нас ждёт
$ git log --oneline
62e7318 (HEAD -> mvp-server) fixup! feat: listen port 8080
ab604f9 feat: added handlers
dc4efa9 feat: listen port 8080
df9f0ae (main) mvp
4. Применяем rebase и делаем вид, что всё было идеально с самого начала
Важно, что надо передать в rebase хеш последнего коммита, который вы хотите сохранить как есть, а не первого, который вы хотите поменять. В нашем случае это будет df9f0ae
, так как git будет менять как следующий за ним коммит dc4efa9 feat: listen port 8080
.
$ git rebase -i --autosquash df9f0ae
Редактор откроет вот такую картину:
pick dc4efa9 feat: listen port 8080
fixup 62e7318 fixup! feat: listen port 8080
pick ab604f9 feat: added handlers
Просто сохраняем, выходим и наслаждаемся магией.
5. Проверяем, что история коммитов идеальна
$ git log --oneline
a72151f (HEAD -> mvp-server) feat: added handlers
0441501 feat: listen port 8080
df9f0ae (main) mvp
$ git push --force-with-lease
Как будто всё было идеально с самого начала, а будущий работодатель уже шлет тебе оффер ибо таких красивых коммитов он еще в жизни не видел и не важно, что код не работает.
А на этом всё — спасибо за внимание. При желании заглядывайте в тележку.
Автор: itcaat