Неотслеживаемые файлы не отображаются в состоянии git
У меня есть проект со следующей структурой папок:
Все файлы проекта находятся в папке base_fldr. Также у меня есть несколько папок внутри base_fldr, которые называются sub_fldr1 и sub_fldr2. Эти подпапки также содержат некоторые файлы.
Если я изменяю какие-либо файлы внутри моего base_fldr или base_fldr\sub_fldr\, то git status показывает их как измененные. Также, если я добавлю новый файл в base_fldr, git status покажет его как неотслеживаемый файл.
Моя проблема в том, что если я добавлю новый файл в base_fldr\sub_fldr\, то в состоянии git файл не будет отслежен. Он даже не даст никакой информации о файле.
Файл или его расширение НЕ в моем списке.gitignore. Также я попробовал git add sub_fldr \ file_name, но он не выдал ошибку и не добавил файл в индекс.
Есть идеи, что здесь происходит? Спасибо!
8 ответов
Я понял, что происходит не так. По сути, первая строка в моем файле.gitignore - "*/". Это приводит к тому, что любой файл, добавленный в подкаталог, игнорируется командой git status. Но забавно то, что если я изменяю какие-либо файлы в подпапке, git status правильно показывает их как измененные, поскольку файл уже находится в репозитории git, но игнорирует новые файлы в подпапке.
Я исправил свою проблему, удалив строку в файле.gitignore, чтобы не игнорировать изменения в подпапках, затем добавил новые файлы в индекс, а затем снова добавил строку в.gitignore, чтобы он игнорировал любые созданные файлы в подпапках.
Спасибо всем за ответы.
Это вероятно потому, что ваш каталог base_fldr\sub_fldr\ не отслеживается, если вы запустите:
git add base_fldr\sub_fldr\
Из корня вашей рабочей копии он автоматически добавит каталог и другие файлы и каталоги в этом каталоге.
По умолчанию git не показывает файлы в каталогах, которые не отслеживаются.
Я столкнулся с подобной проблемой с отсутствующими отслеживаемыми файлами. Экспериментируя со способами управления локально измененными версиями отслеживаемых файлов без необходимости постоянно избегать случайных коммитов, я запустил следующее:
git update-index --assume-unchanged my-tracked-file-that-is-awol
В итоге я отказался от этой идеи, но забыл отменить команду, поэтому последующие изменения этого и других --assume-неизмененных файлов полностью отсутствовали в:
git status -u --ignored
Мне потребовалось некоторое время, чтобы понять, что происходит, но мне просто пришлось отменить команду с помощью:
git update-index --no-assume-unchanged my-tracked-file-that-is-awol
У вас есть .git
подкаталог внутри вашего sub_fldr
каталог? Git может подумать, что вы пытаетесь использовать субмодули.
Для устранения проблемы, подобной этой, посмотрите, .gitignore
Файл является виновником, соблюдая следующие два вывода
Смотрите https://git-scm.com/docs/git-ls-files
git ls-files --other --directory --exclude-standard
Это покажет все неотслеживаемые файлы, подчиняясь .gitignore
файл.
git ls-files --other --directory
Это покажет все неотслеживаемые файлы, не подчиняясь .gitignore
файл.
Какие файлы присутствуют в выводе 2
, но нет в выводе 1
, не отображаются неотслеживаемыми из-за какого-либо флага в вашем .gitignore
файл
Вот еще одна причина поведения, описанного в этом вопросе (список неотслеживаемых файлов состояния git не включает неотслеживаемый файл в подпапке). Если файл не отслежен из-за файла.gitignore в подпапке, то этот файл не будет включен в список неотслеживаемых файлов состояния git.
У вас может возникнуть эта ошибка с файлами, которые были изменены с помощьюchmod
.
С использованиемgit status -u
вы можете увидеть их в «Неотслеживаемых файлах», но сgit diff
все они не показали никакой разницы.
С 2011 года это было впервые исправлено в Git v1.8.3-rc0 (апрель 2013 года).
Он исправляет несколько проблем в коде для обхода рабочего дерева, чтобы найти неотслеживаемые и / или игнорируемые файлы, очищает и оптимизирует путь кода в целом.
См совершать 0aaf62b, совершать defd7c7, совершают 8aaf8d7, совершают b07bc8c, совершают 95c6f27, совершают 6cd5c58, совершают 46aa2f9, совершают 5bd8e2d, совершают be8a84c, совершают c94ab01, совершают 184d2a8, совершают 0104c9e, совершают 289ff55, совершают 560bb7a (15 апреля 2013) по Карстен Blees (kblees
).
(Слияние Junio C Hamano -gitster
- в коммите 7093d2c, 23 апреля 2013 г.)
dir.c
: заставить 'git-status--ignored' работать в ведущих каталогахПодписано: Карстен Блис
'
git status--ignored path/
'не перечисляет игнорируемые файлы и каталоги в'path
'если какой-то компонент'path
'классифицируется как неотслеживаемая.Отключить
DIR_SHOW_OTHER_DIRECTORIES
флаг при просмотре ведущих каталогов. Это предотвращаетtreat_leading_path()
сDIR_SHOW_IGNORED
флаг от прерывания в неотслеживаемой директории верхнего уровня.В качестве побочного эффекта это также исключает рекурсивное сканирование каталогов для каждого уровня ведущего каталога, так как
treat_directory()
больше не могу звонитьread_directory_recursive()
когда звонят изtreat_leading_path()
.
Но, 6 лет спустя (конец 2019 г.), с Git 2.25 (1 квартал 2020 г.), различные исправления API обхода каталогов... верните то самое исправление, которое было показано выше, и повторно внедрите его.
См. Commit 6836d2f (20 декабря 2019 г.) от Junio C Hamano (gitster
).
См. Фиксацию c847dfa, фиксацию 777b420, фиксацию b9670c1 (19 декабря 2019 г.) и фиксацию c5c4edd, фиксацию 072a231, фиксацию 2f5d384, фиксацию a2b1336, фиксацию 452efd1 (10 декабря 2019 г.) Элайджа Ньюрен (newren
).
(Слияние Junio C Hamano -gitster
- в коммите d2189a7, 25 декабря 2019 г.)
Revert "dir.c
: сделать 'git-status--ignored
'работа в ведущих каталогах "Подписано: Элайджа Ньюрен
Зафиксируйте be8a84c52669 ("
[
dir.c](https
: //github.com/git/git/blob/a2b13367fe55bdeb10862f41aff3e2446b63e171/dir.c): make 'git-status--ignored
'работа в ведущих каталогах ", 2013-04-15, Git v1.8.3-rc0 - merge) отметил, чтоgit status--ignored <SOMEPATH>
не будет перечислять игнорируемые файлы и каталоги в
<SOMEPATH>
если<SOMEPATH>
не отслеживались, и изменили поведение, чтобы оно отображало их.Однако это было сделано с помощью хака, нарушившего согласованность; он покажет пути под
<SOMEPATH>
иначе, чем простойgit status--ignored | grep <SOMEPATH>
покажет им.
Правильное исправление немного сложнее и немного усложняется этим хаком, поэтому мы отменяем эту фиксацию (но сохраняем исправленные версии тестовых случаев) и позже исправим исходную ошибку с помощью следующего патча.
Некоторая история может быть полезна:
Очень, очень похожий случай на отменяемый нами коммит был поднят в коммите 48ffef966c76 ("
ls-files
: fix overeager pathspec optimisation", 08.01.2010, Git v1.7.0-rc0 - merge); но на самом деле все пошло в несколько противоположном направлении.В этом коммите упоминалось, как
git ls-files -o --exclude-standard t/
используется для отображения неотслеживаемых файлов в
t/
даже когдаt/
был проигнорирован, а затем изменил поведение, чтобы перестать показывать неотслеживаемые файлы в игнорируемом каталоге.Что еще более важно, эта фиксация рассматривала сохранение этого поведения, но отметила, что это будет несовместимо с поведением, когда были указаны несколько спецификаций пути, и поэтому отклонил его.
Причина всей этой несогласованности, когда указывается один pathspec вместо нуля или двух, заключается в том, что общие префиксы pathspecs отправляются через другой набор проверок (в
treat_leading_path()
), чем при обычном обходе файлов / каталогов (они проходят черезread_directory_recursive()
а такжеtreat_path()
).Таким образом, для согласованности необходимо проверить, что оба кодовых пути дают одинаковый результат.
REVERT https://github.com/git/git/commit/be8a84c526691667fc04a8241d93a3de1de298ab, за исключением вместо удаления TestCase добавил он, изменить его, чтобы проверить правильность и последовательное поведение.
А также:
dir
: исправлены проверки общего каталога префиксовПодписано: Элайджа Ньюрен
Много лет назад логика обхода каталогов имела оптимизацию, которая всегда рекурсивно возвращалась в любой каталог, который был общим префиксом для всех указателей пути, без перехода по ведущим каталогам, чтобы перейти к желаемому каталогу.
Таким образом,
git ls-files -o .git/ # case A
заметил бы, что
.git/
был общим префиксом для всех спецификаций пути (так как это единственный указанный путь), а затем перейти к нему и начать показывать неизвестные файлы в этом каталоге.К сожалению,
.git/
это не каталог, в который мы должны переходить, что сделало эту оптимизацию проблематичной.Это также коснулось таких случаев, как:
git ls-files -o --exclude-standard t/ # case B
где
t/
был в.gitignore
файл и, следовательно, не интересен и не должен использоваться повторно.Это также повлияло на такие случаи, как:
git ls-files -o --directory untracked_dir/ # case C
где
untracked_dir/
действительно не отслеживается и поэтому интересен, но--directory
Флаг означает, что мы хотим показать только сам каталог, а не возвращаться в него и начинать перечисление неотслеживаемых файлов под ним.Ошибки класса B были отмечены и исправлены в коммитах 16e2cfa90993.
("read_directory()
: дальнейшее разделениеtreat_path()
", 08.01.2010) и 48ffef966c76 ("ls-files
: fix overeager pathspec optimisation", 08.01.2010, Git v1.7.0-rc0 - merge), идея заключалась в том, что мы сначала хотели проверить, интересен ли общий префикс.В предыдущем патче отмечалось, что
treat_path()
нельзя использовать при проверке общего префикса, потому чтоtreat_path()
требуетdir_entry()
и мы не читали никаких каталогов на момент проверки общего префикса.Итак, этот патч раскололся
treat_one_path()
снаружиtreat_path()
.Последний патч затем создал новый
treat_leading_path()
который дублировал вручную кусочкиtreat_path()
это не могло быть разбито, а затем позвонитьtreat_one_path()
на остаток.У этого подхода было три проблемы:
- Дублированная логика в
treat_leading_path()
случайно пропустил проверку на особые пути (например,is_dot_or_dotdot
и соответствие ".git
"), из-за чего ошибки типа case A продолжают оставаться проблемой.- В
treat_leading_path()
логика предполагала, что мы должны пройти туда, где path_treatment не был path_none, то есть это увековечило ошибки типа C.- Это означало, что у нас была логика разделения, которую нужно было синхронизировать, рискуя тем, что люди внесут новые несоответствия (например, в фиксацию be8a84c52669, которую мы вернули ранее в этой серии, или в фиксации df5bcdf83ae, которую мы исправим в следующей фиксации)
Решите большинство этих проблем, сделав
treat_leading_path()
не только перебирать каждый компонент ведущего пути, но и вызыватьtreat_path()
прямо на каждом.Для этого нам нужно создать синтетический
dir_entry,
но это займет всего несколько строк.Затем обратите внимание на
path_treatment
результат мы получаем отtreat_path()
и не лечитьpath_excluded,
path_untracked,
а такжеpath_recurse
все так же, какpath_recurse
.