Ответ 1
Они на самом деле оба разумные требования. Я думаю, что "лучший ответ" заключается в том, что оба они ошибаются, хотя первая (версия kernel.org), вероятно, ближе.
Рассмотрим:
$ mkdir /tmp/repo && cd /tmp/repo
$ git init
Initialized empty Git repository in /tmp/repo/.git/
$ echo contents > file
$ git add file
$ git commit -m initial
[master (root-commit) e1731a6] initial
1 file changed, 1 insertion(+)
create mode 100644 file
Теперь у нас есть репозиторий с одной фиксацией, содержащей один файл.
$ echo second line >> file; git add file; echo contents > file
В этот момент индекс имеет file
с двумя строками в нем. Но рабочая версия file
имеет только одну строку в ней и соответствует тому, что в репозитории.
Является ли file
грязным? Ну, git status --short
говорит, что это, дважды (два M
s). Оба git diff
и git diff --cached
показывают изменения (так что да, это "грязно" ), но git diff HEAD
говорит, что нет изменений, и если мы git add
снова и попробуем git status
:
$ git status --short
MM file
$ git diff HEAD
$ git add file
$ git status
# On branch master
nothing to commit, working directory clean
Положите это нечетное изменение назад и сделайте еще одно. На этот раз используйте длинную форму git status
, чтобы она давала нам дополнительную информацию:
$ echo second line >> file; git add file; echo contents > file
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: file
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: file
#
В нем говорится, что мы можем использовать git reset
(то же самое, что и git reset --mixed
) с HEAD
, а имя файла - неактивное; неужели это сделает рабочий каталог грязным?: -)
$ git reset HEAD file
$ git status
# On branch master
nothing to commit, working directory clean
Нет, на самом деле, он снова очищает рабочий каталог! Это следует из (отсутствия) вывода git diff HEAD
: "un-staging" изменение, которое добавляет вторую строку, делает индекс ссылкой на версию HEAD
, а версия рабочего каталога совпадает с версией HEAD
, так что нестационарные "изменения, которые необходимо совершить" заставляют ничего не совершать и никаких изменений в рабочем каталоге.
"Правильное" определение, я думаю, что ваше дерево "чистое", если нет изменений в фиксации и никаких изменений между "деревом, поставленным для фиксации" (содержимым индекса) и "рабочим каталогом". Тем не менее, разумно спросить отдельно, является ли индекс чистым (т.е. Нет ничего поставленного для фиксации) и/или рабочее дерево является чистым (неизменным) относительно заполнения в пробе, где пустым может быть заполняется "промежуточной областью" или "фиксацией HEAD
".
Что git status
говорит вам, что это и ответ на вопрос: "что, если что-либо, поставлено для фиксации" и "что, если что-либо, отличается между деревом и индексом". Вы должны использовать git diff HEAD
(вы можете добавить --name-only
или аналогичный), чтобы увидеть, что, если что-либо, отличается между деревом работы и HEAD
фиксацией, если (как это часто бывает) индекс соответствует HEAD
commit.