您是否曾经在文件中进行过更改,使git无法查看适当的更改?我今天遇到了这种奇怪的git行为。考虑一个文件main.scss,该文件@imports .scss局部文件。日常场景中,总是100%简单,对吧?没问题。直到今天!
当我尝试导入路径为“ layout / sidebars / header”(指向相应的现存的/layout/sidebars/header.scss文件)的文件时,我观察到 git 。
添加该行后,git status产生了干净状态,但是没有响应。即触摸新文件并没有进行任何更改。下图举例说明了这种行为,我希望它可以证明令人满意的表现:
当我尝试将文件移动到名为“ test.scss”或什至“ test.test”的新文件(对于.gitignore怀疑论者)时,我没有机会提交新添加的文件如我所料。
Git已停止根据代码中的这一行来干净地跟踪文件,这是灾难的根源---因为人们可以在自己的计算机上成功构建,并且可能会出于一些不负责任的习惯而犯错使用“ git add --all”的示例,假设包含的文件已在该提交中暂存。如果该开发人员过快退出习惯或使用了其他管道命令,则问题已经到存储库。
这是什么原因造成的?没有人喜欢在提交中使用损坏的代码...但这是我的经验中第一次,似乎内部文件损坏了我的Git正确跟踪文件的能力?
我觉得Git与文件的内容无关,只是处理位模式和字节...所以包含文件会破坏Git的想法对我来说很奇怪。
任何对此的见解或理论都将受到赞赏。
答案 0 :(得分:4)
您跑步了(在第二张图片中可以看到):
mv main.scss test.scss
这会更改您的工作树,但不会更改您的 index 。 1 当然,您当前的提交或HEAD
提交是保持不变。
由于git status
运行两个单独的git diff
(或多或少),因此git status
的作用如下:
比较HEAD
与索引:没有任何变化。
因此,由于没有什么不同,因此尚无提交阶段。
比较索引与工作树。嗯,文件main.scss
在索引中,但不在工作树中。它必须已删除!
由于工作树文件不存在,您最终必须打算删除main.scss
。但是,由于您尚未要求Git从索引中删除它,因此它将继续存在于下一次提交中。因此,此删除尚未暂存为提交。当然,您可以请求从此处开始随时进行提交。
尚不清楚索引中是否有名为test.scss
的文件。 2 如果没有,则刚出现在您的工作中的新test.scss
-树是未跟踪的文件。它可能会也可能不会被忽略-如果不忽略它,git status
会抱怨它,说它未被跟踪。如果同时跟踪了和,git status
将对此保持安静。可以从偷偷摸摸的位置引入忽略规则,因此使用git check-ignore -v
在此处查找更多信息。
请注意,如果您使用git mv
而不是普通的mv
,则Git将同时在工作树和中重命名文件,并在索引中重命名该文件。这样,您的索引中将没有main.scss
(以便计划在下一次提交时将其删除),并且索引和工作树中都将有test.scss
。
由于git status
的{{1}}操作进行了重命名检测,Git会将旧的git diff
与新的main.scss
进行比较,发现它完全相同,并说您重命名了文件。 (实际上,下一次提交将仅缺少test.scss
而具有main.scss
,但是 other 比较也会 检测到重命名并将其报告为一个,前提是您要求Git检测重命名。)
1 请记住,索引(也称为暂存区或有时称为 cache ,具体取决于谁在进行调用)在哪里您构建 next 提交。它开始与您通过运行test.scss
检出的提交匹配:也就是说,它具有每个文件的副本,采用Git使用的特殊的仅Git格式,就像git checkout branch
提交一样。< / p>
索引中的副本与HEAD
提交中的副本之间的主要区别在于,索引中的副本 可以被修改或完全删除;可以将尚未包含在索引中的文件添加到其中。由于您执行的下一个提交是在运行HEAD
时根据索引中的内容进行构建的,因此构建新索引是您的工作。但是由于索引中的文件是这种特殊的,压缩的,仅Git的格式,因此Git还将这些文件也复制到您的工作树中,您可以在其中进行处理。使用git commit
将文件复制回索引,覆盖以前的版本;或者,如果以前没有版本,则在索引的中创建该文件。
2 要查看索引中的所有 ,请使用git add path
。不过,这很冗长。通常,根据什么是 来查看索引会更有趣,这就是为什么git ls-files --stage
先将HEAD-vs-index与index-vs-work-tree进行比较。
答案 1 :(得分:0)
一个特别邪恶的合并是来自 parent .git模块中的master的合并,最终导致负责将我的工作目录(git子模块)包含在.gitignore中。因此,我创建的任何文件都永远不会投放到git status
,因此不会包含在登台中。
正如@Torek所指出的,调整与索引的对应关系是正确的……这只是一种欺骗,因为我在我的 working git存储库中找不到相应的.gitignore规则。感。
深入挖掘,但不要忘记搜索更高的位置。