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

Jef*_*eff 19 git git-merge

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

我按照这里的指示将模块存储库添加为远程,运行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(-)
Run Code Online (Sandbox Code Playgroud)

这里的子目录是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(-)
Run Code Online (Sandbox Code Playgroud)

但现在我的代码位于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.
Run Code Online (Sandbox Code Playgroud)

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

$ git pull -s subtree REMOTE_REPO master
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Already up-to-date.
Run Code Online (Sandbox Code Playgroud)

此时查看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
Run Code Online (Sandbox Code Playgroud)

Jac*_*nor 54

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

例如,如果您尝试使用类似命令拉出GitHub Pages子树

git subtree --prefix gh-pages/ pull origin gh-pages
Run Code Online (Sandbox Code Playgroud)

并且有冲突你会得到一个错误

 * branch            gh-pages   -> FETCH_HEAD
fatal: entry  not found in tree 6e69aa201cad3e5888f1d12af0d910f8a10a8ec3
Run Code Online (Sandbox Code Playgroud)

只需从gh-pages目录中删除尾部斜杠即可

git subtree --prefix gh-pages pull origin gh-pages
Run Code Online (Sandbox Code Playgroud)

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

Automatic merge failed; fix conflicts and then commit the result.
Run Code Online (Sandbox Code Playgroud)

但你必须手动解决冲突,你就完成了.

  • +1救生员,同样的问题出现了git子树进行合并和相同的答案. (4认同)
  • 如果我没记错的话,git会在那里做一些错误的路径分裂,并且它决定子树路径的最后一个组件是一个名为""(空字符串)的目录,而不是删除尾部斜杠.如果仔细观察错误,你会在"entry"之后看到一个额外的空格,因为git实际上是在那里打印条目的名称.请参阅http://comments.gmane.org/gmane.comp.version-control.git/209129 (3认同)

Chr*_*sen 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
Run Code Online (Sandbox Code Playgroud)

  • 我应该多加注意.事实证明,尾部斜杠会导致错误.我使用了subtree = sites/all/modules/my_module /而不是subtree = sites/all/modules/my_module.没有尾随斜线,它的工作原理!再次感谢. (30认同)