我实际上有两个存储库:
main
external
main
存储库在一段时间后合并到external/main
目录(作为子树)。
现在,我想将对external/main
所做的更改迁移回main
存储库,但仅限于这些提交,而不是external/<anything-else>
之类的其他无关提交。
我实际上尝试过经典:
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter main -- --all
但是它也删除了对初始main
存储库的所有提交,只留下了external
git存储库中的提交。
所以:如何只保留提交:
a)对初始main
存储库
和
b)对external
(external/main
)
当我尝试git pull -s subtree ../external
时,提交都被合并,包括在子树中没有改变任何内容的提交。我想只有实际改变了子树中某些东西的提交,而且还只有关于子树中文件的信息。
答案 0 :(得分: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
的内容来指定要考虑的遥控器。
答案 1 :(得分:1)
为了将main
external
中发生的所有相关变更纳入main
,需要做两件事:
main
external
main
首先,隔离原始main
:
好像你可能在自己的存储库中有external
。
如果不是,只要原始main
提交设置为创建external/main
子目录的提交的父级,就可以从main
存储库中检索它。这方面的一个例子是Git Book Subtree Merging page
提交可以找到引入子树的地方in this answer。
然后,这只是抓住作为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/main
分支应该包含master
在main
存储库中原始{{1}}分支顶部重播的所有更改。