TL; DR
По сути, git status
- это лучшая попытка Git рассказать вам все сразу.
Если файл не отображается, и вы думаете, что он может быть проигнорирован, git check-ignore -v
полезно: оно сообщит вам , почему файл игнорируется, если он игнорируется, или ничего не говорит, если он не игнорируется.
Существует одна вещь, которая отсутствует, котораяэто быстрый и простой способ увидеть специальные флаги, которые вы можете установить в индексе.
git ls-files
может показать вам, что в индексе, но это не очень удобно для пользователя.
Long
В Git отслеживается просто означает, что присутствует в индексе . В то же время можно игнорировать только неотслеживаемые файлы. Файл неотслеживаемый по определению является файлом, который не в индексе, но равен в вашем рабочем дереве - области, в которой вы выполняетеповседневная работа.
Индекс также, возможно, лучше всего описать как , что будет входить в следующий коммит . (Это сложнее, потому что у индекса есть несколько дополнительных ролей, но это короткая версия.) Новый git commit
просто упаковывает файлы, которые есть в индексе, для создания моментального снимка для нового коммита. Все остальное вытекает из этого.
Помните, что всегда есть три активных копии отслеживаемого файла, хотя две из них могут отсутствовать:
Существует копия HEAD
(текущая фиксация), откуда файл изначально поступил. Если нет копии HEAD
, файл новый: он будет добавлен в следующем коммите по сравнению с текущим коммитом.
Копия файла HEAD
, как и любой коммиткопия любого файла, только для чтения. Ничто из того, что ты можешь сделать, не может изменить это. Это в специальном формате Git-only, и его довольно сложно найти: вам нужно иметь Git extract в удобной форме.
Есть индексная копия,Технически это действительно ссылка на копию где-то еще. Он также находится в специальном внутреннем формате Git для файлов («объект blob», в терминах Git), но для ваших собственных целей вы можете просто рассматривать его как отдельную физическую копию, поскольку в любой момент вы можете перезаписать с помощью новой копии или удалить ее.
Наконец, есть копия рабочего дерева. Это единственная версия файла, которую вы можете увидеть с помощью обычных компьютерных инструментов. Он находится в обычном формате вашего компьютера, поэтому вы можете делать с этой копией все, что захотите.
Если копия отслеживаемого файла в рабочем дереве отсутствует, она выглядит удаленной по сравнению с (не удаленной)индексная копия.
При первом git checkout
некотором коммите - каждый коммит уникально определяется его большим уродливым хеш-идентификатором, так что вы можете проверить старые, если хотите - Git читаетфайлы коммита в индекс, так что все зафиксированные файлы есть и других файлов там нет. 1 Итак, теперь HEAD
, то есть коммит, который вы только что извлекли, и индекс соответствует . Между тем, этот же git checkout
также удаляет из вашего рабочего дерева все отслеживаемые файлы из коммита, который у вас был момент назад, и заменяет их файлами из индекса из нового HEAD
совершать. Теперь все копии индекса соответствуют всем копиям рабочего дерева. Здесь не затрагиваются ни один из ваших неотслеживаемых файлов, только отслеженные.
В результате сразу после git checkout
, все три копии каждого отслеживаемого файла совпадают ,В коммите HEAD
есть неизменяемая копия, которая была скопирована в индекс и скопирована в ваше рабочее дерево.
С этого момента вы можете:
- измените (или создайте или удалите) файл рабочего дерева, как вам нравится;
- используйте
git add
, чтобы скопировать файл рабочего дерева в указатель: теперь два совпадения, иесли файл вообще не был в индексе, теперь он находится в индексе; - используйте
git rm
до удалить файл из обоих индекса и рабочего дерева: теперь оно ушло из обоих; - использовать (одинформа)
git reset
скопировать файл из HEAD
в указатель, не касаясь рабочего дерева;и / или - используют различные другие команды Git, такие как
git rm --cached
или специальные формы git checkout
, которые теперь проще в Git 2.23+ через новый git restore
, для достижения других манипуляций с индексом и/ или рабочее дерево.
Что бы вы ни делали, копия файла HEAD
никогда не изменяется. Индексная копия либо там, чтобы файл отслеживался, либо не там, чтобы файл не отслеживался. Копия рабочего дерева есть или нет: Git на самом деле не волнует, потому что Git будет использовать копию index для следующей фиксации.
Чтобы увидеть, что отличается , вы должны иметь Git сравнить:
HEAD
против индекса: все, что то же самое скучно;git status
ничего не говорит об этом. Все, что отличается , интересно: git status
говорит вам подготовлено для коммита , потому что, если вы сейчас запустите git commit
, новый коммит, который вы сделаете, будет отличаться от текущегоcommit.
index vs work-tree: все, что то же самое скучно и git status
ничего не говорит. Все, что отличается от * , интересно: git status
сообщает вам не подготовлено для фиксации , потому что вы можете обновить индексную копию файла (или удалить ее), чтобы она соответствовала рабочему дереву. после чего он может больше не соответствовать текущему коммиту.
Last - ну, почти последний - при наличии любого неотслеживаемого файла, которыйпо определению его нет в индексе - git status
будет жаловаться на то, что он не отслежен, , если вы не используете файл "ignore", чтобы закрыть его. Те, о которых вы заставляете Git молчать, это ваши игнорируемые файлы.
Обратите внимание, что отслеживаемый файл может отличаться в всех трех копиях. В этом случае оба из двух сравнений - HEAD
-vs-index и index-vs-work-tree, которые запускает git status
, приводят к «интересным» результатам. Вы увидите файл как подготовленный для фиксации и не подготовленный для фиксации . Иногда результат git status --short
, который помещает оба результата в первые два столбца выходных данных из выходных данных по одной строке на файл с несколькими столбцами, полезен здесь.
1 Это небольшое упрощение. Существует много мрачных подробностей о том, когда незафиксированные изменения могут быть перенесены через извлечение в Оформить заказ на другую ветку, когда в текущей ветке есть незафиксированные изменения .
Предположим, без изменений и skip-worktree
Вы упомянули флаг --assume-unchanged
. Также есть флаг --skip-worktree
. Эти флаги немного различаются внутри, но по большей части достигают того же результата. Они могут быть установлены только для файла, который равен в индексе, поэтому они применяются только к отслеживаемым файлам. Кроме того, только вы (или какая-либо команда, которую вы запускаете) могут установить их: у нового клона никогда не будет любой из этих установленных флагов.
Их эффект - сообщить Git- особенно git status
, который выполняет лот сравнения файлов - что он не должен смотреть на копию рабочего дерева файла. Вместо этого, когда Git проверил бы копию рабочего дерева, Git может просто предположить , что копия рабочего дерева совпадает с копией индекса.
Эти флаги немного сложно просмотреть,потому что они хранятся в индексе, который сам по себе немного сложен для просмотра. Команда git ls-files
может показать их вместе со всеми записями в индексе, что, как правило, составляет тысячи строк во многих проектах и, следовательно, не так уж полезно на практике. Я написал небольшой Python-скрипт, который я называю git-flagged
, чтобы я мог запустить git flagged
, чтобы увидеть, для каких файлов установлены эти флаги, и / или сбросить флаги, не видя много других ненужных вещей. . 2
Обратите внимание, чтоТакие символы, как git checkout
и git merge
, будут смотреть мимо этих флагов и предупреждать вас, если файл рабочего дерева будет перезаписан. То есть вы можете внести некоторые локальные изменения в какой-либо файл, пометить индексную копию, чтобы Git обычно прекращал показывать вам изменения, не подготовленные для фиксации , и работать некоторое время, включая создание новых фиксаций, что, конечно,используйте копию файла index , чтобы они соответствовали предыдущему коммиту. Но затем, сделав это некоторое время, вы забыли у вас есть локальные изменения, которые вы намеренно скрываете.
В какой-то момент кто-то другой, в каком-то другом хранилище Git, из которого вырегулярно получая коммиты, изменяет файл . Если вы git checkout
их подтвердите или git merge
с их подтверждением, Git должен будет записать их версию файла в ваше рабочее дерево. К счастью, Git не просто делает это без предупреждения. К сожалению, вы, возможно, забыли, что вы пометили некоторые файлы, и вы можете получить полный список всех помеченных файлов.
2 Вы также можете использовать grep
или подобное, но когда я часто использую флаги, приятно иметь что-то более удобное.