Восстановление и подстраховка

Восстановление и reflog

Git редко что-то теряет. Сложность — найти это снова.

Reflog

Каждое перемещение HEAD — и каждой ветки — с указанием причины: чекаут, сброс, ребейз, amend, форсированный фетч. Из любой прошлой записи можно переключиться на неё, создать от неё ветку или сделать на неё hard reset.

Просмотрщик reflog

Это и есть кнопка «я только что сбросил не ту ветку».

WIP-снимки

Незакоммиченная работа — единственное, что reflog спасти не может, поэтому Gitcito снимает её сам: всё рабочее дерево — изменённые, проиндексированные и неотслеживаемые файлы — коммитится через одноразовый индекс и закрепляется под refs/gitcito/wip. Ни ваш настоящий индекс, ни список стешей не затрагиваются.

WIP-снимки

Снимок делают три вещи:

Триггер Когда
Страж Автоматически, прямо перед разрушительным действием — отбросом изменений, очисткой, hard reset, восстановлением из коммита. Включён по умолчанию; переключается в диалоге снимков.
Таймер Каждые 5 / 15 / 30 минут, пока репозиторий открыт.
Вручную Кнопка Снимок сейчас.

Страж здесь важнее всего: работа обычно теряется навсегда в ту секунду, что следует за отбросом, которого вы не хотели. С включённым стражем это состояние — снимок: откройте список, нажмите «восстановить», выдохните.

Выберите снимок, чтобы увидеть захваченные им файлы, посмотреть изменение любого файла и восстановить один файл или всё дерево. Восстановление копирует файлы из снимка поверх текущих копий — сначала делается снимок стража, так что само восстановление тоже можно отменить.

Ограничения, о которых стоит знать. Срабатывание таймера или стража, не нашедшее ничего нового, ничего не записывает. Восстановление перезаписывает и воссоздаёт файлы, но никогда не удаляет файл, созданный после снимка. Игнорируемые файлы не захватываются. Снимки — локальные скрытые ссылки: никогда не пушатся, защищены от git gc, хранятся 50 новейших.

Bisect с подсказками

Помечайте коммиты как хорошие и плохие, смотрите, как сужается диапазон, приходите к первому плохому коммиту. Gitcito считает, сколько шагов осталось, — так что вы знаете, два вопроса до ответа или десять.

Bisect с подсказками

Пусть решает команда

Когда диапазон задан, Пусть решает команда передаёт весь поиск в git bisect run. Git выгружает каждого кандидата, запускает вашу команду и читает её код возврата:

Код возврата Что означает
0 Хороший — бага здесь нет
125 Этот протестировать нельзя, пропустить
что угодно ещё Плохой

Тестовый набор уже говорит на этом языке, поэтому npm test обычно и есть весь ответ. Gitcito предлагает скрипты самого проекта в один клик, стримит вывод по ходу дела и приходит к первому плохому коммиту, а вы не отвечаете ни на один вопрос.

Поле команды, готовое передать поиск тестовому набору

За чем следить. Команда выполняется на каждом коммите, который проверяет git, так что команда, которая деплоит, публикует или пишет за пределы репозитория, сделает это несколько раз подряд. Держитесь чего-то, что только читает и сообщает. Стоп убивает прогон и оставляет сессию открытой, чтобы вы продолжили помечать вручную; Прервать завершает bisect целиком.

Команда, которая падает по посторонней причине — скажем, из-за отсутствующей зависимости в этой точке истории, — пометит хороший коммит плохим и уведёт поиск не туда. Выход с кодом 125 из скрипта-обёртки — это способ git из этого выбраться.

Забытый файл блокировки

Git создаёт файл .lock рядом с тем, что собирается записать, и убирает его, когда запись завершилась. Процесс, умерший с блокировкой в руках — упавший редактор, терминал, закрытый во время git commit, fetch, убитый при чистке удалённых ссылок, — оставляет её, и с этого момента любая запись падает с одной и той же строкой:

error: could not delete references: cannot lock ref 'refs/remotes/origin/x':
Unable to create '…/refs/remotes/origin/x.lock': File exists.

Репозиторий не повреждён. Просто на пути лежит файл.

Сначала Gitcito повторяет попытку несколько раз: блокировка в руках работающего git обычно освобождается за миллисекунды. Если нет — ошибка открывает диалог вместо стены текста: все блокировки, ещё лежащие на диске, возраст каждой и одна кнопка, которая удаляет их и повторяет упавшую операцию.

Возраст — весь аргумент. Блокировка моложе 30 секунд считается принадлежащей ещё работающему git, и Gitcito отказывается её удалять — вместо этого предлагает подождать и повторить. Более старые предлагаются к удалению, от самой старой, и диалог прямо говорит, что проверить перед согласием: что сейчас в этом репозитории не работает ни редактор, ни терминал, ни другой Git-клиент. Убрать блокировку из-под живой записи — верный способ порвать индекс.

Обход охватывает собственный каталог git репозитория и общий каталог, так что блокировки связанного worktree тоже находятся. Подмодули пропускаются — они принадлежат другому репозиторию и чистятся его открытием.

Отмена и повтор

Большинство операций кладут запись в стек отмены, так что ⌘Z разворачивает последнюю там, где git это позволяет.

См. также: Что изменилось с тех пор · Стеши

Улучшить этот перевод на GitHub