Git:Subtree合并为一个深层嵌套的子目录?

时间:2011-05-05 21:23:26

标签: git git-merge

我正在尝试使用git的子树合并策略,其中我要合并的子目录嵌套得相当深 - 目前有四个级别。

我按照指示here将模块存储库添加为远程运行git read-tree,以将远程代码放入我本地存储库的子目录中,然后提交这些更改。

当我尝试将更改从远程转移到主项目的主分支时,我的问题出现了。上面的页面中的步骤5建议使用-s子树切换进行git pull。当我的子目录是一个,两个或三个级别深,但不是四个时,这对我来说正常。

这是将2级深度合并到子目录中的结果。您可以看到sites / all /中的README文件已正确更新。在我的远程仓库中,README位于根目录中。

$ git pull -s subtree REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Merge made by subtree.
 sites/all/README |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

这里的子目录是3级深度:sites / all / modules /。这也很好,拉动更改并更新文件。

$ git pull -s subtree REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Merge made by subtree.
 sites/all/modules/README |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

但现在我的代码位于4级深度的子​​目录中:sites / all / modules / my_module /。 Git似乎从REMOTE_REPO中提取了更改,但它没有更新文件,而是告诉我它已经是最新的。

$ git pull -s subtree REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Already up-to-date!
Merge made by subtree.

如果我马上再次运行它,它不会拉动更改或更新文件。

$ git pull -s subtree REMOTE_REPO master
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Already up-to-date.

此时查看git日志将显示远程仓库和合并的更改,但我的结帐中的文件尚未更新。

这是一个错误,还是我做错了什么?

更新:Chris Johnsen提供了以下选项,会引发错误:

$ git pull -X subtree=sites/all/modules/my_module/ REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /Users/jeff/work/checkouts/compass_suite
 * branch            master     -> FETCH_HEAD
fatal: entry  not found in tree 173d4f16af4d2d61ae5c4b3446c392e8b49cc57d

2 个答案:

答案 0 :(得分:54)

澄清未来的读者,解决方案在Chris Johnsen的回应中。如果您看到“致命:在树中找不到条目”错误,请删除子树前缀末尾的尾部斜杠。

例如,如果您尝试使用

之类的命令拉出GitHub Pages子树
git subtree --prefix gh-pages/ pull origin gh-pages

并且存在冲突,您将收到类似

的错误
 * branch            gh-pages   -> FETCH_HEAD
fatal: entry  not found in tree 6e69aa201cad3e5888f1d12af0d910f8a10a8ec3

只需从 gh-pages 目录

中删除尾部斜杠即可
git subtree --prefix gh-pages pull origin gh-pages

这将有效,并将尝试合并。您可以获得的最糟糕的情况是自动合并失败并且您收到类似

的错误
Automatic merge failed; fix conflicts and then commit the result.

但你只需手动解决冲突就可以了。

答案 1 :(得分:10)

subtree合并策略人为地限制了搜索子树“适合”整个树的位置的深度。不幸的是,这个限制是硬编码的(参见match-trees.c:267)。

幸运的是,Git 1.7.0将subtree=…选项添加到(默认)recursive合并策略中。此选项允许您准确指定前缀,以便Git不必猜测(同样多)。

使用Git 1.7.0或更高版本,试试这个:

git pull -X subtree=sites/all/modules/my_module REMOTE_REPO master