Кто-нибудь может пояснить значение этих терминов? Являются ли отслеживаемые файлы файлами, которые в какой-то момент были добавлены на сцену? Является ли «индекс» таким же, как «стадия»? Отслеживаются ли все подготовленные файлы, но не всегда верно обратное (а именно, файлы, которые когда-то были подготовлены и зафиксированы, но не являются частью текущего этапа, подлежащего фиксации)? Как узнать, какие файлы отслеживаются? Как узнать, какие файлы помещены в промежуточные файлы?
Git отслеживаемый, неотслеживаемый, поэтапный, индексированный смысл?
Ответы (2)
Здесь нужно учитывать три вещи: текущий коммит (известный как HEAD
или @
), индекс и рабочее дерево.
Индекс также называется областью подготовки и кэшем. Они представляют его различные функции, потому что индекс делает больше, чем просто содержит содержимое предлагаемой следующей фиксации. Однако его использование в качестве кеша в основном незаметно: вы просто используете Git, а трюки с кешем, которые заставляют Git работать быстро, выполняются «под капотом» без необходимости ручного вмешательства. Таким образом, вам нужно только «кешировать», чтобы помнить, что некоторые команды используют --cached
, например, git diff --cached
и git rm --cached
. Некоторые из них имеют дополнительные имена (git diff --staged
), а некоторые нет.
Git не очень последователен в отношении того, где он использует каждый из этих терминов, поэтому вы должны просто запомнить их. Одна проблема заключается в том, что для многих пользователей «индекс» является загадочным. Вероятно, это связано с тем, что вы не можете увидеть его напрямую, кроме как с помощью git ls-files
(это неудобная команда: она предназначена для программирования, а не для повседневного использования).
Обратите внимание, что рабочее дерево (также называемое рабочим деревом, а иногда и рабочим каталогом или рабочим каталогом) совершенно отделено от индекса. Вы можете легко просматривать и изменять файлы в рабочем дереве.
Когда-то я думал, что слово «отслеживается» сложнее, но оказалось, что отслеживается буквально означает находится в индексе. Файл отслеживается тогда и только тогда, когда git ls-files
показывает, что он будет в следующей фиксации.
Вы не можете так легко увидеть файлы в индексе, но вы можете легко скопировать из рабочего дерева в индекс, используя git add
:
git add path/to/file.txt
копирует файл из рабочего дерева в индекс. Если его еще не было в индексе (не отслеживалось), то теперь оно есть в индексе (отслеживается).
Следовательно:
Являются ли отслеживаемые файлы файлами, которые в какой-то момент были добавлены на сцену?
Нет! Отслеживаемые файлы — это файлы, которые находятся в индексе прямо сейчас. Неважно, что произошло в прошлом, в любом коммите или в любой момент в прошлом. Если некоторый путь path/to/file.txt
присутствует в индексе прямо сейчас, этот файл отслеживается. В противном случае он не отслеживается (и потенциально также игнорируется).
Если path/to/file.txt
сейчас в индексе, а вы его убираете, то файл больше не отслеживается. Он может быть или не быть в каких-либо существующих коммитах, и он может быть или не быть в рабочем дереве.
Является ли «индекс» таким же, как «стадия»?
Да, более или менее. Различные документы и люди не очень последовательны в этом.
Отслеживаются ли все подготовленные файлы, но не всегда верно обратное (а именно, файлы, которые когда-то были подготовлены и зафиксированы, но не являются частью текущего этапа, подлежащего фиксации)?
Этот вопрос не имеет смысла, так как "промежуточная область" является индексом. Я думаю, что постановка не имеет точного определения, но я бы определил это так. Файл является помещенным, если:
- его нет в
@
/HEAD, а есть в индексе, или - находится как в
@
/ HEAD, и в индексе, и отличается в них.
Эквивалентно, вы можете сказать: «когда какой-то путь вызывается staged, это означает, что если я сделаю новую фиксацию прямо сейчас, новая версия фиксации этого файла будет отличаться от версии текущей фиксации». Обратите внимание: если вы никак не трогали файл, так что он находится в текущем коммите и в индексе, и в рабочем дереве, но все три версии совпадают, файл все равно будет зафиксирован. Просто это не "постановка" и не "модификация".
Как узнать, какие файлы отслеживаются?
Хотя git ls-files
может сообщить вам об этом, обычный способ узнать это косвенно: вы запускаете git status
.
Как узнать, какие файлы помещены в промежуточные файлы?
Принимая приведенное выше определение, вы должны попросить Git diff
текущий коммит (HEAD / @
) и индекс. Все, что между ними отличается, является «постановочным». Запуск git status
сделает это сравнение за вас и сообщит имена таких файлов (без отображения подробных различий).
Чтобы получить подробные различия, вы можете запустить git diff --cached
, который сравнивает HEAD
с индексом. У него также есть имя git diff --staged
(это имя лучше, но, возможно, просто для того, чтобы раздражать, --staged
недоступно в качестве опции для git rm
!).
Поскольку существует три копии каждого файла, вам нужно два сравнения, чтобы увидеть, что происходит:
- сравнить HEAD с индексом:
git diff --cached
- сравнить индекс с рабочим деревом:
git diff
Запуск git status
запускает для вас оба этих git diff
и суммирует их. Вы можете получить еще более короткую сводку с помощью git status --short
, где вы увидите такие вещи, как:
M a.txt
M b.txt
MM c.txt
Первый столбец является результатом сравнения HEAD
с индексом: пробел означает, что два совпадают, M
означает, что HEAD
и index
различаются. Второй столбец — результат сравнения индекса с рабочим деревом: пробел означает, что они совпадают, M
означает, что они различаются. Два M
подряд означают, что все три версии c.txt
различны. Вы не можете увидеть тот, что находится в указателе напрямую, но вы можете его git diff
!
Это может быть ясно, показывая, а не описывая.
Обратите внимание, что информация в ответе от @torek верна.
Напомним, что index, stage и cache — синонимы в git.
## No new files
$ git status
On branch master
nothing to commit, working tree clean
# So git shows no files or changes
## New file that is not tracked
$ touch foo
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
foo
nothing added to commit but untracked files present (use "git add" to track)
# So git realises there is a new file, but it is not tracking it
## Tracked but not staged
$ git add --intent-to-add foo # shorthand equivalent flag is -N
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
new file: foo
no changes added to commit (use "git add" and/or "git commit -a")
# Now git is tracking the file, but no changes are staged for commit yet
## Tracked and staged
$ git add foo
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: foo
# Now the file is still tracked and the change is staged
Из этого, надеюсь, вы можете увидеть разницу между неотслеживаемым, отслеживаемым и постановочным