如何在Git中提交仅区分大小写的文件名更改?


1300

我已经改变了一些文件名去首字母大写,如Name.jpgname.jpg。Git无法识别此更改,因此我不得不删除文件并再次上传。检查文件名的更改时,Git是否可以区分大小写?我尚未对文件本身进行任何更改。


4
@nif这不是很正确,Git实际上有一个配置设置来控制它是否忽略大小写。


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


请参阅这篇文章。我能够提交,但仅使用git commit -m“ msg”而不使用任何文件路径作为参数。它更新了索引并检入了文件。[link] stackoverflow.com/questions/35790113/…–
ARKS

Answers:


1512

您可以使用git mv

git mv -f OldFileNameCase newfilenamecase

12
这给了我“源目录为空”而并非为空
WiseStrawberry 2014年

6
在这里使用MacOS(不区分大小写的FS)和-f起作用了!谢谢你的提示
caesarsol

49
在最新版本中,您不再需要该-f标志。
Joshua Pinter

8
不要忘记提供完整的文件路径。很明显,我知道,但是让我了一段时间
rickrizzo

7
最有投票权的评论:您确实需要-f使用最新的git(2.18)进行切换,否则可能会fatal: destination exists出错。
DeepSpace101 '19

1035

Git的配置设置告诉它是否区分大小写:core.ignorecase。要告诉Git区分大小写,只需将此设置设置为false

git config core.ignorecase false

文献资料

git config文档中

core.ignorecase

如果为true,则此选项启用各种变通办法,以使git在不区分大小写的文件系统(例如FAT)上更好地工作。例如,如果目录列表makefile在git期望的时间找到Makefile,则git将假定它确实是同一文件,并继续将其记为Makefile

默认值为false,除了git-clone(1)git-init(1)core.ignorecase在创建存储库时进行探测并设置为true(如果适用)。

不区分大小写的文件系统

我所知道的两种最不区分大小写的文件系统是:

  • 视窗
  • OS X

9
附带一提,我认为Mac OS X本身不区分大小写。而是由文件系统决定是否区分大小写。格式化HFS +分区时,用户可以选择是区分大小写还是不区分大小写。默认大小写不区分大小写。
spaaarky21 2014年

225
在这个答案中似乎非常值得注意,在false不区分大小写的文件系统上将此选项设置为一个好主意。这不一定很明显。例如,我刚刚在Mac上尝试过此操作,认为它可以解决我的问题,然后将文件从重命名productPageCtrl.jsProductPageCtrl.jsgit status看到一个名为的文件,ProductPageCtrl.js认为productPageCtrl.js已被删除。当我添加新文件,提交并推送到GitHub时,即使我(据说是最新的)本地存储区只有一个,GitHub存储区现在也包含两个文件。
Mark Amery

5
@MarkAmery听起来很像您的Git客户端中的错误。您提交报告了吗?
米(Domi)2015年

24
@Domi这不是错误,这是预期的行为。实际上,在不敏感的文件系统上将其设置为false是一个坏主意,因为这会发生。git看不到小写文件被删除的原因是文件系统没有将其报告为已删除,因为它确实忽略了大小写,而git没有将此选项设置为false。不是文件名在ntfs上没有小写还是大写,或者不是文件名查找忽略大小写。
ohcibi

15
@Domi git 聪明。因此,在不区分大小写的文件系统上,不应将其设置为false。使用git mv移动文件,看看Git是如何对其进行管理。如果在没有git的情况下移动文件,则git无法执行任何操作,因为文件系统没有向git讲真相。这是ntfs / fat / hfs之类的问题,而不是git / linux。
ohcibi'6

157

使用SourceTree,我能够从UI进行所有操作

  1. 重命名 FILE.extwhatever.ext
  2. 暂存该文件
  3. 现在重命名 whatever.extfile.ext
  4. 舞台再次证明文件

这有点乏味,但是如果您只需要对几个文件进行处理,那将会非常快


5
与git bash相同
Alex78191

