如何更改已提交的多个文件名称的大小写? [英] How do I change case of the names of multiple files, already committed?

查看:49
本文介绍了如何更改已提交的多个文件名称的大小写?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

如果我使用小写图像推送代码,Git会忽略大小写.
有什么具体的命令可以解决吗?

操作系统:MAC

解决方案

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

这实际上不是真的.

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

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

  • 提交 do 存储文件,但以与计算机正常运行相同的方式提交.提交中存储的文件始终具有区分大小写的名称.

  • git push 发送 commits .

从这个意义上讲,Git完全能够用新提交 Y 中新的仅小写名称替换提交 X 中的所有仅大写字母名称,同时保留所有每个文件的内容相同.也就是说,在提交 X 中,您将找到文件 X :PATH/TO/FOO.JPG ,在提交 Y ,文件 Y :path/to/foo.jpg 与以前的文件是同一文件",但其名称现在位于全部小写而不是全部大写.

请注意,提交中的文件具有很长的路径,其中似乎包含文件夹名称.就Git而言,它们仍然只是具有这些长路径的文件.您的计算机要求首先创建一个名为 path 文件夹,然后在 path 中创建另一个名为 to ,这样它就可以在其中有一个名为 foo.jpg 的文件,您可以通过 path/to/foo.jpg 进行访问.好吧,这就是您的计算机的问题;Git将尽最大努力适应它.

这也是名称框问题的发源地.您的计算机坚持认为,名为 PATH 的文件夹和名为 path 的文件夹是相同的文件夹.两者兼而有之!如果您尝试在名为 path 的文件夹中创建名为 to 的新文件夹,并且存在名为 PATH 的文件夹,则您的计算机坚持将名为 to 的文件夹放入名为 PATH 的文件夹中.更糟糕的是,如果名为 TO 的文件夹存在于名为 PATH 的文件夹中,则您的计算机坚持使用该文件夹,而不是创建一个新文件夹./p>

如果这两种方式都没有,则您的计算机将继续创建 path ,然后创建 path/to .因此,您有一个 1 选项是删除 PATH/TO 中的所有内容,完全删除文件夹 TO ,然后然后删除 PATH 中的所有内容,然后完全删除文件夹 PATH .现在,Git可以创建 path path/to .

path/to PATH/to path/TO pAtH/tO 发生的一切code>或其他任何内容,现在假设Git想要在此文件夹中创建或修改名为 foo.jpg 的文件.如果没有使用该名称的文件,则您的计算机很乐意创建一个新文件并保留全小写的名称,以便最后在其中使用 foo.jpg .但是,如果已经有一个名为 FOO.JPG 的文件,则任何尝试创建新的 foo.jpg 并将其写入的尝试都只会写入现有的 FOO.JPG,保留其大写的大写名称.

换句话说,这不是 Git的问题.这是您计算机的问题.当然,Git在您的计算机上运行,​​这使其成为您和Git所要解决的问题.但是重要的是要了解这里到底出了什么问题:这是您的计算机,而不是Git对您执行此操作.如果我们让您的Mac停止对您执行此操作,则问题将消失:文件名突然出现问题,Git认为事情应该以这种方式进行,而其他一切都将正常工作.


1 很显然,您还有其他选择:例如,您可以将 PATH 重命名为 I_LIKE_YELLING_PATH ,这将保留您所有现有的文件.最终,您可以将其重命名,或将文件移出其中,等等.


最简单的解决方法是使用不折叠大小写的文件系统

