Ежедневный рабочий процесс — Примеры

Пример 1 — Две несвязанные правки в одном рабочем дереве

Разработчик исправил ошибку округления, переименовал несвязанный модуль и оставил отладочный print в той же сессии; состояние ниже — рабочее дерево. Скажите, почему коммитить всё сразу — проблема, затем подготовьте и закоммитьте изменения по отдельности.

git status --short
#  M src/price/round.ts        <- собственно исправление
#  M src/price/index.ts        <- переименование модуля
#  M src/cart.ts               <- отладочный print

Решение

git add -p src/cart.ts          # ответьте «нет» на фрагмент с отладочным print
git add src/price/round.ts
git commit -m "fix: округлять полпенни вверх в суммах цен"

git add src/price/index.ts
git commit -m "chore: переименовать модуль цен"
# src/cart.ts остаётся незакоммиченным, отладочный print на месте

Коммит хранит содержимое индекса, а не рабочего дерева, поэтому подготовка решает, что войдёт в снимок: коммит всего дерева смешал бы исправление поведения с переименованием, и исправление стало бы невозможно откатить отдельно. Интерактивная подготовка выбирает фрагменты, так что одно логическое изменение становится одним коммитом. Ловушка в том, что git add . — самое быстрое, что можно набрать, а путаница всплывает лишь недели спустя, когда кто-то хочет откатить исправление и не может без отката переименования.

Пример 2 — Четыре проблемы, которые все выглядят как отмена

Команда за один день сталкивается с четырьмя ситуациями ниже. Скажите, какая операция git соответствует каждой, и почему обращение не к той разрушительно.

1. в последнем коммите опечатка в сообщении; ничего не отправлено
2. последние три коммита были тупиком и существуют только локально
3. коммит, слитый вчера, вызвал сбой; коллеги его уже стянули
4. эксперимент в src/cart.ts нужно отбросить; сами коммиты в порядке

Решение

1. git commit --amend -m "fix: исправить округление в суммах цен"
2. git reset --hard HEAD~3          # только потому, что их нет ни у кого другого
3. git revert 9d8e7f                # новый коммит, обращающий старый
4. git restore src/cart.ts          # отбросить правки файла, историю сохранить

Каждая ситуация задаёт свой вопрос о том, какие коммиты двигаются и кто это заметит: amend заменяет один неотправленный коммит, reset двигает ветку назад через коммиты, которых нет ни у кого другого, revert добавляет коммит, так что все клоны сходятся, а restore трогает файлы, а не историю. Ловушка в том, что все четыре ощущаются как «отмена», поэтому в случае 3 тянутся к reset, который переписывает историю, уже имеющуюся у коллег, — и их следующая отправка тихо возвращает сбой.