我有一个具有以下文件夹结构的项目:
所有项目文件都在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 status不会将文件显示为未跟踪。它甚至不会提供有关该文件的任何信息。
该文件或其扩展名不在我的.gitignore列表中。我也尝试了git add sub_fldr \ file_name,但既没有给出错误,也没有将文件添加到索引中。
知道这里发生了什么吗?谢谢!
答案 0 :(得分:22)
答案 1 :(得分:15)
我遇到了丢失跟踪文件的类似问题。在尝试管理本地修改版本的跟踪文件而不必经常避免意外提交的方法时,我运行了以下内容:
git update-index --assume-unchanged my-tracked-file-that-is-awol
我最终废弃了这个想法,但忘了撤消命令,因此对此和其他--asume-unchanged文件的后续更改完全丢失了:
git status -u --ignored
我花了一段时间才弄清楚发生了什么,但我只需要用以下方法撤消命令:
git update-index --no-assume-unchanged my-tracked-file-that-is-awol
答案 2 :(得分:14)
这可能是因为您的base_fldr \ sub_fldr \目录未跟踪,如果您运行:
git add base_fldr\sub_fldr\
从您的工作副本根目录中,它将自动添加该目录中的目录和其他文件和目录。
默认情况下,git不会在未跟踪的目录中显示文件。
答案 3 :(得分:8)
您的.git
目录中是否有sub_fldr
子目录? Git可能认为您正在尝试使用submodules。
答案 4 :(得分:4)
为了调试这样的问题,通过观察以下两个输出来查看你的.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
文件中的某些标记
答案 5 :(得分:2)
以下是此问题中描述的行为的另一个原因(git status untracked files list不包括子文件夹中未跟踪的文件)。如果文件由于子文件夹中的.gitignore文件而未被跟踪,则该文件将不会包含在git status untracked files列表中。
答案 6 :(得分:0)
自2011年以来,此问题首次在Git v1.8.3-rc0(2013年4月)中得到修复。
它修复了代码中的一些问题,以遍历工作树以查找未跟踪和/或被忽略的文件,通常清理并优化代码路径。
请参见commit 0aaf62b,commit defd7c7,commit 8aaf8d7,commit b07bc8c,commit 95c6f27,commit 6cd5c58,commit 46aa2f9,{{3} },commit 5bd8e2d,commit be8a84c,commit c94ab01,commit 184d2a8,commit 0104c9e,commit 289ff55(2013年4月15日)作者:commit 560bb7a。 br />
(由Karsten Blees (kblees
)在Junio C Hamano -- gitster
--中合并,2013年4月23日)
commit 7093d2c:在主要目录中使用“ git-status --ignored”功能
签名人:Karsten Blees
'
dir.c
'不会列出'path
'的某些部分被归类为未跟踪的'path
'内被忽略的文件和目录。遍历前导目录时禁用
DIR_SHOW_OTHER_DIRECTORIES
标志。这样可以防止带有treat_leading_path()
标志的DIR_SHOW_IGNORED
在顶级未跟踪目录中终止。作为副作用,这也消除了在每个主要目录级别进行递归目录扫描的情况,因为从
treat_directory()
调用read_directory_recursive()
时无法再调用treat_leading_path()
。
但是,六年后(2019年末),在Git 2.25(2020年第一季度)中,对目录遍历API进行了各种修复……还原了上面看到的那个修复,然后重新实现。
请参见git status --ignored path/
的commit 6836d2f(2019年12月20日)。
请参见Junio C Hamano (gitster
),commit c847dfa,commit 777b420(2019年12月19日)和commit b9670c1,commit c5c4edd,commit 072a231,commit 2f5d384,{ {3}}(2019年12月10日)通过commit a2b1336。
(由commit 452efd1在Elijah Newren (newren
)中合并,2019年12月25日)
Junio C Hamano --
gitster
--:使'git-status --ignored
'在主要目录中工作”签名人:伊利亚·纽伦
提交commit d2189a7(“
[
dir.c](https
://github.com/git/git/blob/a2b13367fe55bdeb10862f41aff3e2446b63e171/dir.c):将'{{1} }'在主要目录中工作”,2013-04-15,Git v1.8.3-rc0-Revert "dir.c
)指出如果未跟踪git-status --ignored
git status --ignored <SOMEPATH>
,将不会列出
<SOMEPATH>
中被忽略的文件和目录,并且修改了行为以使其显示。但是,它是通过破坏一致性的黑客行为来实现的;它将在
<SOMEPATH>
下显示的路径与简单显示的路径不同<SOMEPATH>
将显示它们。
涉及到正确的修复程序,并且由于此hack稍微复杂一些,因此我们还原了该提交(但保留了测试用例的正确版本),以后将通过后续补丁修复原始错误。
一些历史记录可能会有所帮助:
在be8a84c52669中提出了与我们正在还原的提交非常非常相似的情况(“
git status --ignored | grep <SOMEPATH>
:修复了过度的路径规范优化”,2010-01-08,Git v1.7.0-rc0- -merge);但实际上却是相反的方向。在该提交中,它提到了方式
ls-files
用于在
git ls-files -o --exclude-standard t/
下显示未跟踪文件,即使t/
被忽略,然后将其更改为停止在被忽略目录下显示未跟踪文件的行为。更重要的是,此提交考虑保留此行为,但指出当指定了多个pathspec并因此拒绝它时,该行为将与该行为不一致。
指定一个路径规范而不是零或两个时,会出现整体不一致的原因是,路径规范的公共前缀是通过与正常的文件/目录遍历(通过这些遍历)不同的一组检查(在
t/
中发送的)发送的treat_leading_path()
和read_directory_recursive()
)。因此,为了保持一致性,需要检查两个代码路径是否产生相同的结果。
还原commit 48ffef966c76,除了不删除它添加的测试用例外,还可以对其进行修改以检查正确和一致的行为。
并且:
merge:修复对公共前缀目录的检查
签名人:伊利亚·纽伦
许多年前,目录遍历逻辑进行了优化,可以始终递归到所有路径规范的通用前缀的任何目录中,而无需先行到达目录即可到达所需目录。
因此
treat_path()
会注意到
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/
标志意味着我们只想显示目录本身,而不是递归到该目录中,并开始在其下面列出未跟踪的文件。在提交commit be8a84c526691667fc04a8241d93a3de1de298ab
--directory
中记录并修复了案例B类错误:进一步拆分了("read_directory()
“”,2010-01-08)和dir
(“ { {1}}:修复过度的路径规范优化”,2010年1月8日,Git v1.7.0-rc0-16e2cfa90993),其思想是我们首先要检查公共前缀是否有趣。 / p>前一个补丁指出,
treat_path()
不能在检查公共前缀时使用,因为ls-files
需要一个treat_path()
并且我们在检查时还没有读取任何目录通用前缀。因此,该补丁将
treat_path()
从dir_entry()
中分离出来。随后的补丁程序创建了一个新的
treat_one_path()
,它手工复制了无法分裂的treat_path()
的位,然后将其余部分称为treat_leading_path()
。此方法存在三个问题:
treat_path()
中重复的逻辑意外漏掉了对特殊路径的检查(例如treat_one_path()
和匹配的“treat_leading_path()
”),从而导致案例A类型的错误继续成为问题。is_dot_or_dotdot
逻辑假设我们应该遍历path_processing不是path_none的任何地方,即,它使C类错误永久存在。- 这意味着我们需要保持同步的分裂逻辑,冒着人们引入新不一致的风险(例如我们在本系列前面的48ffef966c76或merge中引入了新的不一致之处)我们将在以后的提交中修复)
通过使
.git
不仅遍历每个引导路径组件,而且直接在每个前导路径组件上调用treat_leading_path()
来解决这些问题。为此,我们必须创建一个合成的
treat_leading_path()
,但这只需要几行。然后,请注意我们从
treat_path()
获得的dir_entry,
结果,不要将path_treatment
treat_path()
和path_excluded,
与{{ 1}}。