如何将 Git 存储库历史记录重播到子目录中?

如何将 Git 存储库历史记录重播到子目录中?

假设我有两个存储库ayebee并且我想摆脱bee,以这样的方式,bee/master在 的新子目录(几层深)中“重播”的线性历史记录aye我只想要文件和提交消息,我不关心提交 ID。想要一个合理的历史,所以git subtree add --prefix=subdirectorygit read-tree --prefix=subdirectory/不是我要找的。

这两个存储库都是私有的,因此不存在为其他人重写历史记录的风险。然而,bee 有一个子模块cee

答案1

第一的,重写bee历史记录以将所有文件移动到子目录中:

cd /path/to/bee
git filter-branch --force --prune-empty --tree-filter '
dir="my fancy/target directory"
if [ ! -e "$dir" ]
then
    mkdir --parents "${dir}"
    git ls-tree --name-only "$GIT_COMMIT" | xargs -I files mv files "$dir"
fi'

git log --stat应该显示出现在my fancy/target directory.现在你可以将历史合并到aye轻松地:

cd /path/to/aye
git remote add -f bee /path/to/bee
git checkout -b bee-master bee/master
git rebase master
git checkout master
git rebase bee-master

在以下位置重新创建子模块aye

git submodule add git://my-submodule 'my fancy/target directory/my-submodule'

最后你可以清理aye

git rm 'my fancy/target directory/.gitmodules'
git branch --delete --force bee-master
git remote remove bee

您可能还需要修复存储库中的任何绝对路径(例如在.gitignore

答案2

更快的版本(帽子提示这个答案):

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

替换newsubdir为您喜欢的任何目录或嵌套目录。在 macOS 上,您可能必须使用gsedsed安装brew install gnu-sed)。

相关内容