在Mac上,您可以启动运行Linux的VM(例如,参见

也更改 Name 字段,就在 Size 上方(我在截屏时忘记了这样做).也就是说,另存为应该是 .dmg 文件的一个令人难忘的名称,而 Name 应该是您希望磁盘显示的位置每次安装时都在/Volumes 中.点击保存,完成后,点击 Done 按钮关闭弹出窗口.

您现在可以随时挂载此文件系统(Disk Utility目前已经完成;以后,只需双击 .dmg 文件)并使用 cd/Volumes/case终端窗口或标签中的敏感" .在这里,您可以克隆并使用区分大小写的存储库,而不必担心大小写.

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

  cd/卷/区分大小写git clone< url>cd< clone>/< path> 

您现在可以重命名了.有很多方法可以做到这一点.请参阅 VonC的答案以获取bash脚本示例.这是在MacOS上运行的/bin/sh shell片段:

 ,用于* .JPG中的名称;做lc = $(echo $ name | sed'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')回声git mv $ name $ lc完毕 

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

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

  ls * .JPG>/tmp/x#注意:ls(不是回声),每行获取一个 

然后在 vim 中将/tmp 文件适当地编辑为正确的一系列命令:

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

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

  sh/tmp/xrm/tmp/x 

您现在可以在此区分大小写的文件系统中的此区分大小写的目录中,以 git commit git push 进行其他任何所需的更改,以>/卷/区分大小写.

(一旦完成了区分大小写的文件系统 .dmg 文件,就可以像删除任何 .dmg 一样将其弹出并删除.文件.如果没有占用太多空间,您也可以保留它的时间.)

I want to rename all 500 images which I had uploaded on Git to lowercase.

Git ignores the casing if I push the code with lowercase images.
Is there any specific command to fix it?

OS: MAC

解决方案

Git ignores the casing if I push the code with lowercase images ...

This is not actually true.

To understand the problem properly, you need to know the following things:

  • Git doesn't store files, but rather commits.

  • Commits do store files, but not in the same way your computer does normally. The files stored inside commits have case-sensitive names, always.

  • git push sends commits.

In this sense, Git is perfectly capable of replacing all the uppercase-only names in commit X with new lowercase-only names in new commit Y, while keeping all the content of each file the same. That is, in commit X, you would find file X:PATH/TO/FOO.JPG, and in commit Y, file Y:path/to/foo.jpg would be "the same file" as the earlier one, except for the fact that its name is now in all lowercase instead of all uppercase.

Note that files inside commits have long paths that appear to have folder names in them. As far as Git is concerned, they're still just files with these long paths. The fact that your computer requires that something first create a folder named path, then another one in path named to, so that it can have a file in there named foo.jpg that you'll access as path/to/foo.jpg ... well, that's your computer's problem; Git will do its best to adapt to it.

This is where the name-casing issue comes in as well. Your computer insists that the folder named PATH and the folder named path are the same folder. It won't make both! If you try to create a new folder named to in the folder named path, and the folder named PATH exists, your computer insists on putting the folder named to into the folder named PATH. Worse, if the folder named TO exists in the folder named PATH, your computer insists on using that, instead of creating a new one.

If neither of these are already in the way, your computer will go ahead and create path, and then path/to. So one option you have1 is to remove everything in PATH/TO, remove the folder TO entirely, and then remove everything in PATH and remove the folder PATH entirely. Now Git can create path and path/to.

Whatever may be going on with path/to or PATH/to or path/TO or pAtH/tO or whatever, now suppose that Git wants to create or modify the file named foo.jpg within this folder. If there is no file with that name, your computer is happy to create a new one and preserve the all-lowercase name, so that you wind up with foo.jpg in there. But if there is already a file named FOO.JPG, any attempt to create a new foo.jpg and write to it just writes to the existing FOO.JPG, which retains its shouty uppercase name.

In other words, this is not Git's problem. This is your computer's problem. Of course, Git is running on your computer, which makes it your—and Git's—problem to deal with. But it's important to understand what precisely is at fault here: it's your computer, not Git, doing this to you. If we make your Mac stop doing this to you, the problems vanish: file name case suddenly matters, the way Git thinks things should be, and everything else just works.


1Obviously, you have other options as well: you could just rename PATH to I_LIKE_YELLING_PATH, for instance, which retains all your existing files. Eventually you can rename it back, or move files out of it, or whatever.


The easiest way to fix it is to use a file system that does not fold case

On a Mac, you could spin up a VM running Linux (see, e.g., https://apple.stackexchange.com/questions/264527/linux-vm-installation-on-macbook-pro-with-macos-sierra-10-12, which is old but probably still works; I have a Linux VM with VirtualBox that I use for all kinds of things on this particular laptop). The default Linux file systems don't think that README is the same file as ReadMe, and will let you put both files into the file system. Git works really well here, which is probably not surprising.

(As I understand it, VMs work well on Windows too, and are probably the easiest way to go there. I don't "do" Windows, though.)

You can also make a non-case-folding file system. I do not recommend reformatting your main file system as case sensitive (see https://superuser.com/questions/203896/case-sensitive-folder-names-in-os-x), but you can make a mountable image, or use a USB stick. For instance, using the Disk Utility, create a new blank image. Name it something like case-sensitive—this will be the name for the .dmg file—and place it somewhere you can reach easily, e.g., Desktop or Downloads. Make it big enough, e.g., 1 GB should be plenty. For the Format, select a case sensitive file system such as Mac OS Extended (Case-sensitive, Journaled):

Change the Name field too, just above the Size (I had forgotten to do this at the point I made the screenshot). That is, the Save As should be a memorable name for the .dmg file, and Name should be where you want the disk to show up in /Volumes whenever you mount it. Click Save and once it's done, click the Done button to dismiss the popup.

You can now mount this file system any time (Disk Utility has already done it for right now; later, just double click the .dmg file) and use cd /Volumes/case-sensitive in a Terminal window or tab. Here you can clone and work with case-sensitive repositories, and not have to worry about case.

Now that you have a case-sensitive local file system, clone your repository and rename your files

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

You're now ready for renaming. There are lots of ways to do this. See VonC's answer for a sample bash script. Here is a /bin/sh shell fragment that works on MacOS:

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

Run this once to make sure you like the product, then again with the echo removed so that it actually issues git mv commands.

My own preferred method is to dump the file names into a /tmp file:

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

then to edit the /tmp file in place into the right series of commands, in vim:

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

Once the result looks right, I write out the temp file and exit (ZZ or :x) and then execute it. Remove it when done:

sh /tmp/x
rm /tmp/x

You are now ready to make any other changes needed, git commit, and git push from this case-sensitive directory within this case-sensitive file system in /Volumes/case-sensitive.

(Once you're done with the case-sensitive-file-system .dmg file, you can eject and delete it, as you would with any .dmg file. You can also keep it as long as you like, if it's not using up too much space.)

这篇关于如何更改已提交的多个文件名称的大小写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