Git表示“提交更改或在切换分支之前存储它们”,但也“什么也没提交”

时间:2019-02-20 18:49:29

标签: git

我正在尝试通过运行test1将分支从test2切换到git checkout test2,但出现此错误:

error: Your local changes to the following files would be overwritten by checkout:
    path/to/file.xml
Please commit your changes or stash them before you switch branches.
Aborting

尽管如此,当我在git status上运行git committest1时,我还是得到了:

On branch test1
nothing to commit, working tree clean

有趣的是,我可以在mastertest1之间切换。

这是怎么回事?切换到test2我需要做什么?

2 个答案:

答案 0 :(得分:1)

TL; DR

您需要清除skip-worktree位并重新运行git status以查看发生了什么。从那时起,事情将会(某种程度上)变得更加清晰。

长(ish)

这里的问题是skip-worktree位设置为:

path/to/file.xml

有一个相关的部分拼写为假设不变。两位具有相同的实际效果。尽管文档和stackoverflow答案都建议使用skip-worktree位 1 ,但这两种方式都不意味着人们倾向于使用它们。但在实践中,任何一个都做同样的事情。您必须记住(或重新发现)您设置的位,以清除该位:

git update-index --no-skip-worktree path/to/file.xml

在名称和内容记录在索引中的文件上设置了任一位时,Git假定应使用通过索引存储的内容,并且在git statusgit add个操作。

幸运的是,Git足够聪明,可以检查 other 操作上的实际工作树副本。如果Git由于某种原因要覆盖工作树副本,例如提交的git checkoutgit merge,而该提交的提交副本与当前索引副本不同— Git将再次检查path/to/file.xml work-tree 副本是否与索引副本匹配。否则,Git将抱怨该操作将覆盖工作树副本。

不幸的是,git status在设计上并非宣布工作树副本与索引副本不同步。它只是假设文件的两个版本都匹配。因此,您运行git status,没有要提交的更改,因此没有要保存的内容,但是与此同时,git checkoutgit merge一直抱怨您必须提交更改。

清除该位,无论哪个位,都使git status注意到问题。在我看来git status应该在这里提供更多信息:它需要说,也许在使用其他选项时,或者也许总是,在这里 有所不同,但是有意忽略了它。由于这些位之一或全部。 (要使它在稀疏签出时能很好地工作,它可能不应该对索引中而不是工作树中且被稀疏规则排除的标记的--skip-worktree文件不作任何说明。)


1 Assume-unchanged用于在lstat调用特别慢且允许Git忽略的文件系统上使用。跳过工作树适用于稀疏签出,并且不允许 忽略Git。 Git也没有面向用户的稀疏签出命令,因此设置skip-worktree位更好。

答案 1 :(得分:0)

Git重置为我解决了此问题:

git reset --hard