回答
解决方案的核心将是使用一种工具/方法来自动执行批量重命名。您可以使用mv结合git add或只是git mv。无论哪种情况,如果您使用的是不区分大小写的文件系统,则可能需要采取额外的步骤。因此,在我们处理批量重命名之前,讨论如何处理案例可能会有所帮助。
大小写敏感性
有些系统(或系统+文件系统组合般在Mac OS X *的HFS +文件系统的默认变体)的情况下保留,但不区分大小写。在这样的系统中,在进行只涉及更改名称大小写的重命名时,您可能需要小心。通常的解决方法是使用一个临时名称,这个名称在两个名称之间的“桥梁”之间的差异不仅仅是大小写(例如mv foo.JPG tmp && mv tmp foo.jpg
)。
*可以在Mac OS X上使用区分大小写的文件系统(包括HFS +的敏感变体 )。
从这里开始,我将假设一个不区分大小写的文件系统。
在Mac OS X上的mv命令可以在单个步骤中处理仅更换情况的重命名。如果与-i
选项一起运行,它将提供“覆盖?”提示,如果给出-n
选项,它将跳过重命名。它只能通过“类似Unix系统的许多部分”的“足够的绳索来挂断你自己”的默认操作而获得成功。
该git mv命令是有点偏执的情况。它拒绝操作(“目标存在”错误),除非给出-f
/--force
选项。
# this will succeed, though it may fail/prompt if mv is aliased to use -n/-i
mv foo.JPG foo.jpg
# this will succeed
mv -f bar.JPG bar.jpg
# this will succeed but give a warning
git mv -f quux.JPG quux.jpg
批量重命名选项
Perl的重命名
所需的操作是很简单的一个位shell脚本做,但你可以得到的Perl 重命名实用程序(一个乔丹·刘易斯提及)如果你需要做一些更复杂的事情。您可以尝试rename from Debian's perl package,或者如果您觉得需要使用CPAN,则可以安装File::Rename,其中包括重命名程序。
ksh的,的bash,的zsh,破折号
下面使用不兼容POSIX的-ef
。同样,虽然在POSIX中指定-e
,但它不是纯Bourne兼容的。但他们都得到了广泛的支持。
for f in *.JPG; do
ff="${f%.JPG}.jpg"
test -e "$f" || continue # possible when not using nullglob
test "$f" != "$ff" || continue # possible when using nocaseglob
if test -e "$ff" &&
! test "$f" -ef "$ff"; then # possible on a case sensitive filesystem
echo "skipping <$f>: destination <$ff> exists and is distinct" 1>&2
continue
fi
# "mv" with "git rm" and "git add"
mv -f "$f" "$ff" &&
git rm --cached "$f" &&
git add "$ff"
done
最后一节(MV,git的RM,git的添加)可能只有混帐MV更换:
# "git mv"
git mv -f "$f" "$ff"
如果你非常关心如何重命名可能会在不区分大小写的系统上失败,那么您可以使用临时名称:
# temp-based "mv" with "git rm" and "git add"
t="$ff.tmp"; while test -e "$t"; do t="$t.tmp"; done
mv -n "$f" "$t" &&
mv -n "$t" "$ff" &&
git rm --cached "$f" &&
git add "$ff"
或用混帐MV:
# temp-based "git mv"
t="$ff.tmp"; while test -e "$t"; do t="$t.tmp"; done
git mv "$f" "$t" &&
git mv "$t" "$ff"
的zsh /&#xfeff; zmv
这其中需要-f
两个zmv和混帐MV。
zsh -c 'autoload zmv && $0 [email protected]' zmv -fp git -o 'mv -f' '(*).JPG' '$1 x.jpg'
现在,你把它们都改名和Git的索引更新,你可以提交他们。
但是会使用区分大小写的文件系统的其他Git用户能够检查它们吗?
git的结帐后为例,仅重命名
如果有你的历史的其他用户,他们可能会仍然有JPG
文件,当他们最终结账(的后代),您与jpg
提交文件。他们会发生什么?
无论发生什么事情,都不需要“重命名为temp,提交,重命名为final,commit”。git checkout在提交之间移动时不按顺序应用提交。它通过将来自HEAD的索引和工作树“合并”到新提交而起作用。这实际上意味着它在“HEAD”和索引/工作树之间发现的非冲突性变化时直接“跳转”到新提交。
在内部,Git视图重命名为删除和添加。我没有发现任何描述git结账关于删除和添加顺序的行为的文档,所以我查看了源代码。 git checkout在任何更新/添加(cmd_checkout - > switch_branches - > merge_working_tree( - > reset_tree) - > unpack_trees - >check_updates)之前处理所有删除。
您可以测试了这一点后,就在您的命名承诺:
git checkout HEAD~ # note: detached HEAD
# verify that the original names are back in place
git checkout - # back to your branch
# verify that the new names are in place again
的混帐怪上的文件似乎表明一个可能犯:Make unpack-tree update removed files before any updated files,这是首次在Git的发布1.5.6-RC0 (2008-06-18)。所以,尽管没有记录(?),但这种行为是专门为支持不区分大小写的文件系统而实现的。
谢谢,Linus!
可能重命名为* .somethingelse,然后重命名回* .JPG
使用标准的Linux rename(1) utility.一旦你重命名的文件,git的添加。
您是否可以更改文件的大小取决于您的文件系统。即使它在你的文件系统上工作,你也可能会导致其他人更新的问题。你最好重新命名它们,提交它们,然后重新命名它们。使用以下bash脚本将所有内容更改为* .tmp:
for i in *.JPG; do mv $i ${i%.JPG}.tmp; done
然后将它们全部移入git中。你可以使用类似的命令,但我建议检查guess-renames这将有助于此举。
然后使用类似的过程将它们全部重命名为* .jpg。
我认为我会推荐'* .JPG'作为'\'ls \'' – Dustin 2010-06-05 20:00:11
好建议,我更新了使用* .JPG的答案。 – wbyoung 2010-06-05 20:07:33
在提交之间移动时,Git不会重播每个中间变更集。移至新提交会更新当前HEAD /索引与目标提交之间已更改的文件。在多个阶段提交重命名将无助于那些不能直接处理'mv foo.JPG foo.jpg'的机器的用户(除非他们在移动到“on”提交时手动“访问”“.tmp”提交重命名的另一面“)。 * git不需要* guess-renames *,'git add -u && git add
- 1. 重命名大量的文件
- 2. 大规模批量重命名文件
- 3. 重命名大文件
- 4. 如何用循环重命名大量文件?
- 5. 如何创建批文件以重命名文件夹中的大量文件?
- 6. 批量重命名文件
- 7. 重命名批量文件
- 8. 批量重命名文件
- 9. 如何重命名文件?
- 10. 如何重命名文件?
- 11. PowerShell命令批量重命名文件
- 12. 大量扫描和重命名文件名
- 13. 批量重命名文件扩展名
- 14. Windows批量重命名文本文件
- 15. 批量如何重命名保存到变量中的文件?
- 16. 大会文件重命名和Assembly.LoadFile
- 17. python文件被重命名,如何获得'重命名时间'
- 18. 如何根据现有文件名重命名文件名
- 19. 寻找一次重命名大量文件的方法
- 20. 根据模式在Linux中重命名大量文件
- 21. git冲突重命名/大量文件更改
- 22. 使用Bash批量重命名文件
- 23. 日期批量重命名文件
- 24. 文件重命名后的变量
- 25. 批量压缩和重命名文件
- 26. 批量重命名文件夹
- 27. 在Bash中批量重命名文件
- 28. 在Python 2.7批量重命名文件
- 29. 如何一次重命名大量的.asc文件?使用MS Office或Matlab
- 30. 重命名文件
您在下面的评论中提到您使用OS X.这意味着您(可能)正在使用保留大小写的不区分大小写的文件系统。因此,重命名中的问题是:你的文件系统将目标名称视为与目标名称相同,并且由于Git通过文件系统工作,所以它也具有打开外壳的功能。 wbyoung下面的方法将通过将文件传递给可识别的中间名称来解决问题。 – Jeet 2010-06-06 05:29:29
注意:git 2.0.1解决了这个问题:http://stackoverflow.com/a/24979063/6309 – VonC 2014-07-27 08:06:44