потому что файлы еще не поставлены
На самом деле это не совсем так. Но это тоже не совсем ложь.
Вот (глупый, предназначенный только для иллюстрации) хук перед фиксацией, чтобы продемонстрировать проблему:
$ cat .git/hooks/pre-commit
#! /bin/sh
echo \$GIT_INDEX_FILE = $GIT_INDEX_FILE
git diff-index --cached --name-only HEAD
exit 1
Этот хук использует правильную (во всяком случае, с точки зрения надежности) команду git diff-index --cached HEAD
для поиска имен промежуточных файлов. Однако сначала он печатает имя индекса, который используется для фиксации файлов. (Наконец, это предотвращает фиксацию, так как я действительно не хочу совершать что-либо из этого.)
Я сделал этот исполняемый файл (в репозитории Git для самого Git) и изменил несколько файлов без их git add
ing:
$ git status --short
M Makefile
M wt-status.c
(обратите внимание, что M
находятся во втором столбце). Затем:
$ git commit
$GIT_INDEX_FILE = .git/index
$ git commit -a
$GIT_INDEX_FILE = [redacted]/.git/index.lock
Makefile
wt-status.c
echo
первого вызова хука говорит нам, что мы используем реальный (основной) индекс, и его git diff-index
не выводит никаких результатов.
Второй вызов говорит нам, что мы используем альтернативный индексный файл с именем .git/index.lock
(я убрал исходный путь). Он показывает два подготовленных файла.
Давайте сделаем еще одну вещь: я сделаю git add
модифицированный Makefile
и внесу второе изменение в Makefile
. Теперь у нас есть:
$ git status --short
MM Makefile
M wt-status.c
Первая строка показывает нам, что HEAD:Makefile
(в фиксации, заморожено) отличается от :Makefile
(в индексе, поэтапно), которое отличается от Makefile
(в рабочем дереве, неустановлено), и действительно, мы можем видеть, что три файла разные:
$ git show HEAD:Makefile | head -2
# The default target of this Makefile is...
all::
$ git show :Makefile | head -2
#
# The default target of this Makefile is...
$ head -2 Makefile
# different
# The default target of this Makefile is...
Запуск git commit
против git commit -a
теперь дает:
$ git commit
$GIT_INDEX_FILE = .git/index
Makefile
$ git commit -a
$GIT_INDEX_FILE = [redacted]/.git/index.lock
Makefile
wt-status.c
Если бы я не предотвратил не--a
версию git commit
, то была бы зафиксирована git commit
версия Makefile
в (основном/реальном/.git/index
) индексе, а не версия в рабочем состоянии. дерево. Следовательно, если вы хотите проверить файлы, которые будут зафиксированы, вам следует заглянуть в файл index. Вы можете использовать git checkout-index
для извлечения файлов из индекса, но будьте осторожны, чтобы не стереть версии рабочего дерева, которые могут отличаться.
То, что было бы зафиксировано git commit -a
, — это версия Makefile в рабочем дереве, которую Git уже добавил в (нестандартный, временный) индекс .git/index.lock
. Как только git commit -a
завершится, этот нестандартный временный индекс станет настоящим индексом, уничтожив мою промежуточную, специально подготовленную копию Makefile
. Опять же, чтобы проверить файлы, которые будут зафиксированы, посмотрите в индексе — используя перенаправленный индекс, как Git автоматически, как для git diff-index
, так и для git checkout-index
.
(Поскольку я не совсем понимаю, что нужно вашему сценарию, я не могу дать конкретные рекомендации, как именно использовать git checkout-index
для извлечения интересующих файлов. Однако рассмотрите возможность использования --work-tree=
и временного каталога.)
(См. также мой ответ на Пропустить прошлую (полную) промежуточную область и напрямую зафиксировать файл или патч?, в котором обсуждается, что именно -a
, --only
и --include
действительно работают внутри компании.)
person
torek
schedule
24.01.2019