Untracked files not shown in "git status"
I have a project with the following folder structure:
All the project files are in base_fldr
folder. Also, I have a few folders inside base_fldr
called sub_fldr1
and sub_fldr2
. These sub folders also contain some files.
If I modify any of the files inside my base_fldr
or base_fldr\sub_fldr\
then git status
shows them as modified. Also if I add a new file to base_fldr
, git status
will show it as untracked file.
My problem is if I add a new file inside base_fldr\sub_fldr\
then the git status
doesn't show the file as untracked. It wo开发者_运维知识库n't even give any info about the file.
The file or its extension is NOT in my .gitignore
list. Also, I did try git add sub_fldr\file_name
, but neither it gave an error nor it added the file to index.
Any idea what's happening here? Thanks!
I figured out what was going wrong. Basically the first line in my .gitignore file is "*/". This causes any file added to sub directory being ignored by git status command. But the funny thing was if I modify any files in sub folder, git status correctly shows them as modified as the file is already in git repository, but was ignoring new files in sub folder.
I fixed my issue by removing the line in .gitignore file to not ignore changes in sub folders, then added the new files to index and then again added back the line in .gitignore so that it will ignore any generated files in subfolders.
Thanks all for the responses.
I ran into a similar issue with missing tracked files. While experimenting with ways to manage locally modified versions of tracked files without having to constantly avoid accidental commits, I ran the following:
git update-index --assume-unchanged my-tracked-file-that-is-awol
I ended up scrapping this idea, but forgot to undo the command, so subsequent changes to this and other --assume-unchanged files were completely missing from:
git status -u --ignored
It took me a while to figure out what was going on, but I simply had to reverse the command with:
git update-index --no-assume-unchanged my-tracked-file-that-is-awol
This is likely because your base_fldr\sub_fldr\ directory is untracked, if you run:
git add base_fldr\sub_fldr\
From within your working copy root, it will automatically add the directory and other files and directories within that directory as well.
By default, git will not show files within directories that are untracked.
Do you have a .git
subdirectory inside your sub_fldr
directory? Git may think you're trying to use submodules.
In order to debug an issue like this, see if your .gitignore
file is the culprit by observing the following two outputs
See https://git-scm.com/docs/git-ls-files
git ls-files --other --directory --exclude-standard
This will show all untracked files, while obeying the .gitignore
file.
git ls-files --other --directory
This will show all untracked files, without obeying the .gitignore
file.
Whichever files are present in output of 2
, but are not present in output of 1
, are not shown in untracked because of some flag in your .gitignore
file
Here is another cause of the behavior described in this question (git status untracked files list doesn't include an untracked file in a sub-folder). If the file is untracked because of a .gitignore file in the sub-folder then the file won't be included in the git status untracked files list.
Since 2011, this was fixed for the first time with Git v1.8.3-rc0 (April 2013).
It fixes a handful of issues in the code to traverse working tree to find untracked and/or ignored files, cleans up and optimizes the codepath in general.
See commit 0aaf62b, commit defd7c7, commit 8aaf8d7, commit b07bc8c, commit 95c6f27, commit 6cd5c58, commit 46aa2f9, commit 5bd8e2d, commit be8a84c, commit c94ab01, commit 184d2a8, commit 0104c9e, commit 289ff55, commit 560bb7a (15 Apr 2013) by Karsten Blees (kblees
).
(Merged by Junio C Hamano -- gitster
-- in commit 7093d2c, 23 Apr 2013)
dir.c
: make 'git-status --ignored' work within leading directoriesSigned-off-by: Karsten Blees
'
git status --ignored path/
' doesn't list ignored files and directories within 'path
' if some component of 'path
' is classified as untracked.Disable the
DIR_SHOW_OTHER_DIRECTORIES
flag while traversing leading directories. This preventstreat_leading_path()
withDIR_SHOW_IGNORED
flag from aborting at the top level untracked directory.As a side effect, this also eliminates a recursive directory scan per leading directory level, as
treat_directory()
can no longer callread_directory_recursive()
when called fromtreat_leading_path()
.
But, 6 years later (late 2019), with Git 2.25 (Q1 2020), an assorted fixes to the directory traversal API... revert that very fix seen above, and re-implement it.
See commit 6836d2f (20 Dec 2019) by Junio C Hamano (gitster
).
See commit c847dfa, commit 777b420, commit b9670c1 (19 Dec 2019), and commit c5c4edd, commit 072a231, commit 2f5d384, commit a2b1336, commit 452efd1 (10 Dec 2019) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit d2189a7, 25 Dec 2019)
Revert "dir.c
: make 'git-status --ignored
' work within leading directories"Signed-off-by: Elijah Newren
Commit be8a84c52669 ("
[
dir.c](https
://github.com/git/git/blob/a2b13367fe55bdeb10862f41aff3e2446b63e171/dir.c): make 'git-status --ignored
' work within leading directories", 2013-04-15, Git v1.8.3-rc0 -- merge) noted thatgit status --ignored <SOMEPATH>
would not list ignored files and directories within
<SOMEPATH>
if<SOMEPATH>
was untracked, and modified the behavior to make it show them.However, it did so via a hack that broke consistency; it would show paths under
<SOMEPATH>
differently than a simplegit status --ignored | grep <SOMEPATH>
would show them.
A correct fix is slightly more involved, and complicated slightly by this hack, so we revert this commit (but keep corrected versions of the testcases) and will later fix the original bug with a subsequent patch.
Some history may be helpful:
A very, very similar case to the commit we are reverting was raised in commit 48ffef966c76 ("
ls-files
: fix overeager pathspec optimization", 2010-01-08, Git v1.7.0-rc0 -- merge); but it actually went in somewhat the opposite direction.In that commit, it mentioned how
git ls-files -o --exclude-standard t/
used to show untracked files under
t/
even whent/
was ignored, and then changed the behavior to stop showing untracked files under an ignored directory.More importantly, this commit considered keeping this behavior but noted that it would be inconsistent with the behavior when multiple pathspecs were specified and thus rejected it.
The reason for this whole inconsistency when one pathspec is specified versus zero or two is because common prefixes of pathspecs are sent through a different set of checks (in
treat_leading_path()
) than normal file/directory traversal (those go throughread_directory_recursive()
andtreat_path()
).As such, for consistency, one needs to check that both codepaths produce the same result.
Revert commit be8a84c526691667fc04a8241d93a3de1de298ab, except instead of removing the testcase it added, modify it to check for correct and consistent behavior.
And:
dir
: fix checks on common prefix directorySigned-off-by: Elijah Newren
Many years ago, the directory traversing logic had an optimization that would always recurse into any directory that was a common prefix of all the pathspecs without walking the leading directories to get down to the desired directory.
Thus,
git ls-files -o .git/ # case A
would notice that
.git/
was a common prefix of all pathspecs (since it is the only pathspec listed), and then traverse into it and start showing unknown files under that directory.Unfortunately,
.git/
is not a directory we should be traversing into, which made this optimization problematic.This also affected cases like:
git ls-files -o --exclude-standard t/ # case B
where
t/
was in the.gitignore
file and thus isn't interesting and shouldn't be recursed into.It also affected cases like:
git ls-files -o --directory untracked_dir/ # case C
where
untracked_dir/
is indeed untracked and thus interesting, but the--directory
flag means we only want to show the directory itself, not recurse into it and start listing untracked files below it.The case B class of bugs were noted and fixed in commits 16e2cfa90993
("read_directory()
: further splittreat_path()
", 2010-01-08) and 48ffef966c76 ("ls-files
: fix overeager pathspec optimization", 2010-01-08, Git v1.7.0-rc0 -- merge), with the idea being that we first wanted to check whether the common prefix was interesting.The former patch noted that
treat_path()
couldn't be used when checking the common prefix becausetreat_path()
requires adir_entry()
and we haven't read any directories at the point we are checking the common prefix.So, that patch split
treat_one_path()
out oftreat_path()
.The latter patch then created a new
treat_leading_path()
which duplicated by hand the bits oftreat_path()
that couldn't be broken out and then calledtreat_one_path()
for the remainder.There were three problems with this approach:
- The duplicated logic in
treat_leading_path()
accidentally missed the check for special paths (such asis_dot_or_dotdot
and matching ".git
"), causing case A types of bugs to continue to be an issue.- The
treat_leading_path()
logic assumed we should traverse intoanything where path_treatment was not path_none, i.e. it perpetuated class C types of bugs.- It meant we had split logic that needed to kept in sync, running the risk that people introduced new inconsistencies (such as in commit be8a84c52669, which we reverted earlier in this series, or in commit df5bcdf83ae which we'll fix in a subsequent commit)
Fix most these problems by making
treat_leading_path()
not only loop over each leading path component, but callingtreat_path()
directly on each.To do so, we have to create a synthetic
dir_entry,
but that only takes a few lines.Then, pay attention to the
path_treatment
result we get fromtreat_path()
and don't treatpath_excluded,
path_untracked,
andpath_recurse
all the same aspath_recurse
.
精彩评论