繁体   English   中英

从远程签出一个 repo,但是当我执行 git status 时,文件显示为已修改 - 如何修复?

[英]Checked out a repo from remote but when I do a git status a file shows up as modified — how to fix?

我正在使用 Windows 和 Git,并且我修改了一个文件。 无论我执行 git add 和 commit 多少次,该文件一直显示为已修改,例如我无法执行 git pull --rebase。 我想我做错了什么,搞砸了本地 Git 存储库,所以我决定从 github 克隆存储库,到一个全新的目录中。 令我惊讶的是,即使在这个新的目录树中,当我执行 git status 时,同一个文件也显示为已修改——就好像它在 github(远程)存储库中以某种方式进行了修改,这对我来说没有意义。 此外,克隆的本地存储库中的文件版本没有我在 github 上查看代码时可以看到的最新版本的代码。 我怎样才能解决这个问题? 我担心克隆代码的其他人最终会遇到同样的问题。 (显然只有我看到了这个问题——我没有以某种方式设法破坏 github 存储库,这让我相信这是一个 git/windows 问题。)就我认为我做错的事情而言,我修改了一个文件和做了一个 git add,我使用小写字母而不是大写字母拼错了目录路径,然后添加一个文件导致另一个正确拼写的路径显示为已修改,反之亦然。 我不知道是否在 Windows 上创建了符号链接——文件内容是相同的。 但是有人会认为克隆(通过 Eclipse)到一个全新的目录树中会使这成为一个非问题。

我查看了回复,但似乎基本问题是 Window 不区分大小写,这导致了一些(对我而言)奇怪的行为。 特别是,我根本无法删除其中一个文件夹——它们“纠缠不清”。 因此,简单的解决方案是从区分大小写的 unix 中删除文件夹及其内容。 然后我检查了一个新的 repo,问题似乎完全解决了。

您在评论中提到您发现一个提交包含两个有问题的文件:一个名为Login/Login.tsx和一个名为login/Login.tsx 这个评论是关于一个相关的问题 有关 Git 在其索引中命名文件的方法的讨论,以及您的操作系统在您的工作树中的要求,请参阅我的回答

您的解决方案——使用 Unix 或 Linux 机器,在那里你得到一个区分大小写的文件系统,来修复这种情况——可能是处理这个问题的最简单和最好的方法。 如果您可以在自己的机器上建立区分大小写的文件系统,那么也可以轻松处理这个问题(请参阅我对另一个相关问题的回答,了解 macOS 特定的创建区分大小写文件系统的方法)。

鉴于您想要的只是删除其中一个拼写,但是git rm应该允许您这样做。 特别是git rm --cached login/Login.tsx会从 Git 的索引中删除login/Login.tsx ,而不会影响Login/Login.tsx 但是,这可能会使您的工作树具有现有的login文件夹。

重要的是——在任何时候,真的,但尤其是在这样的情况下工作时——意识到 Git 本身实际上并不需要或使用你的工作树来进行新的提交。 每个提交都包含 Git 知道的每个文件的完整快照。 这些文件在 Git 的index 中作为“副本”存在。 1因此,每个文件实际上有三个副本:

  • 每个文件的冻结版本出现在当前提交中(无论该提交的哈希 ID 是什么)。

  • 该版本的“副本”(见脚注 1)出现在 Git 的索引中。 你可以用不同的内容替换这个副本,提交中的只读副本不会改变。 您可以完全删除此副本,只读副本仍然不会更改。 任何现有提交中的任何内容都不会或永远不会改变。 索引副本精确存在,以便您可以替换它,或删除它,或其他任何东西。 实际上,索引(或暂存区,如果您更喜欢这个术语)充当您建议的下一次提交 它只是从提交中填写

  • 最后,还有一个常规的、普通的、日常的文件。 此副本进入您的工作树工作树 为了放置这个副本,Git 必须使用你操作系统的文件操作工具。 这可能需要在文件夹中创建文件夹和文件。 如果这些不区分大小写,并且当login文件夹存在时 Git 会创建一个Login文件夹,反之亦然,操作系统会说:不,抱歉,已经存在 无论如何,Git 将尽最大努力通过使用“错误”案例来适应操作系统,并将在该错误案例文件夹中创建一个文件 - 或者可能会销毁一些其他同名的工作树文件,除了案例,或其他任何.

最后一点,您的工作树文件以错误的名称结束和/或在错误的文件夹中和/或最终覆盖名称不同的类似文件,这对您来说是一个问题。 不过,这对Git 来说不是问题。 Git 只是继续使用每个文件的索引副本。 您运行的下一个git commit使用 Git 索引中的任何内容。 您的工作树不匹配的事实对 Git 来说不是问题。 这对你来说只是一个问题,因为正常的日常git add命令意味着使这个文件的 Git 索引条目与我的工作树中的副本匹配,如果这是错误的副本,那么,这是一个问题。

在任何情况下,一旦您在 Git 中将正确提交作为当前提交,并提取到 Git 的索引中,您就可以对工作树执行任何您喜欢的操作,包括删除大片的工作树,或重命名文件夹,等等。 随心所欲地设置它,然后使用git checkoutgit restore将当前提交的全部或部分重新提取到您的工作树。 现在您已经消除了 Git 提交和索引中的名称大小写问题,并清理或删除了工作树中的任何有问题的文件和/或文件夹,Git 可以根据需要创建正确大小写的文件夹和/或文件。 将正确提交到 Git 的过程是痛苦的,除非在区分大小写的文件系统上。


1 “副本”在此处用引号引起来,因为 Git 索引中的文件(Git 也将其称为暂存区)采用特殊的 Git-only 格式,可以对内容进行重复数据删除。 当 Git 索引中的副本与某个现有提交中的副本匹配时,Git 实际上只是重新使用现有提交的文件。 具有全新内容的文件实际上需要一个新的内部 blob 对象,Git 根据需要创建该对象; 之后,内容将像往常一样进行重复数据删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM