Как выровнять коммит, а не рабочий каталог?
У меня раздражающая проблема. Мы работаем с линтингом как зацепка перед фиксацией. Проблема заключается в том, что он связывает рабочий каталог, а не фактическую фиксацию. Есть две проблемы с этим:
Совершать это плохо, но долгая передача проходит.
Если вы забыли внести изменения после устранения проблем с линтингом, это то, что происходит.Фиксация это хорошо, но задержка не удалась.
У меня часто есть какой-то отладочный код, который я не собираюсь фиксировать. На самом деле нет смысла указывать эти изменения, и с этим надоедать.
Теперь вопрос в том, как я могу написать более умную ловушку перед фиксацией, которая связывает реальный коммит, а не рабочий каталог, предпочтительно без изменения рабочего каталога?
1 ответ
Это вообще довольно сложно.
Самый простой способ - извлечь индекс во временный каталог. Это имеет некоторые очевидные недостатки: в частности, игнорируемые файлы, которые находятся в рабочем дереве, не переносятся во временный каталог. Хуже того, временный каталог содержит только файлы этого репозитория: любая среда (например, субмодули и / или суперпроекты) не переносится.
Перенос этих вещей возможен, но потенциально занимает много места и / или времени.
Вот простой метод для переноса всего рабочего дерева (включая подмодули) во временный каталог, а затем извлечения содержимого индекса поверх него:
#! /bin/sh -e
tmpdir=$(mktemp -d)
trap "rm -rf $tmpdir" 0 1 2 3 15
# remainder assumes we are at top of work-tree, which is true in
# practice in git hooks, even if it is not documented anywhere.
# step 1: copy current tree to tmp dir
tar cf - . | (cd $tmpdir; tar xf -)
# step 2: extract current index to tmp dir
git --work-tree=$tmpdir checkout -- .
# step 3: run tests
... tests go here ...
Для ловушек перед фиксацией, которые хотели бы изменить файлы (например, используйте gofmt
или же clang-format
), это портит общую идею, поскольку теперь измененные файлы находятся во временном каталоге, который удаляется.