git mv和仅更改目录的大小写


259

虽然我发现了类似的问题,但没有找到解决问题的答案

当我尝试通过该目录从FOO重命名为foo git mv FOO foo我得到

fatal: renaming 'FOO' failed: Invalid argument

好。所以我尝试git mv FOO foo2 && git mv foo2 foo

但是,当我尝试提交通过git commit .我得到

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# foo
nothing added to commit but untracked files present (use "git add" to track)

当我通过git add foo任何方式添加目录时,都不会更改,并git commit .再次给我相同的消息。

我究竟做错了什么?我以为我使用的是区分大小写的系统(OSX),为什么我不能简单地重命名目录?


10
OS X的文件系统不区分大小写。
mipadi 2010年

2
@mipadi它可以在区分大小写的模式下运行,但是默认情况下通常是关闭的。
GordonM 2012年

1
这个问题及其答案在Windows中也很有用。考虑取消标记“ osx”
Barett

1
参见stackoverflow.com/a/24979063/6309:自git 2.0.1起,很简单git mv
VonC 2015年

在Windows上,git mv foo Foo如果您使用cygwin shell ,则可以使用常规。
安德鲁·斯科特

Answers:


409

您处于不区分大小写的环境中。此外,如Git所理解-Amv那样,添加no 将不会照顾到remove的一面。警告!执行此操作时,请确保没有其他更改或未跟踪的文件,否则它们将作为更改的一部分提交! git stash -u首先,执行此操作,然后再执行git stash pop。继续:要解决此问题,请执行以下操作:

mv foo foo2
git add -A
git commit -m "renaming"
mv foo2 FOO
git add -A
git commit --amend -m "renamed foo to FOO"

这是更改工作目录,提交然后折叠2个提交的引出方式。您可以只在索引中移动文件,但是对于git的新手来说,它对发生的事情可能不够明确。较短的版本是

git mv foo foo2
git mv foo2 FOO
git commit -m "changed case of dir"

如其中一项注释中所建议,您还可以进行交互式重新编排(git rebase -i HEAD~5如果在5次提交之前引入了错误的案例)来修复该案例,而不会在历史记录中的任何位置出现错误的案例。如果要执行此操作,则必须小心,因为从那时起的提交哈希值将有所不同,而其他哈希表必须将其工作与最近的分支重新建立基础或重新合并。

这与更正文件名有关:git不区分大小写吗?


1
谢谢。这让我发疯。我不知道-A或--amend选项。
oschrenk 2010年

7
小心-A,因为它将递归地添加当前目录中的所有内容,包括未跟踪的内容。可能更好git add foo2
rich.e 2012-12-22

2
那是正确的。但是,您将需要分别除去foo2和添加FOO。-A照顾两者。反之亦然。我将添加警告。谢谢!
Adam Dymitruk

您还可以使用交互式资源库来清理历史记录git rebase -i HEAD~2。注意:为简化此过程,请在您的第一次提交中设置最终消息,并修复第二个消息。
Alex B.

5
我在git mv foo foo2上取得了成功;git mv foo2 FOO; git commit
Chris

146

您要将选项设置core.ignorecase为false,这将使Git注意本机不支持它的文件系统的大小写。要在您的仓库中启用:

$ git config core.ignorecase false

然后,您可以使用重命名文件,该文件git mv将按预期工作。


1
我认为这可能在其他地方产生不良影响。不区分大小写的系统应让Git认为它是相同的目录。
Adam Dymitruk 2010年

2
我将选项添加到了全局配置中,但没有帮助
oschrenk 2010年

3
我在OSX上看到了一些奇怪的行为。hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:但...这些文件不存在。
Skylar Saveland

这正是我想要的。我正在运行CentOS 5.6,但没有发现大小写的变化。
crmpicco 2014年

5
这行不通!在Git 1.8.3上,Git将重命名的文件视为新文件,而不是删除+添加。提交此类将使存储库中保留两个相同的文件,例如foo和FOO都存在!但是,当结帐时仅出现一个文件(但一个案件可能胜过另一个案件)
Johnny Wong

68

我能够通过使用临时文件名使用git 1.7.7解决此问题:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"

有趣。从那时起,也许GIT有所改善。当我再次遇到这个问题时,我将再次尝试。
oschrenk'5

这样更容易
olore 2012年

在macOS上为我工作。
Mr_Pouet

14

git mv-free变体。)

我在Mac OS X 10.9的Git中遇到了这个问题。我解决了如下问题:

git rm -r --cached /path/to/directory

这会在Git中暂存要删除的目录,但实际上不会删除任何物理文件(--cached)。这也使得该目录(现在以适当的大小写)显示在未跟踪的文件中。

