7

我实际上有两个存储库:

  • main
  • external

一段时间后,main存储库被合并到external/main目录中(作为子树)。现在我想将所做的更改迁移external/mainmain存储库,但只有这些提交,没有其他不相关的提交喜欢external/<anything-else>.

我实际上已经尝试过经典:

git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter main -- --all

但这也会删除对初始main存储库所做的所有提交,只留下在externalgit 存储库中所做的提交。


所以:如何只保留提交:

a) 制作到初始main存储库

b) 生成external( external/main)的子树


当我尝试git pull -s subtree ../external时,所有提交都被合并,包括未更改子树中任何内容的提交。我只想拥有在子树中实际更改某些内容的提交,并且也只有有关子树中文件的信息。

4

2 回答 2

2

您应该能够通过在命令部分中filter-branch使用来限制重写的提交:--not --remotes<rev-list options>

git filter-branch --tag-name-filter cat --prune-empty
    --subdirectory-filter main -- --all --not --remotes

这将导致filter-branch不包括可从远程分支访问的提交。如果您有多个遥控器,您可以使用类似的东西--remotes=origin来指定要考虑的遥控器。

于 2014-01-22T20:00:19.290 回答
1

为了将main发生在两件事中的所有相关变化带入external需要发生的事情:

  • 隔离原件main
  • main发生在external

首先,隔离原始main

似乎您可能main在自己的存储库中。

external如果不是,只要将原始main提交设置为创建external/main子目录的提交的父级,就可以从存储库中检索它。一个例子是Git Book Subtree Merging 页面中概述的过程

提交可以找到引入的子树,如this answer中所述。

然后只需抓住作为基础的整个提交集main并从中创建一个存储库。


其次,main发生在的所有提交纳入其中external

您已经隔离了包含exteral/main子文件夹中更改的提交,但正如您所说,它不包括原始main提交。

git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter main -- --all

这是因为filter-branch只会检查特定子目录位置中的文件,而不知道如何处理更复杂的操作,例如read-tree创建子目录的操作。

操作后filter-branch,您将留下一组提交,其中包含在main/external. 让我们假设可以在filteredMain分支中访问这组提交。

由于内容已从子目录移动到根目录,因此文件的位置现在再次与main存储库中的内容相同。这将允许连接两棵树。由于这两个树main的主分支并filterBranch没有共同的历史记录,因此可以通过rebase重放提交的更改来加入它们。

# in the main repository

# bring the external repository and get the branch
git remote add external /path/to/external
git fetch external filteredMain
git checkout filteredMain

# We need the first commit of this tree for the rebase command
firstCommit=$(git rev-list --max-parents=0 HEAD)

# run the rebase
git rebase --onto master $firstCommit filteredMain

在此之后,分支应该包含在存储库中的原始分支之上重放的filteredMain所有更改。external/mainmastermain

于 2014-01-24T21:50:47.077 回答