使用 update-index

问题描述

我一直试图破译 git-filter-branch 命令使用 here 重写索引,以便所有 repo 内容都在一个新目录中,然后用于将其移动到另一个回购。专注于具体命令:

git filter-branch --index-filter '
        git ls-files -s |
        sed "s,\t,&'"$dir"'/," |
        GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
    ' HEAD

这实质上似乎将索引从 /folder1/path/to/file 更改为 'newrootfolder'/folder1/path/to/file

问题:

  • GIT_INDEX_FILE 变量来自哪里,它被设置为什么以及整行如何工作?
  • 如何在存储库中自动创建新文件夹(例如 newrootfolder) - git 是否在内部检测并创建目录?

解决方法

GIT_INDEX_FILErepository environment variables

之一

索引文件的路径(仅限非裸仓库)。

该过滤器命令和示例是 introduced in June 2007,带有 this patch

GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info 

这部分强制 git 重新创建一个新的索引文件,其中包含重命名的文件夹。

mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"

新索引一旦创建,就可以替换旧索引。


请注意当前的选项(在 python 中,所以跨平台)是使用 git filter-repo,它取代了 old obsolete git filter-branch or BFG

git filter-repo --path <olddirectory>/ --path-rename <olddirectory>/:<newdirectory>/

示例:

如果你想重命名两个目录(如果两个目录都重命名到相同的位置,可能会合并),使用 --path-rename;例如,将 cmds/src/scripts/ 重命名为 tools/

git filter-repo --path-rename cmds:tools --path-rename src/scripts/:tools/