3
“保存该文件”是重要的部分-上面的其他答案对我来说都不起作用。实际上,它可以与普通的旧Windows命令提示符一起使用。
弗拉德·萨贝夫

1
我没有意识到这在暂存区中起作用。但就我而言,我想修改文件夹名称以及这些文件夹中的某些文件。因此,我首先将所有文件夹重命名为临时名称。提交新名称(其中的所有文件)和“已删除”文件。Git将它们全部标记为“重命名”。然后将所有这些文件夹重命名为其新的案例版本,然后再次提交。最后,合并这两个提交。但是根据您的写法,我可以直接在指定区域完成整个操作,而无需创建2个commits + merge。
ThermoX

3
也可以在文件夹名称上与gitkraken一起使用。
菲利普·马特雷

我编写了Python 3脚本来完成这项繁琐的工作:stackoverflow.com/a/58159822/4934640
用户

126

这是我在OS X上所做的:

git mv File file.tmp
git mv file.tmp file

两步,因为否则我收到“文件存在”错误。也许可以通过添加--cached等一步来完成。


21
如最佳答案所示,-f(力)是您要寻找的旗帜
rperryng

5
@rperryng-不,-f如果基础FS不区分大小写,则该标志无济于事。但是,两步解决方案对我
有用

使用不区分大小写的FS(在Mac上)成功了-f!谢谢你的提示
caesarsol

这也适用于不带-f标志的Windows文件夹。
NICH

git -c "core.ignorecase=false" add .将考虑大小写已更改以提交的文件。
nietonfir

67

暂时更改Git的大小写敏感性有时很有用:

方法1-更改单个命令的区分大小写:

git -c core.ignorecase=true checkout mybranch关闭单个checkout命令的区分大小写。或者更一般地说:。(感谢VonC在评论中建议这一点。)git -c core.ignorecase= <<true or false>> <<command>>

方法2-更改多个命令的区分大小写:

更改设置的时间更长(例如,如果需要先运行多个命令再将其更改回),请执行以下操作:

  1. git config core.ignorecase(这将返回当前设置,例如false)。
  2. git config core.ignorecase <<true or false>> -设置所需的新设置。
  3. ...运行其他多个命令...
  4. git config core.ignorecase <<false or true>> -将配置值恢复为之前的设置。

1
为什么不直接git -c core.ignorecase=<true or false> checkout <<branch>>呢?之后没有任何重置。
VonC

2
我对拟议的core.ignorecase在从小写变为大写而不是从大写变为小写时的工作有一种奇怪的体验。似乎唯一可靠的解决方案是停止使用无法识别文件名大小写的操作系统。
aspiringGuru

是否有理由应该进行临时更改?如果仅将设置更改为区分大小写,那会引起任何问题吗?
cytsunny

这可能取决于一些因素,尤其是目标文件系统是否区分大小写-请参阅en.wikipedia.org/wiki/Case_sensitiveivity#In_filesystems。如果部署文件系统对用于开发的文件系统具有不同的大小写敏感性,则可能需要临时更改。同样在我的情况下,我在一个团队中工作,每个人都应该具有相同的Git设置(即区分大小写),因此,如果我将其关闭,则它必须是临时的。
史蒂夫·钱伯斯

44

在OSX下,为避免此问题并避免在不区分大小写的文件系统上进行开发时遇到其他问题,可以使用“磁盘工具”来创建区分大小写的虚拟驱动器 /磁盘映像。

运行磁盘实用程序,创建新的磁盘映像,并使用以下设置(或根据需要进行更改,但区分大小写):

Mac Disk Utility屏幕截图

确保告诉git它现在位于区分大小写的FS上:

git config core.ignorecase false

15
不,Nuclear在OSX上运行完全区分大小写的启动驱动器。您将不得不生活在没有写得不好的(糟糕的,Adobe的)应用程序中,或者在自己的笨拙的VM中运行这些应用程序,但是如果您主要为* nix系统编写代码,那是值得的。
Mike Marcacci

1
这是唯一可以正常工作的选项。我尝试了其余的方法,您最终还是以一种或多种方式泡菜。这样做可以正确解决问题。
约翰·亨特

