在git origin(比特桶)中出现了大小写不同的重复文件

56

我试图将文件从foobar.php重命名为FooBar.php,在Git中这是一个相当大的挑战。到目前为止,我已经发现我必须设置git配置值ignorecasefalse(不管怎样,为什么在Mac OS X上默认为true?)。我已成功地在本地仓库中重命名了这些文件,但在将其推送到BitBucket后,我在那里得到了FooBar.php以及foobar.php。如何摆脱这些重复文件?谢谢。

6个回答

60

忽略大小写但保留大小写

你可能遇到的问题是,mac上默认的文件系统是忽略大小写但保留大小写;在这种情况下,file.phpFile.php不能同时存在-它们被视为同一个文件。

这很容易证明:

$ cd /tmp
$ mkdir example
$ cd example/
$ git init
Initialized empty Git repository in /private/tmp/so/.git/ 
$ touch readme
$ git add readme 
$ git commit -m "adding readme"
[master (root-commit) 05fdf7d] adding readme
 0 files changed
 create mode 100644 readme
$ mv readme x
$ git status 
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#  deleted:    readme
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       x
no changes added to commit (use "git add" and/or "git commit -a")
$ mv x README
$ git status 
# On branch master
nothing to commit (working directory clean)
$ ls -l
total 0
-rw-r--r--  1 andy  wheel  0 Aug  1 19:38 README

上面的文件现在被命名为README,但是根据Git,文件readme存在且未被修改。

使用两个提交

所以,不要将文件重命名(在大小写不敏感的系统上会有问题),而是分两步进行:

$ mv file.php /tmp
$ git rm file.php
$ git commit -m "deleting file"
$ git push

确保不需要的文件已经从代码库中删除。然后将该文件移回正确位置并进行添加。

$ mv /tmp/file.php File.php
$ git add File.php
$ git commit -m "adding File"
$ git push   

4
谢谢!我已经完成了一步操作,就像这样:git mv foobar.php foobar.php.bak git mv foobar.php.bak FooBar.php git commit -m "重命名文件。"看起来应该可以工作。 - petiar
很奇怪。它在一个目录中的文件上运行正常(我已经将大小写设置正确,并且BitBucket上的重复文件已经消失了)。然而,在另一个目录中的文件上却不起作用(我在git状态中看到了删除的文件,我已经将它们提交并推送到了origin,但是在BitBucket上仍然存在这些重复文件)。我现在会尝试你的方式。 - petiar
好的,我已经按照您的方式进行了操作,但在BitBucket上仍然存在重复项(包括FooBar.php和foobar.php,它们都有相同的提交信息“添加文件。”)。还有其他想法来管理执行文件重命名这样复杂和复杂的过程吗? - petiar
你说的“什么repo”是什么意思?这是我的私人repo。现在我决定删除整个目录。我已经将其移动到/tmp并提交和推送了,但该目录仍然存在于BitBucket上。每个文件名和大小旁边都有“...”。 - petiar
抱歉,我不知道那是什么意思(我不确定你在做什么,也不知道你所说的“每个文件名和大小旁边都有‘...’”是什么意思)。我建议你获取一些交互式帮助,例如 chat 或者在 freenode irc 上的 #git 频道。或者检查你可以访问的任何服务器上的存储库(repo),并在那里纠正大小写问题,提交并推送。 - AD7six
显示剩余2条评论

24

应用于目录

