Follow renames when performing git subtree split

你离开我真会死。 提交于 2019-12-31 09:34:06

问题


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.

I then run: git subtree split -P my_new_subdir -b newbranch

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?

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


回答1:


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.

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]+$'

or even eg:

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

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.

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.



来源:https://stackoverflow.com/questions/26304941/follow-renames-when-performing-git-subtree-split

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!