Git放弃子模块工作目录中的更改

6

我正在子模块中工作,遇到了取消跟踪一个文件夹中所有文件的问题。

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
    #   modified:   public/javascripts/app/fckeditor/editor/skins/office2003/fck_dialog.css
    #   modified:   public/javascripts/app/fckeditor/editor/skins/office2003/fck_editor.css
    #   modified:   public/javascripts/app/fckeditor/editor/skins/silver/fck_dialog.css
    #   modified:   public/javascripts/app/fckeditor/editor/skins/silver/fck_editor.css
    #   modified:   public/javascripts/app/fckeditor/fckconfig.js
    #   modified:   public/javascripts/app/fckeditor/fckeditor.js
    #   modified:   public/javascripts/app/fckeditor/fckpackager.xml

我输入

git reset --hard

该命令返回

HEAD现在指向 b2c5a77,无任何更改

但是当我输入

git status

我又被一个长长的文件列表打招呼了。我曾尝试过...
git clean -f 

我还删除了整个子模块并从主服务器检出。 我还尝试删除了包含子模块的整个项目,然后拉取它,但是无济于事。
rm -rf project
git clone foo@bar.project.net:/home/rails/repo/gits/project.com
#Cloning into project...
#remote: Counting objects: 2452, done.
#remote: Compressing objects: 100% (2040/2040), done.
#remote: Total 2452 (delta 1238), reused 582 (delta 145)
#Receiving objects: 100% (2452/2452), 561.32 KiB | 438 KiB/s, done.
#Resolving deltas: 100% (1238/1238), done.
cd project.com
git submodule init
git submodule update
#Cloning into vendor/plugins/project_engine...
cd vendor/plugins/project_engine
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   public/javascripts/app/fckeditor/editor/skins/office2003/fck_dialog.css
#   modified:   public/javascripts/app/fckeditor/editor/skins/office2003/fck_editor.css
#   modified:   public/javascripts/app/fckeditor/editor/skins/silver/fck_dialog.css
#   modified:   public/javascripts/app/fckeditor/editor/skins/silver/fck_editor.css
#   modified:   public/javascripts/app/fckeditor/fckconfig.js
#   modified:   public/javascripts/app/fckeditor/fckeditor.js
#   modified:   public/javascripts/app/fckeditor/fckpackager.xml

唯一能够删除这些文件的方法似乎是在我的Mac上以另一个用户身份登录,这让我想到这可能是我的本地机器的问题,而不是仓库本身的问题。

我还尝试了卸载和重新安装GIT,并且目前正在运行1.7.5.4版本的安装程序,并使用brew(Ruby软件包管理器)进行编译。

如何从git状态中删除这些文件?


你想要删除哪些文件? - TheOneTeam
我想要移除任何未被提交的更改文件,我想要检出主分支,包括主子模块,并期望键入git status时没有需要提交的内容,但是我似乎无法“摆脱”这些文件。 - Karl Entwistle
关于 git statusgit reset --hard 后仍然显示文件为“更改但未更新”的说法非常令人惊讶。你确定你没有在超级模块中执行 git reset --hard,而在子模块中执行 git status 吗? 你是否设置了任何清理或过滤器? 你设置了 core.autocrlf 吗? - Mark Longair
我肯定执行了 git reset --hard 和 git status 命令在子模块中,我用 pwd 命令进行了双重检查,返回的是 ~/Sites/project.com/vendor/plugins/arena_engine。我还设置了 git config --global core.autocrlf true,我尝试将其设置为 false,看看是否能解决问题,但我感到绝望。 - Karl Entwistle
你能否更改并保存这些文件中的任何一个,以查看是否可能是权限问题?(尽管如果那是问题,我会感到惊讶为什么没有错误消息。另一方面,如果rm project是一个目录,那么显然会是一个错误,因此可能缺少其他错误输出...) - Mark Longair
使用 rm -rf 命令删除了项目,这只是一个打字错误。 - Karl Entwistle
4个回答

9

我同意Richard的看法,这个问题可能来自于大小写敏感性/不敏感性。我将在此答案中解决这个问题。

问题