2
请注意,磁盘工具存在OS X 10.11错误-它不会创建区分大小写的映像。您需要使用命令行工具hdiutil。apple.stackexchange.com/questions/217915/…–
dellsala

7
借助High Sierra中的APFS,这甚至更加容易。单击带有加号的驱动器图标,然后添加大小写敏感的卷,且大小不受限制。它仅与主卷共享空间,并挂载在/ Volumes / volume-name。
迈克尔·福克斯

21

我从其他答案中尝试了以下解决方案,但它们不起作用:

如果您的存储库是远程托管的(GitHub,GitLab,BitBucket),则可以在源位置重命名文件(GitHub.com),并以自上而下的方式强制重命名该文件。

以下说明与GitHub有关,但是它们背后的一般思想应适用于任何远程存储库托管平台。请记住,您尝试重命名的文件类型很重要,也就是说,它是GitHub在浏览器中认为是可编辑的(代码,文本等)还是不可编辑的(图像,二进制等)文件类型。

  1. 访问GitHub.com
  2. 导航到GitHub.com上的存储库,然后选择您正在使用的分支
  3. 使用网站的文件导航工具,导航到要重命名的文件
  4. GitHub是否允许您在浏览器中编辑文件?
    • a。)可编辑
      1. 点击“编辑此文件”图标(看起来像铅笔)
      2. 在文件名文本输入中更改文件名
    • b。)无法编辑
      1. 在新标签页中打开“下载”按钮,然后将文件保存到计算机
      2. 重命名下载的文件
      3. 在GitHub.com上的上一个标签中,点击“删除此文件”图标(看起来像垃圾桶)
      4. 确保branchname选中“直接提交到分支”单选按钮,然后单击“提交更改”按钮
      5. 在GitHub.com上的同一目录中,单击“上传文件”按钮
      6. 从您的计算机上传重命名的文件
  5. 确保branchname选中“直接提交到分支”单选按钮,然后单击“提交更改”按钮
  6. 在本地,签出/提取/拉出分支
  7. 完成了

我直接在BitBucket上重命名,并且有效。谢谢。
rsc

很高兴知道。从理论上讲,该技术应可在任何存储库托管平台上使用,但我想知道是否有任何它不能使用的功能。
gmeben

不适用于无法在浏览器中编辑的文件,例如图像或PDF;很明显,没有编辑选项。
Abhijit Sarkar '18

@AbhijitSarkar好点。对于这些情况,我更新了答案。我测试并验证了这些说明的工作原理。
gmeben

任何人都可以通过这种方式重命名目录吗?
Solvitieg

20

类似于@Sijmen的答案,这是我在重命名目录时在OSX上起作用的方式(灵感来自另一篇文章):

git mv CSS CSS2
git mv CSS2 css

简单地做git mv CSS css就给出了无效的参数错误:fatal: renaming '/static/CSS' failed: Invalid argument也许是因为OSX的文件系统是不区分大小写

ps BTW如果您使用的是Django,collectstatic也无法识别大小写差异,因此您还必须在静态根目录中手动执行上述操作


18

1)重命名文件Name.jpgname1.jpg

2)提交删除的文件 Name.jpg

3)将文件重命名name1.jpgname.jpg

4)将添加的文件修改name.jpg为先前的提交

git add
git commit --amend

2
fatal: bad source, source=name1.jpg, destination=name.jpg在第3步得到这个。您有建议吗?Thx
安东尼·孔

1
您不能进行提交,只是git add
Alex78191

看起来很hacky,不是吗?或猴子修补。
jeromej '18 -10-2

18

我使用了以下步骤:

git rm -r --cached .
git add --all .
git commit -a -m "Versioning untracked files"
git push origin master

对我来说是一个简单的解决方案


这是解决方案。并且与其他答案不同,当您进行批量重命名时,它可以很好地工作。在glamourphilly.org上,我们需要将每个.Jpg都更改为.jpg。在Finder中,你可以做批量重命名这样的,这个答案让你托运。
威廉Entriken

10

