【问题标题】:How do I commit case-sensitive only filename changes in Git?如何在 Git 中提交仅区分大小写的文件名更改?
【发布时间】:2016-06-08 18:02:26
【问题描述】:

我通过将第一个字母不大写更改了一些文件名,例如 Name.jpgname.jpg。 Git 无法识别此更改,我不得不删除文件并再次上传。 Git 在检查文件名更改时是否可以区分大小写?我没有对文件本身进行任何更改。

【问题讨论】:

  • @nif 这不是很正确,Git 实际上有一个配置设置来控制它是否忽略区分大小写。
  • stackoverflow.com/a/24979063/6309:从git 2.0.1开始,一个简单的git mv就可以工作了。
  • @nif 只是想添加(几年后;)HFS 可以区分大小写,但默认情况下不区分大小写。我有一个单独的 65 GiB 分区,使用区分大小写的 HFS 格式化,用于我的 git 工作副本。我必须承认,我的理智很多……

标签: git case-sensitive git-commit git-config


【解决方案1】:

使用以下命令:

git config --global  core.ignorecase false

您可以将您的 git 系统全局配置为对文件和文件夹名称区分大小写。

【讨论】:

    【解决方案2】:

    Git 有一个配置设置,告诉它是否需要区分大小写或不区分大小写的文件系统:core.ignorecase。要告诉 Git 区分大小写,只需将此设置设置为 false。 (如果您已经推送了文件,请小心,那么您应该先移动它们,给出其他答案)。

    git config core.ignorecase false
    

    请注意,在不区分大小写的文件系统上将此选项设置为 false 通常是个坏主意。这样做会导致奇怪的错误。例如,以仅更改字母大小写的方式重命名文件将导致 git 报告虚假冲突或创建重复文件(来自 Mark Amery 的评论)

    文档

    来自git config documentation

    core.ignorecase

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

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

    不区分大小写的文件系统

    据我所知,两个最流行的具有不区分大小写文件系统的操作系统是

    • 窗户
    • OS X

    【讨论】:

    • 附带说明,我不认为 Mac OS X 本身不区分大小写。相反,文件系统决定了区分大小写。格式化 HFS+ 分区时,用户可以选择区分大小写或不区分大小写。默认情况下不区分大小写。
    • 在这个答案中似乎非常值得注意的是,在不区分大小写的文件系统上将此选项设置为false 是一个坏主意。这不一定很明显。例如,我刚刚在我的 Mac 上尝试过,认为它可以解决我的问题,然后将文件从 productPageCtrl.js 重命名为 ProductPageCtrl.jsgit status 看到了一个名为ProductPageCtrl.js 文件,但没有 认为productPageCtrl.js 已被删除。当我添加新文件、提交并推送到 GitHub 时,GitHub 存储库现在包含 两个 文件,即使我的(假设是最新的)本地存储库只有一个。
    • @MarkAmery 这听起来很像您的 Git 客户端中的错误。你提交报告了吗?
    • @Domi 这不是错误,这是预期的行为。实际上,在不敏感的文件系统上将其设置为 false 是一个坏主意,因为这就是发生的情况。 git 没有看到小写文件被删除的原因是文件系统没有报告它已删除,因为它忽略这种情况,而 git 没有将此选项设置为 false。这并不是说文件名在 ntfs 上没有小写和大写,或者只是文件名查找忽略了大小写。
    • @Domi git 足够聪明。这就是为什么您应该在不区分大小写的文件系统上将此设置为 false。使用git mv 移动文件,看看git 是如何管理它的。如果您在没有 git 的情况下移动文件,则 什么 git 无能为力,因为文件系统不会向 git 说出真相。这是 ntfs/fat/hfs 之类的问题,而不是 git/linux。
    【解决方案3】:

    只要你只是重命名一个文件,而不是一个文件夹,你就可以使用git mv

    git mv -f yOuRfIlEnAmE yourfilename
    

    (从 Git 2.0.1 中的 a change 开始,上述咒语中的 -f 标志是多余的,但在较旧的 Git 版本中需要它。)

    【讨论】:

    • 这给了我“源目录为空”,而它不是
    • 在此处使用 MacOS(不区分大小写的 FS)并且 -f 有效!感谢您的提示
    • 别忘了给出完整的文件路径。很明显,我知道,但让我有一段时间
    • 最高投票评论:您确实需要使用最新 git (2.18) 的 -f 开关,否则您可能会收到 fatal: destination exists 错误。
    • 请务必注意,如果您尝试重命名目录而不是文件,这将不起作用。如果您需要重命名目录,则必须为目录中的每个文件执行git mv
    【解决方案4】:
    1. 将文件Name.jpg重命名为name1.jpg

    2. 提交删除文件Name.jpg

    3. 将文件name1.jpg重命名为name.jpg

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

      git add name.jpg
      git commit --amend
      

    【讨论】:

    • 我在第 3 步收到了这个fatal: bad source, source=name1.jpg, destination=name.jpg。您有什么建议吗?谢谢
    • 你不能提交,只需要git add
    • 看起来很hacky,不是吗?或者猴子补丁。
    • 为我工作。老实说,从审计的角度来看,它实际上是正确的。
    • 正如CBarr's answer 所说,这里不需要中间提交。您可以重命名、暂存、重命名、暂存,然后提交,而无需在此答案使用的中间额外提交。
    【解决方案5】:

    有时临时更改 Git 的区分大小写很有用。

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

    git -c core.ignorecase=true checkout mybranch 关闭单个checkout 命令的大小写敏感性。或更笼统地说:git -c core.ignorecase= <<true or false>> <<command>>(感谢 VonC 在 cmets 中提出的建议。)

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

    要更改设置更长的时间(例如,如果需要在更改回之前运行多个命令):

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

    【讨论】:

    • 为什么不直接git -c core.ignorecase=<true or false> checkout <<branch>>?之后无需重置。
    • 我对建议的 core.ignorecase 在从小写变为大写时有一种奇怪的体验,但在从大写变为小写时却不行。似乎唯一可靠的解决方案是停止使用无法识别文件名大小写的操作系统。
    • 临时更改有什么原因吗?如果我只是将设置更改为区分大小写,这会导致任何问题吗?
    • 这可能取决于几个因素,特别是目标文件系统是否区分大小写 - 请参阅en.wikipedia.org/wiki/Case_sensitivity#In_filesystems。如果部署文件系统与用于开发的文件系统区分大小写不同,则可能需要临时更改。 在我的情况下,我在一个团队中工作,每个人都应该有相同的 Git 设置(即区分大小写),所以如果我关闭它,它需要是临时的。
    【解决方案6】:

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

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

    【讨论】:

    【解决方案7】:

    我接受了@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()
    

    【讨论】:

      【解决方案8】:

      类似于@Sijmen 的回答,这对我在OSX 上重命名目录 有用(灵感来自另一篇帖子的this 回答):

      git mv CSS CSS2
      git mv CSS2 css
      

      简单地做git mv CSS css给出了无效参数错误:fatal: renaming '/static/CSS' failed: Invalid argument可能是因为OSX的文件系统是case insensitive

      p.s 顺便说一句,如果您使用的是 Django,collectstatic 也不会识别大小写差异,您还必须在静态根目录中手动执行上述操作

      【讨论】:

        【解决方案9】:

        我从其他答案中尝试了以下解决方案,但没有奏效:

        如果您的存储库是远程托管的(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 上重命名,它工作。谢谢。
        • 很高兴知道。这种技术理论上应该适用于任何存储库托管平台,但我很想知道是否有任何它不能使用。
        • 不适用于无法在浏览器中编辑的文件,例如图像或 PDF;显然没有编辑选项。
        • @AbhijitSarkar 好点。我更新了这些案例的答案。我测试并验证了这些说明有效。
        【解决方案10】:

        使用 SourceTree,我可以通过 UI 完成所有这些操作

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

        这有点乏味,但如果你只需要对几个文件进行处理,它会很快

        【讨论】:

        • 与 git bash 相同
        • “暂存该文件”是重要的部分 - 上面的其他答案都不适合我。它实际上适用于普通的旧 Windows 命令提示符。
        • 我没有意识到这在暂存区有效。但就我而言,我想修改文件夹名称以及这些文件夹中的一些文件。所以我首先将所有文件夹重命名为临时名称。提交新名称(其中的所有文件)和“已删除”文件。 Git 将它们全部标记为“重命名”。然后将所有这些文件夹重命名为新的案例版本并再次提交。最后,合并这 2 个提交。但根据你写的,我可以直接通过座位区完成整个事情,而不需要创建 2 个提交 + 合并。
        • 也适用于文件夹名称的 gitkraken。
        • 如果您的操作系统不区分大小写,对文件名的更改将不会出现在 Sourcetree 中
        【解决方案11】:

        如果没有任何效果,请使用 git rm filename 从磁盘中删除文件并将其添加回来。

        【讨论】:

        【解决方案12】:

        我使用了以下步骤:

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

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

        【讨论】:

        • 这就是解决方案。与其他答案不同,它在您进行批量重命名时效果很好。在 glamourphilly.org 上,我们需要将每个 .Jpg 更改为 .jpg。在 Finder 中,您可以像这样进行批量重命名,这个答案可以让您签入。
        • 这对我来说也是唯一简单的解决方案
        • 这是迄今为止最简单的解决方案。适用于文件和目录。谢谢!
        • OMG THANK THANK THANK THANK YOUUUU 我已经准备好扯头发了,为什么我在 github 上有两个相同文件夹的案例,即使在本地我只有一个案例!这很令人沮丧,谢谢
        • 这个命令实际上做的是删除 git 认为仍然存在的文件/文件夹名称的缓存版本。因此它将清除其缓存,但将所有内容保留在当前文件夹中(您已在本地进行更改),但它会看到那些其他错误的案例文件夹/文件不再存在,因此将在git status 中将它们显示为已删除。然后你可以推送到 github,它会删除错误案例的文件夹/文件。这个答案有一个描述命令含义的图形:stackoverflow.com/a/41863575/4484799
        【解决方案13】:

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

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

        您的驱动器将位于/Volumes/Sensitive/

        How do I commit case-sensitive only filename changes in Git?

        【讨论】:

        • 我喜欢这个建议,它优雅而轻松地解决了问题,而无需求助于丑陋的变通方法。谢谢!
        【解决方案14】:

        当您进行了大量文件重命名并且其中一些只是更改大小写时,很难记住哪个是哪个。手动“git移动”文件可能是相当多的工作。所以在我的文件名更改任务中我会做的是:

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

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

        【讨论】:

        • 为什么不在第 4 段中git commmit --amend?否则,将有一个额外的提交与删除所有文件。或者您可以将git rebase -i 与壁球一起使用。
        【解决方案15】:

        我在 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~2drop TEMP COMMIT!!
        5. 确认文件现在名为FooBar.java

        【讨论】:

        • -1。我无法重现您在此处提到的错误,没有它,其余的答案就没有意义。此外,在没有正在进行 rebase 的情况下执行 git rebase --continue 只会产生 "No rebase in progress?" 错误,并且在步骤 4.2 期间没有正在进行 rebase,因此在那里运行该命令没有意义要么。
        【解决方案16】:

        在 OSX 下,为了避免这个问题并避免在不区分大小写的文件系统上开发时出现其他问题,您可以使用磁盘工具创建一个区分大小写的虚拟驱动器 /磁盘映像。

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

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

        git config core.ignorecase false
        

        【讨论】:

        • 不,核在 OSX 上运行完全区分大小写的引导驱动器。您将不得不在没有写得不好(咳咳,Adobe)的应用程序的情况下生活,或者在他们自己的案例愚蠢的虚拟机中运行这些应用程序,但如果您主要为 *nix 系统编写代码,这是值得的。
        • 这是唯一可以正常工作的选项。我已经尝试了其余的,但你最终会以一种或另一种方式泡菜。这样做可以正确解决问题。
        • 请注意,磁盘工具有一个错误 OS X 10.11 -- 它不会创建区分大小写的图像。您需要使用命令行工具 hdiutil。 apple.stackexchange.com/questions/217915/…
        • 借助 High Sierra 中的 APFS,这更加容易。单击带有加号的驱动器图标,然后添加一个区分大小写且没有大小限制的卷。它只是与主卷共享空间并安装在 /Volumes/volume-name。
        【解决方案17】:

        这就是我在 OS X 上所做的:

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

        两个步骤,否则我会收到“文件存在”错误。或许可以通过加--cached之类的方式一步完成。

        【讨论】:

        • 如最佳答案所示,-f(强制)是您正在寻找的标志
        • @rperryng - 不,-f 标志在底层 FS 不区分大小写的情况下无济于事。但是,两步解决方案对我有用
        • 使用不区分大小写的 FS(在 Mac 上)和 -f 工作!感谢您的提示
        • 这也适用于没有 -f 标志的 Windows 上的文件夹。
        • git -c "core.ignorecase=false" add . 将考虑提交大小写已更改的文件。
        猜你喜欢
        • 2012-05-18
        • 2020-04-18
        • 1970-01-01
        • 2021-04-23
        相关资源
        最近更新 更多