如果一个git提交包含两个文件名仅以大小写区分,那么将该提交检出到大小写不敏感的文件系统中的工作目录会导致问题。如果提交包含例如myfilemyFILE,git将创建myfile,然后当它尝试创建/更新myFILE时,文件系统会给它一个指向myfile的句柄。

如果myfile和myFILE在仓库中具有不同的内容,则会显现出来。当检出文件时,第二个文件“获胜”,物理文件包含第二个文件的内容。当您运行git status时,索引中的两个文件都与工作目录中的同一文件进行比较,对于输掉的文件,内容不匹配。

验证问题

您可以在大小写敏感的系统上检出存储库以在那里分析和解决所有问题。或者,git提供了足够的工具来处理当前系统上的文件。

确定这是否真的是问题的简单方法是对列出的文件进行微小修改。然后,运行git status应该显示文件名的两个变体,因为工作目录版本与索引中的任何版本都不匹配:

$ echo >> public/javascripts/app/fckeditor/fckpackager.xml
$ git status
Possible outcome:
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   ...
#   modified:   public/javascripts/app/fckeditor/fckpackager.xml
#   modified:   public/javascripts/app/fckeditor/FCKPACKAGER.xml

或者,您也可以使用git ls-files命令查看索引中包含的内容:

$ git ls-files public/javascripts/app/fckeditor/fckpackager.xml
public/javascripts/app/fckeditor/fckpackager.xml
public/javascripts/app/fckeditor/FCKPACKAGER.xml

如果你想精确查看每个文件的内容,你可以使用git checkout-index从索引中提取一个文件并将其保存在某个地方(使用前缀使内容写入单独的文件):

$ git checkout-index --prefix=v1/ public/javascripts/app/fckeditor/fckpackager.xml
$ git checkout-index --prefix=v2/ public/javascripts/app/fckeditor/FCKPACKAGER.xml

分辨率

一旦你确定了想要删除的每个文件的变体,你可以使用 git rm --cached从索引中删除它,该命令会注意到路径的大小写:

$ git rm --cached public/javascripts/app/fckeditor/FCKPACKAGER.xml

然后提交,如果必要的话再执行git reset --hard


然而,你提到使用不同用户登录并得到不同结果可能意味着存在另一个问题。在这种情况下,我会查看用户特定的.gitconfig文件是否有差异。


我似乎已经解决了这个问题,.gitconfig文件存在问题,删除以下内容解决了该问题 [apply] whitespace = fix。 - Karl Entwistle

2
你可能遇到了大小写敏感的问题。默认情况下,Mac文件系统是大小写保留但不区分大小写的。
Git本身是区分大小写的。如果你没有一个区分大小写的文件系统,并且有两个文件名仅因大小写而不同,则git status会显示其中一个文件已修改(假设这两个文件的内容不同)。如果你有两个目录的名称仅因大小写而不同(例如fckeditorFCKeditor),那么Git可能会显示很多修改过的文件。
尝试创建一个区分大小写的卷并在其中运行git clone

2
为清理未跟踪的文件,您应该使用 git clean -xdf 而不是只用 git clean -f -d 除了未跟踪的文件外,还会删除未跟踪的目录。如果未跟踪的目录由另一个git存储库管理,则默认情况下不会将其删除。如果您确实想要删除这样的目录,请两次使用-f选项。
-x 不使用忽略规则。这允许删除所有未跟踪的文件,包括构建产品。这可以用于(可能与git reset一起)创建一个原始的工作目录,以测试干净的构建。

我尝试了git clean -xdf,但是当我输入git status时,这些文件仍然存在,可以提交。 - Karl Entwistle
git clean 不会影响已跟踪的文件,因此这与问题无关。 - Richard Hansen

1

在对子模块仓库进行操作之前,先切换到子模块目录 - 它是自己的仓库。然后您应该能够以通常的方式清理和修复子模块仓库。

虽然各种子模块文章(progit 和 git 社区书籍)都提到了这一点,但并不像需要的那样清晰明了。


OP 删除并重新克隆了整个项目,问题仍然存在,因此还有其他问题--“通常的方法”不起作用。 - Richard Hansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接