git - git-subtree 添加后如何 rebase ?

标签 git git-rebase git-subtree

我正在尝试学习新的 git-subtree在 Git 1.7.11 中添加的命令。添加子树后,我似乎失去了 rebase 的能力。我有一个带有 README 文件的主存储库和一个也有一个 README 文件的库存储库。我使用 subtree add 将它添加到 lib 目录:

$ git subtree add -P lib/mylib myliborigin master

这工作正常,但现在历史看起来像这样:

*   22c1fe6 (HEAD, master) Merge commit 'b6e698d9f4985825efa06dfdd7bba8d2930cd40e' as 'lib/mylib' - 
|\                                                                                                                
| * b6e698d Squashed 'lib/mylib/' content from commit d7dbd3d
* b99d55b Add readme
* 020e372 Initial

现在,当我想根据 origin/master 重新设置我的 repo 时,它失败了,因为 squash 提交直接应用于它的父提交,而父提交不适用,因为它应用于repo 而不是我在添加子树时给它的前缀。

如果我查看 squash 提交,原因就很清楚了。没有关于前缀的信息。它只是压缩在一起的原始 mylib 提交。只有下一次 merge 提交才知道它,但 rebase 在这里不考虑它。

是否有任何解决方法(除了永远不会对子树提交进行 rebase )?

最佳答案

这适用于简单的情况:

git rebase --preserve-merges master

感谢@Techlive Zheng 的评论。


你可能会看到

fatal: refusing to merge unrelated histories
Error redoing merge a95986e...

这意味着 git 未能自动应用您的子树。这使您处于@ericpeters 在他的回答中描述的情况。解决方案:

重新添加您的子树(使用您最初使用的相同命令):

git subtree add -P lib lib-origin master

继续 rebase :

git rebase --continue

一切就绪!


如果您想知道它是否成功运行,您可以在 rebase 后与您的原始版本进行比较,以确保您没有进行任何更改:

git diff <ref-before-rebase> <ref-after-rebase> -- .

(末尾的 -- . 指示 git 仅diff 当前目录中的文件)。


如果所有其他方法都失败并且您不关心保留提交本身,您可以简单地 git cherry-pick 原始子树提交。

提交消息看起来像 Add 'lib/' from commit '9767e6...' —— 这就是您想要的。

关于git - git-subtree 添加后如何 rebase ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12858199/

相关文章:

git - 如何获取整个git历史记录中每个文件的大小?

git - 如果依赖项尝试从 Internet 下载,如何配置代理?

git - 压缩第一次和第三次提交(不压缩第二次)

git - 比较 Git 中 rebase 的差异

git - 如何重写 git 历史以匹配流行的 git 工作流程

git - 如何将一个 git 仓库中的目录镜像到另一个 git 仓库中?

git - 如何从远程分支 pull 更新

git:如何在 merge 时覆盖所有本地更改?

git - 如何使用 git subtree 包含另一个 git 存储库的一部分并在两个方向上 merge 更新

git - 将许多子目录拆分为一个新的、独立的 Git 存储库