由于我在目录级别(而不是文件级别)遇到了这个问题,因此以下是应用于文件夹的步骤(这是在 Windows 上,git 版本为 v2.9.2):

  • Bitbucket 将显示两个子文件夹,比如 FoobarFooBar,它们下面有不同的文件/文件夹。
  • 在客户端上,将 core.ignorecase 设置为 true 并将两个文件树合并到一个共同的根路径下,比如 Foobar
    • 不要立即将 core.ignorecase 设置为 false,否则会让您突然发现其他路径中的“未跟踪”文件!
  • git mv Foobar Foobar.tmp - 您会得到一组重命名的文件,还有一组从其他路径中删除的文件及其相应的未跟踪文件。
  • git add . - 将所有删除/未跟踪的文件添加到暂存区。
    • 对我来说,这个方法可以正常工作。尽管这些看起来像是删除/添加操作,但这些文件的历史记录并没有被删除。
  • git commit -m "将 Foo[Bb]ar 同步到临时文件夹中" - 提交临时文件夹。
  • git mv Foobar.tmp FooBar - 现在将文件夹从临时名称更改为所需的名称。
  • git commit -m "将 FooBar 移动到指定位置" - 提交目标名称。
  • git push - 现在 Bitbucket 应该显示一个名为 FooBar 的子文件夹。
  • git config [--global] core.ignorecase false - 不要再遇到这个问题了。

太棒了!正是我所需要的,顺便说一下。Git就像某种神秘的魔法。太神奇了:D - Olaj
我以为我要疯了,直到我发现了你的解决方案。谢谢! - Niraj Pandey
@McGuireV10 一些 Git 命令,如“rm”或“mv”,会立即将它们的效果添加到暂存区。 - ThomasH
1
@McGuireV10 这与无关的活动无关。第一个 mv 命令通常会导致您本地 Git 认为是“未跟踪”的第二个目录中的一些文件,而未跟踪的文件需要显式添加,以便在以下提交中包含它们。 - ThomasH
你是我的英雄 :D - naspinski
显示剩余3条评论

6

将代码克隆/检出到区分大小写的文件系统(在 Mac OS X 上,您可以制作区分大小写的磁盘映像),然后使用 git rm 命令删除您不想要的大写字母文件。

至于为什么要将 ignorecase 设置为 true,文档 中有说明:

core.ignorecase
默认值为 false,但是在创建存储库时,git-clone(1)git-init(1) 将探测并设置 core.ignorecase 为 true。

由于您的 Mac 可能具有不区分大小写的文件系统(这是默认设置),因此 git 会注意到并适当地设置标志。


感谢您的回复。我的Mac OS X是区分大小写的,但是当我将origin/master拉到本地master分支时,我只看到正确大小写的文件,没有重复的文件。然而,在BitBucket上有重复的文件。或者您是指其他的事情吗?很抱歉,我对git还不熟悉。 - petiar
你确定你的文件系统区分大小写吗?那有点奇怪。 - Carl Norum
5
抱歉,这些年来我一直认为Mac OS X应该是类Unix系统,因此区分大小写。但显然它并不是,这让我有点震惊,老实说。感谢所有的回复,我会尝试处理这个新情况,以免在1 Infinite Loop上伤害到任何人。 - petiar
2
HFS+默认情况下是区分大小写但不区分大小写的。 - Carl Norum
是的,现在我意识到这是文件系统的问题,而不是操作系统。很有道理。 - petiar

2
一个简单而快速的解决方法是来回重命名受影响的根文件夹:
例如:
mv src src-tmp
git add .
git commit 'step 1'
git push origin your-branch
mv src-tmp src
git add .
git commit 'step 2'
git push origin your-branch

这应该解决所有文件大小写问题(如果在您的本地修复)。

2
我在Sourcetree的Windows版本上得到了以下更改:

enter image description here

我通过设置所需的大小写来解决了这个问题,在这种情况下是 constants.ts
将文件移动,这样 git 就会删除带有错误大小写的文件,然后提交。

enter image description here

然后只需将文件移回去:

enter image description here

现在一切都按预期运行。

enter image description here


0
  1. 启用 Git 的大小写敏感功能

    git config core.ignorecase true

  2. 从 Git 中删除文件(Git 现在会提示 foobar.php 文件已丢失,FooBar.php 文件已被删除)

    git rm FooBar.php

  3. 提交文件 "FooBar.php"(请确保只提交您不需要的文件 - 在这里我正在删除大写字母文件名文件)

  4. 推送更改并还原丢失的文件。

  5. 恢复为不区分大小写

    git config core.ignorecase false


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