gpt4 book ai didi

git - 如何重命名大量文件

转载 作者:太空狗 更新时间:2023-10-29 12:50:29 27 4
gpt4 key购买 nike

我有一个包含这样的文件的目录

a.JPG
b.JPG
c.JPG

我想执行这样的事情
git mv a.JPG a.jpg

我尝试使用xargs和其他工具,但似乎没有任何效果。

最佳答案

解决方案的核心将是使用一种工具/方法,该工具/方法将自动进行批量重命名。您可以将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,破折号

下面使用的 -ef与POSIX不兼容。同样,虽然在POSIX中指定了 -e,但它不是纯伯恩兼容的。虽然它们都得到了广泛的支持。
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 add)可以仅用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"

或使用git 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/zmv

这需要zmv和git mv的 -f
zsh -c 'autoload zmv && $0 $@' zmv -fp git -o 'mv -f' '(*).JPG' '$1 x.jpg'

现在,您已经在Git的索引中将它们全部重命名和更新了,您可以提交它们了。

但是其他使用区分大小写的文件系统的Git用户是否可以将它们 check out ?

git checkout仅重命名后

如果您的历史记录还有其他用户,他们可能仍将拥有 JPG文件,并且当他们最终用 jpg文件 checkout (其后代)您的提交时。他们会发生什么?

无论发生什么情况,都不需要“重命名为temp,提交,重命名为final,提交”。 git checkout在提交之间移动时不按顺序应用提交。它实际上是通过将索引和工作树从HEAD“merge ”到新提交而真正起作用的。这实际上意味着它直接“跳转”到新提交,同时拖动HEAD与索引/工作树之间的无冲突更改。

在内部,Git View 将重命名为删除和添加。我没有找到任何文档来描述有关删除和添加顺序的git checkout行为,因此我查看了源代码。 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

文件上的git怪似乎表明可能是提交: Make unpack-tree update removed files before any updated files,它首先在Git 1.5.6-rc0(2008-06-18)中发布。因此,尽管未记录(?),但此行为是为支持不区分大小写的文件系统而专门实现的。

谢谢,莱纳斯!

关于git - 如何重命名大量文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2981208/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com