Как исправлять ошибки в Git, не оставляя улик

в 6:46, , рубрики: Git, github, gitlab

Иногда так хочетсябыстро закоммитить изменения с 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js