执行git子树拆分时遵循重命名 [英] Follow renames when performing git subtree split

查看:53
本文介绍了执行git子树拆分时遵循重命名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多子目录,我想将它们拉到单独的存储库中.为了使用单个命令提取它们,我将它们移动(重命名)到根目录内的单个子目录中.

I have a number of subdirectories that I want to pull out into a separate repo. In order to extract these with a single command I move (rename) them to a single subdirectory inside the root.

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

如果我随后签出该新分支并运行git log --follow someoldfile,则仅显示与移入临时子目录有关的日志条目.我想保留这些文件的完整历史记录.

If I then checkout this new branch and run git log --follow someoldfile it only shows me the log entries pertaining to the move into the temporary subdirectory. I want to carry over the full history of those files.

是否可以保留完整的历史记录,包括在进行子树拆分时重命名?有没有其他方法可以达到预期的结果?

Is there a way to preserve full history, including renames when doing a subtree split? Is there another means of achieving the desired outcome?

我已经考虑过在仓库的克隆上使用filter-branch,但是我知道这样做会很慢.

I have considered using filter-branch on a clone of the repo but I know that will be very slow.

推荐答案

实际上,虽然没有通用的方法,而且似乎必须自己编写食谱,但实际上已经有几次提出这个问题了.

Actually it is possible and this issue has been raised here few times although there is no universal way and it looks like you have to compose your own recipe.

>

如果只想保留my_new_subdir中的文件,则实际上需要自己删除所有其他文件.该概念是使用:

If you want just to leave files from my_new_subdir you need actually to remove all other files by your own. The concept is to use:

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

然后,为了帮助查找必须删除的其他内容,您可以使用诸如此类的方法:

then to help finding what else have to be deleted you can use sth like:

git log --name-status --all  | grep -P '^\w\s+[\S]+$'

甚至例如:

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

这样,您可以随时查找存储库中存在的所有文件/目录(或者在第二种情况下仅查找路径的前两个段).之后,您可以使用以下命令来清理存储库:

This way you can find all the files/directories (or just first two segments of path in second case) that was present in the repo at anytime. After that you can use following command to clean the repo:

git gc --aggressive

因此,在将文件留到my_new_subdir中之后,我使用了以上命令的组合来从历史记录中清除所有不需要的文件.但是,我仍然在历史中发现无关的合并,但最终我对结果感到满意.请注意,上面有一些git命令的参数,这些参数对于遍历所有历史记录,分支和标签至关重要.

So after moving files to be left into my_new_subdir I've used combination of above commands to clean up any unneeded files from history. However I still found unrelated merges in the history but in the end I was satisfied with the result. Note that above there is number of parameters to git commands that are crucial to walk through all the history, branches and tags.

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

To speedup things you can identify the biggest parts of the repo to remove in first iteration then do the git gc --aggressive. Having i5 CPU and SSD disk it took me about a minute to complete one git filter-branch iteration and about 1000 history entries has been processed.

这篇关于执行git子树拆分时遵循重命名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