因此,您可以执行以下操作:

mv /path/to/directory /path/to/DIRECTORY
git add -A /path/to/DIRECTORY

然后,Git将识别出您已经重命名了文件,并且当您这样做时git status,应该会看到许多renamed:行。检查它们并确保它们看起来正确,如果正确,则可以正常地进行更改。


我发现该mv命令实际上无法重命名目录。我不得不在Finder中重命名它。除此之外,此修复程序可以完美运行。
亚当S

9

这是一个快速且安全的错误解决方案:

git mv -f path/to/foo/* path/to/FOO/

警告!始终重命名重命名文件夹中的所有文件(使用/*)。

不要重命名单个文件。这将导致错误,如答案中所述

如果您首先要先查看结果,请使用-n

git mv -f -n path/to/foo/* path/to/FOO/

完成后mv

  1. 提交变更
  2. 检阅任何其他修订
  3. 结帐回来。

现在,Git应该已经在其内部文件和文件系统中将文件夹BOTH重命名了。


正如我在上面的问题注释中提到的,这仅适用于Git 2.0.1吗?(指stackoverflow.com/a/24979063/6309
VonC

8

使用-f选项强制使用:

git mv -f FOO foo

不适合我。我的设置是.git / config的“ ignorecase = true”。这样,重命名不能在暂存区中暂存。(Git版本1.8.3.msysgit.0)Adam Dymitruk的解决方案是唯一正确的答案。
Johnny Wong

@JohnnyWong改变你的设置false,它为我工作
因德尔·库马尔·拉索

这样,即使其他用户的计算机被设置为忽略大小写,它是否也会在所有其他用户的计算机上更新?
布莱斯

@Bryce不,您需要提交更改并将其推送到中央存储库,然后其他用户才能拉出更改。
konyak '16

3

我有一个相关的问题。

一个文件夹名为“ Pro”(首先创建),另一个名为“ pro”(错误创建)。在Mac中,这是同一件事,但是根据git的不同。

$ git config core.ignorecase false

git config将文件重命名到正确的文件夹(谢谢),并在'pro'中创建了幻影文件(No !!)。我无法将幻影文件更改添加到音轨,也无法签出其他分支,除非随身携带这些文件,而且我也无法以某种方式重置它。

取而代之的是,我做到了

$ git rm -r --cached pro
$ git status // => pro files removed, new Pro files untracked
$ git add Pro

为了使其更加安全,我在一个单独的修订分支中进行了此操作,然后将其合并回主分支

对于造成的Ghost文件问题,任何一位专家都可以解释如何以及为什么吗?提前致谢。


2

除非明确选择,否则您不会在OS X中使用区分大小写的文件系统。HFS + 可以区分大小写,但默认值不区分大小写。


4
在OS X上使用区分大小写的文件系统不是一个好主意。我从尝试中了解到很多应用程序无法正常运行。一个特殊的问题是Adobe Photoshop将拒绝安装,原因是不支持区分大小写的文件系统。
jpswain 2011年

1

这是围绕此页面上所有gitfoo的一个非常简单的解决方案。

  1. 手动将文件复制到项目中。
  2. git rm所有文件。
  3. git commit像往常一样。
  4. 手动添加文件。
  5. git添加所有文件。
  6. git commit像往常一样。
  7. 利润。

1
这在本地有效,但是如果其他人进行拉动,则不会改变情况。
杰森

感谢您在不同情况下帮助我修复git中的重复项。我使用了这种形式。刚刚重命名了父文件夹。做了一个承诺。然后将父文件夹重命名为原始文件夹。并做了第二次提交。现在,不同大小写的旧条目消失了。
dreamerkumar

0

使用“ git mv”改进Adam Dymitruk的答案(很傻,SO不允许我评论他的答案),它将自动准确地移动文件。无需隐藏,可以避免使用危险的“ git add -A”:

old="abc";    new="ABC";
tmp="$old-renamed";
git mv "$old" "$tmp";
git commit -m "Renamed '$old' to '$tmp'.";
git mv "$tmp" "$new";
git commit --amend -m "Renamed '$old' to '$new'.";

0

在Windows上,这对我来说很棒。使用过的powershell具有以下功能:

  1. mv .\Folder-With-Wrong-Casing .\temp
  2. git add -A
  3. git commit -m "renamed folder with wrong casing to temp"
  4. mv .\temp .\Folder-with-Correct-Casing
  5. git add -A
  6. git commit --amend -m "Renamed to proper casing"
  7. (可选的) git push

感谢以上亚当的回答。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.