【发布时间】:2012-10-10 07:18:54
【问题描述】:
我正在使用 Avery Pennarun 的 git-subtree,它是 git 的扩展。
如何使用 git subtree 从子仓库中挑选提交到我的主仓库中?另外,在我已经对该前缀执行 git subtree pull 之后,如何转到子仓库历史记录中的特定提交?
我主要在 squash 提交模式下运行它。
【问题讨论】:
标签: git cherry-pick git-subtree
我正在使用 Avery Pennarun 的 git-subtree,它是 git 的扩展。
如何使用 git subtree 从子仓库中挑选提交到我的主仓库中?另外,在我已经对该前缀执行 git subtree pull 之后,如何转到子仓库历史记录中的特定提交?
我主要在 squash 提交模式下运行它。
【问题讨论】:
标签: git cherry-pick git-subtree
如何进入子仓库历史中的特定提交?
如果你已经压缩了提交,那么就没有办法了,因为压缩会丢失不同的提交。
否则,使用未压缩的子树,您可以导航到子树的任何提交,其哈希值与创建子树的原始存储库中的哈希值相同。
git subtree(没有 squash)实际上将来自外部存储库的所有相关提交作为当前存储库中的独立树添加到存储库中。当您执行git subtree add 时,您会注意到添加了几个提交(来自外部存储库的所有原始提交)和最后一个合并提交,它将内容从该子树移动到使用--prefix 选项指定的给定目录。简而言之,它会从另一个不相关的存储库中签出一个分支,然后通过将所有内容移动到给定的子文件夹中来将其合并到您当前的分支中。
所有这一切意味着您可以使用外部回购的历史记录,您可以像这样签出它,请记住,作为一个完全不同的树,这个签出可能会修改您工作区的所有内容,在大型项目中可能会很长。
这将我们带到第二个:
如何使用 git subtree 从子存储库中挑选提交到我的主存储库?
似乎git subtree 本身不支持当前的“樱桃采摘”。但是考虑到上述所有的含义,可以做到以下几点。
# move yourself to the subtree commit of your choice
git checkout <subtree-hash>
# fetch commits from the subtree repository, to have available the commit you want
# to cherry pick.
git fetch <path-to-remote>
# cherry pick the hash you want
git cherry-pick <cherry-hash>
# move back to your original branch
git checkout <your-branch>
# subtree merge your cherry pick (using the previous HEAD),
# so that it gets moved to the correct location specified by prefix.
git subtree merge --prefix <subtree-prefix> HEAD@{1}
# Since you probably fetched more commits that you needed from
# the remote, you might want to clean those that where not needed
git gc
考虑到,在这样做之后,如果您尝试将 git subtree pull 更新到您的子树中,并且它包括您选择的提交,那么您将以冲突结束,因为您将在同一个地方进行两次更改。
另一个更简单的选择是,如果您可以访问原始子树存储库,则在一个分支中选择樱桃,然后只需 git subtree pull 那个特定的分支。
【讨论】:
git version 1.8.1 对此进行了调查,其中已经包含 subtree 命令。