我们可以使用git mv命令。下面的示例,如果我们将文件abcDEF.js重命名为abcdef.js,则可以从终端运行以下命令

git mv -f .\abcDEF.js  .\abcdef.js

8

Mac OSX High Sierra 10.13对此进行了一些修复。只需为您的git项目创建一个虚拟APFS分区,默认情况下它没有大小限制并且不占用空间。

  1. 在“磁盘工具”中,选择“容器”磁盘后单击“ +”按钮
  2. 在格式下选择APFS(区分大小写)
  3. 命名 Sensitive
  4. 利润
  5. 可选:在“敏感”文件夹中创建一个名为gitln -s /Volumes/Sensitive/git /Users/johndoe/git

您的驱动器将进入 /Volumes/Sensitive/

在此处输入图片说明

如何在Git中提交仅区分大小写的文件名更改?


我喜欢这个建议,它可以优雅而轻松地解决问题,而无需采取丑陋的解决方法。谢谢!
Phil Gleghorn

4

我在MacOS上已经多次遇到此问题。Git区分大小写,但Mac仅保留大小写。

有人提交文件:Foobar.java几天后决定将其重命名为FooBar.java。当您提取最新代码时,它将失败并显示The following untracked working tree files would be overwritten by checkout...

我所见的解决此问题的唯一可靠方法是:

  1. git rm Foobar.java
  2. 提交您不能错过的消息 git commit -m 'TEMP COMMIT!!'
  3. 这将弹出一个冲突,迫使您合并该冲突-因为您的更改将其删除,但另一个更改已重命名(因此出现问题)
    1. 接受您的更改,即“删除”
    2. git rebase --continue
  4. 现在放弃您的解决方法git rebase -i HEAD~2dropTEMP COMMIT!!
  5. 确认文件已被调用 FooBar.java

3

当您完成了许多文件重命名,而其中的一些只是大小写的更改时,很难记住是哪个。手动“ git move”文件可以完成很多工作。因此,在文件名更改任务期间我将要做的是:

  1. 将所有非git文件和文件夹删除到另一个文件夹/存储库。
  2. 提交当前空的git文件夹(这将显示为已删除的所有文件。)
  3. 将所有文件重新添加到原始git文件夹/存储库中。
  4. 提交当前的非空git文件夹。

这将解决所有案例问题,而无需尝试找出重命名的文件或文件夹。


为什么不在git commmit --amend第4段中?否则,将删除所有文件,从而产生额外的提交。或者您可以git rebase -i与壁球一起使用。
Alex78191

1

如果没有任何效果,请使用git rm filename从磁盘删除文件,然后将其重新添加。


0

我用@CBarr回答并编写了Python 3脚本来处理文件列表:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import os
import shlex
import subprocess

def run_command(absolute_path, command_name):
    print( "Running", command_name, absolute_path )

    command = shlex.split( command_name )
    command_line_interface = subprocess.Popen( 
          command, stdout=subprocess.PIPE, cwd=absolute_path )

    output = command_line_interface.communicate()[0]
    print( output )

    if command_line_interface.returncode != 0:
        raise RuntimeError( "A process exited with the error '%s'..." % ( 
              command_line_interface.returncode ) )

def main():
    FILENAMES_MAPPING = \
    [
        (r"F:\\SublimeText\\Data", r"README.MD", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\Alignment", r"readme.md", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\AmxxEditor", r"README.MD", r"README.md"),
    ]

    for absolute_path, oldname, newname in FILENAMES_MAPPING:
        run_command( absolute_path, "git mv '%s' '%s1'" % ( oldname, newname ) )
        run_command( absolute_path, "git add '%s1'" % ( newname ) )
        run_command( absolute_path, 
             "git commit -m 'Normalized the \'%s\' with case-sensitive name'" % (
              newname ) )

        run_command( absolute_path, "git mv '%s1' '%s'" % ( newname, newname ) )
        run_command( absolute_path, "git add '%s'" % ( newname ) )
        run_command( absolute_path, "git commit --amend --no-edit" )

if __name__ == "__main__":
    main()
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.