首页 > 解决方案 > 如何更改已提交的多个文件名称的大小写?

问题描述

我想将我在 Git 上上传的所有 500 张图片重命名为小写。

如果我使用小写图像推送代码,Git 会忽略大小写。
是否有任何特定的命令来修复它?

操作系统:MAC

标签: gitmacosfilenames

解决方案


如果我用小写图像推送代码,Git 会忽略大小写...

这实际上不是真的。

要正确理解问题,您需要了解以下内容:

  • Git 不存储文件,而是提交

  • 提交确实存储文件,但您的计算机正常存储的方式不同。存储在提交中的文件始终具有区分大小写的名称。

  • git push发送提交

从这个意义上说,Git 完全有能力用新提交Y中的新小写名称替换提交X中的所有仅大写名称,同时保持每个文件的所有内容相同。也就是说,在提交X中,您会找到 file ,而在提交Y中, file将与之前的文件是“相同的文件”,除了它的名称现在全小写而不是全大写这一事实。X:PATH/TO/FOO.JPGY:path/to/foo.jpg

请注意,提交中的文件具有长路径,其中似乎包含文件夹名称。就 Git 而言,它们仍然只是具有这些长路径的文件。事实上,您的计算机需要先创建一个名为的文件夹path,然后再创建一个path名为的文件夹to,这样它就可以在其中有一个名为的文件foo.jpg,您可以访问它path/to/foo.jpg......好吧,那是您的计算机的问题;Git 会尽力去适应它。

这也是名称大小写问题出现的地方。您的计算机坚持命名的文件夹PATH和命名的文件夹path同一个文件夹。两者都不会!如果您尝试在名为 的文件夹中创建一个名为 的新文件topath,并且该文件夹PATH存在,则您的计算机坚持将该文件夹to放入名为 的文件夹PATH中。更糟糕的是,如果名为 的文件夹TO存在于名为 的文件夹中PATH,您的计算机会坚持使用该文件夹,而不是创建一个新文件夹。

如果这些都不妨碍,您的计算机将继续创建path,然后创建path/to. 因此,您拥有的一个选项1删除 中的所有内容PATH/TO,完全删除该文件夹TO,然后删除其中的所有内容PATH并完全删除该文件夹PATH。现在 Git 可以创建pathpath/to.

无论path/toor PATH/toor path/TOor pAtH/tOor 发生什么,现在假设 Git 想要创建或修改foo.jpg此文件夹中命名的文件。如果没有具有该名称的文件,您的计算机很乐意创建一个新文件并保留全小写的名称,这样您就可以foo.jpg在那里结束。但是,如果已经有一个名为 的文件FOO.JPG,那么任何创建新文件foo.jpg并对其进行写入的尝试都只会写入现有的FOO.JPG,它会保留其大写的名称。

换句话说,这不是Git 的问题。这是你电脑的问题。当然,Git 正在您的计算机上运行,​​这使它成为您和 Git 需要处理的问题。但重要的是要了解这里到底出了什么问题:是你的计算机,而不是 Git,对你这样做。如果我们让你的 Mac 停止对你这样做,问题就会消失:文件名大小写突然变得重要,Git 认为事情应该是这样,其他一切都正常工作。


1显然,您还有其他选择:例如,您可以重命名PATHI_LIKE_YELLING_PATH,它会保留所有现有文件。最终,您可以将其重命名,或将文件移出,或其他任何方式。


修复它的最简单方法是使用不折叠大小写的文件系统

在 Mac 上,您可以启动运行 Linux 的 VM(例如,参见https://apple.stackexchange.com/questions/264527/linux-vm-installation-on-macbook-pro-with-macos-sierra-10 -12,这是旧的但可能仍然有效;我有一个带有 VirtualBox 的 Linux VM,我在这台特定的笔记本电脑上用于各种事情)。默认的 Linux 文件系统不认为这README是同一个文件ReadMe,并且会让您将两个文件都放入文件系统中。Git 在这里工作得非常好,这可能并不奇怪。

(据我了解,VM 也可以在 Windows 上运行良好,并且可能是最简单的方法。不过,我不“做”Windows。)

您还可以制作非大小写折叠文件系统。我不建议将您的主文件系统重新格式化为区分大小写(请参阅https://superuser.com/questions/203896/case-sensitive-folder-names-in-os-x),但您可以制作可挂载的图像,或者使用 U 盘。例如,使用磁盘工具创建一个新的空白图像。将其命名为 -这case-sensitive将是.dmg文件的名称 - 并将其放置在您可以轻松访问的地方,例如,DesktopDownloads. 让它足够大,例如,1 GB 应该足够了。对于Format,选择区分大小写的文件系统,例如Mac OS Extended (Case-sensitive, Journaled)

使区分大​​小写的日志 fs

也更改Name字段,就在上方Size(我在制作屏幕截图时忘记了这样做)。也就是说,Save As应该是.dmg文件的易记名称,并且Name应该是您希望磁盘在/Volumes挂载时出现的位置。单击Save并完成后,单击Done按钮以关闭弹出窗口。

您现在可以随时挂载此文件系统(磁盘工具现在已经完成;稍后,只需双击该.dmg文件)并cd /Volumes/case-sensitive在终端窗口或选项卡中使用。在这里,您可以克隆和使用区分大小写的存储库,而不必担心大小写。

现在您有了一个区分大小写的本地文件系统,克隆您的存储库并重命名您的文件

cd /Volumes/case-sensitive
git clone <url>
cd <clone>/<path>

您现在已准备好重命名。有很多方法可以做到这一点。有关示例 bash 脚本,请参阅VonC 的答案。这是一个/bin/sh适用于 MacOS 的 shell 片段:

for name in *.JPG; do
    lc=$(echo $name | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')
    echo git mv $name $lc
done

运行一次以确保您喜欢该产品,然后再次echo删除,以便它实际发出git mv命令。

我自己的首选方法是将文件名转储到/tmp文件中:

ls *.JPG > /tmp/x      # note: ls, not echo, to get one per line

然后将/tmp文件编辑成正确的一系列命令,在vim

vim /tmp/x
:%s/.*/git mv & \L&/

一旦结果看起来正确,我就写出临时文件并退出(ZZ:x)然后执行它。完成后将其删除:

sh /tmp/x
rm /tmp/x

您现在已准备好进行所需的任何其他更改git commit,并且git push/Volumes/case-sensitive.

(一旦你完成了区分大小写的文件系统.dmg文件,你可以像处理任何.dmg文件一样弹出和删除它。如果它不占用太多空间,你也可以随意保留它.)


推荐阅读