执行git子树拆分时请遵循重命名

el_*_*one 18 git git-subtree

我有许多子目录,我想把它们分成一个单独的仓库.为了使用单个命令提取它们,我将它们移动(重命名)到根目录内的单个子目录.

然后我跑: git subtree split -P my_new_subdir -b newbranch

如果我然后签出这个新分支并运行git log --follow someoldfile它只显示有关移动到临时子目录的日志条目.我想继续这些文件的完整历史记录.

有没有办法保存完整的历史记录,包括在进行子树分割时重命名?是否有另一种方法可以达到预期的效果?

我曾考虑在repo的克隆上使用filter-branch,但我知道这将非常慢.

cie*_*awy 10

实际上这是可能的,这个问题已在这里提出几次,虽然没有通用的方法,看起来你必须撰写自己的食谱.

如果您只想离开文件,my_new_subdir您需要自己删除所有其他文件.这个概念是用来:

git filter-branch --tag-name-filter cat --index-filter \
  'git rm -r --cached --ignore-unmatch 
    unneeded-subdir-1 unneeded-pattern-* unneeded-etc' \
--prune-empty -f -- --all
Run Code Online (Sandbox Code Playgroud)

然后,为了帮助找到其他什么必须删除你可以使用像:

git log --name-status --all  | grep -P '^\w\s+[\S]+$'
Run Code Online (Sandbox Code Playgroud)

甚至例如:

git log --name-status --all  | grep -P '^\w\s+[\S]+$' | \
  sed s/^.// | cut -f 1-2 -d '/' | sort -u
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以随时找到存储在仓库中的所有文件/目录(或者只是前两个路径段).之后,您可以使用以下命令清理repo:

git gc --aggressive
Run Code Online (Sandbox Code Playgroud)

因此,在移动文件后,my_new_subdir我已经使用了上述命令的组合来清理历史记录中任何不需要的文件.但是我仍然在历史中发现了不相关的合并,但最后我对结果感到满意.请注意,上面有一些git命令的参数对于遍历所有历史记录,分支和标记至关重要.

为了加快速度,您可以在第一次迭代中识别要删除的repo的最大部分,然后执行git gc --aggressive.拥有i5 CPU和SSD磁盘我花了大约一分钟来完成一次git filter-branch迭代,并且已经处理了大约1000个历史条目.