简体   繁体   English

Git子树拆分两个目录

[英]Git subtree split two directories

I've been following this excellent answer to extract a subdirectory of my git repository into its own repository, while retaining the complete history.我一直在关注这个优秀的答案,将我的 git 存储库的子目录提取到它自己的存储库中,同时保留完整的历史记录。

My repository looks like:我的存储库看起来像:

src/
    http/
    math/
tests/
    http/
    math/

I want to create a new branch that only contains the src/math and tests/math directories.我想创建一个只包含src/mathtests/math目录的新分支。

If I run the following command:如果我运行以下命令:

git subtree split -P src/math -b math

It creates a branch that contains the contents of the src/math directory, but discards the src/math/ prefix.它创建一个包含src/math目录内容的分支,但丢弃src/math/前缀。

If I try the same command with two directories:如果我对两个目录尝试相同的命令:

git subtree split -P src/math -P tests/math -b math

It only extracts the contents of tests/math , ignoring src/math , and also discarding the tests/math prefix.它只提取tests/math的内容,忽略src/math ,并丢弃tests/math前缀。

To summarize, I would like my final repository to look like:总而言之,我希望我的最终存储库看起来像:

src/
    math/
tests/
    math/

That is, keeping the original directory structure but discarding everything that's not explicitly mentioned in the command-line.也就是说,保留原始目录结构但丢弃命令行中未明确提及的所有内容。

How can I do that?我怎样才能做到这一点?

Depending on your needs you might get away with git filter-branch .根据您的需要,您可能会使用git filter-branch

I'm not entirely sure what you are trying to achieve, but if you merely want to have a repository with two directories removed (in the history?) this is probably your best shot.我不完全确定您要实现什么,但是如果您只想删除两个目录的存储库(历史上?),这可能是您最好的选择。

See also Rewriting Git History .另请参阅重写 Git 历史记录

$ git filter-branch --tree-filter 'rm -rf tests/http src/http' --prune-empty HEAD

This will look into each commit and remove the two directories from this commit.这将查看每个提交并从此提交中删除两个目录。 Be aware that this rewrites history (ie: alters your commit sha) and will cause headaches if you have a common history with another repository.请注意,这会重写历史记录(即:更改您的提交 sha),如果您与另一个存储库有共同的历史记录,则会引起头痛。

Use git-subtree add to split-in使用git-subtree add拆分

# First create two *split-out* branches
cd /repos/repo-to-split
git subtree split --prefix=src/math --branch=math-src
git subtree split --prefix=test/math --branch=math-test

# Now create the new repo
mkdir /repos/math
cd /repos/math
git init

# This approach has a gotcha:
# You must commit something so "revision history begins",
# or `git subtree add` will complain about.
# In this example, an empty `.gitignore` is commited.
touch .gitignore
git add .gitignore
git commit -m "add empty .gitignore to allow using git-subtree"

# Finally, *split-in* the two branches
git subtree add --prefix=src/math ../repo-to-split math-src
git subtree add --prefix=test/math ../repo-to-split math-test

It worked for me with git --version 2.23.0 .它对我有用git --version 2.23.0 Also note that you can setup different prefixes at split-in time, ie add the src/math/ to src/ and test/math/ to test/ .另请注意,您可以在拆分时设置不同的前缀,即将src/ src/math/添加到src/并将test/math/test/

Side note : use git log at the new repo before commiting to a remote, to see if resultant history is ok enought for you.旁注:在提交到远程之前,在新的 repo 中使用git log ,看看结果历史是否适合你。 In my case I have some commits with duplicated messages, because my repo history was so dirty, but it's ok for me.在我的情况下,我有一些带有重复消息的提交,因为我的回购历史很脏,但对我来说没关系。

Source来源

Use git-filter-repo This is not part of git as of version 2.25.使用git-filter-repo从 2.25 版开始,这不是 git 的一部分。 This requires Python3 (>=3.5) and git 2.22.0这需要 Python3 (>=3.5) 和 git 2.22.0

git filter-repo --path src/math --path tests/math 

For my repo that contained ~12000 commits git-filter-branch took more than 24 hours and git-filter-repo took less than a minute.对于包含 ~12000 次提交的存储库, git-filter-branch花费了 24 多个小时,而git-filter-repo花费了不到一分钟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM