重命名 Git 中的文件夹。所有分支和所有修订

Rename folder in Git. All branches and all revisions

我在检查 windows 中的分支时遇到问题。一个文件夹以空 space 结尾,导致 windows 自动 trim 该文件夹,而 git 试图将文件放入原始路径并导致错误。

fatal: cannot create directory at 'raisesoft/61571_delivery /acl': No such file or directory

在 linux 上它工作正常,因为 linux 不会自动 trim 文件夹。

我正在尝试重命名该文件夹。这是我想出的脚本:

git filter-branch --tree-filter '
if [ -d "61571_delivery " ]; then
  mv "61571_delivery " "61571_delivery"
fi' --force HEAD

然而它不起作用。它根本没有重命名文件夹。我不精通 linux bash,所以不胜感激。

谢谢

你基本上是在正确的轨道上。您的树过滤器只是在寻找错误的名称。目录的路径名不是:

"61571_delivery "

(完整的尾部 space 需要引号才能清楚),而是:

"raisesoft/61571_delivery "

因此:

git filter-branch --tree-filter '
if [ -d "61571_delivery " ]; then
  mv "61571_delivery " "61571_delivery"
fi' --force HEAD

应该读作:

git filter-branch --tree-filter '
if [ -d "raisesoft/61571_delivery " ]; then
  mv "raisesoft/61571_delivery " "raisesoft/61571_delivery"
fi' --force HEAD

(一旦您对其进行测试并发现它有效,请切换到 --all 并添加 --tag-name-filter cat 以更改带注释的标签)。

值得注意的是 --tree-filter 非常 慢。在大型存储库上,在旋转媒体(而不是 SSD 或内存文件系统)上执行此操作可能需要几天甚至几周的时间。您可以通过使用内存文件系统大大加快速度,但最大的加速来自使用 --index-filter 而不是 --tree-filter。使用树过滤器,Git 必须将索引中的每个提交提取到常规文件系统树中,运行 您的过滤器,然后将树转换回可用于编写新提交的索引。虽然 git filter-branch 中没有任何部分是 fast,但这是最慢的部分。使用索引过滤器,Git 可以完全跳过此步骤:它只是将提交读入索引,运行 是您的索引过滤器,然后从索引写入一个新的提交。

不幸的是,没有现成的好方法来编写执行此操作的索引过滤器。您基本上希望 hg mv --after 的 Git 等价物仅重命名索引中的文件,但 Git 没有。我写了 a script that does this for one file,但您想对目录中的每个文件都这样做。