17

我使用不带 squash 选项的 git subtree add 将一棵树合并到我的存储库中。git 日志显示提交已成功添加到存储库。但是,如果我执行 a git log --follow filename,历史记录会在合并处停止,并且不会显示以前的提交。我尝试使用-M而不是,--follow但这也不起作用。如何获取合并前特定文件或文件的提交日志?

4

2 回答 2

18

提交由来自子树的文件创建git subtree merge或执行“添加”,而不是“移动”。git subtree add这意味着他们的历史不能像其他合并或移动一样被跟踪。

您仍然可以通过在合并前直接查看子树来显示所需文件的历史记录。如果您的工作区是git subtree创建的合并提交,那么它的第二个父级 ( HEAD^2) 将是原始子树的最后一个提交。从这里你可以看到原始子树的内容:

# Display the contents of the original subtree
git ls-tree HEAD^2

从此提交中,您可以跟踪您感兴趣的文件的更改。请注意,您的文件路径在工作区中的子树中会有所不同。您需要删除--prefix给定的 togit subtree才能获得文件的正确路径。

git log HEAD^2 --follow -- path-in-subtree/file
于 2013-01-21T22:00:22.863 回答
7

实际上,git log --follow 应该与子树合并一起使用,但众所周知它在很长一段时间内都是 hackish [1-3]。

人们可以坚持使用子树合并,并确信该策略对跟踪多个历史记录有效,并耐心等待不可避免的事件git log --follow将得到改善。这实际上可能是一个可行的决定,因为目前git log --follow可以在非常有用的情况下看到一些历史。假设您将文件从顶级存储库移动到子存储库,然后它可以跟踪完整移动。当您想要跟踪特定于子存储库的历史记录时,您确实必须拥有单独的副本或签出子存储库分支。

替代方案和解决方法

您可以获取此类文件的日志 [1]:

git log -- '*filename'          # from the toplevel

这将查看每个涉及名称以 . 结尾的文件的提交filename。它不会跟随实际的重命名,并且如果您有多个具有相同基本名称的文件 [1],则可能会显示误报。

您还可以使用不同的策略合并存储库。参考文献 [4] 展示了一种执行此操作的方法,该方法与常规子树合并的方法非常接近,但具有可追溯的历史记录。基本上,你:

  1. 将每个子存储库添加、获取和合并到顶级存储库,作为常规远程,没有 git 子树或 readtree。起初,这会污染你的根目录,就好像它是他们的一样,所以这是在项目生命的开始时完成的。
  2. git mv子仓库文件到单独的文件夹

然后:

  • 上游更改可以正常获取和合并,但带有-Xsubtreegit merge 的标志。
  • 其他情况应该类似。我已经测试了向上游推送并且它有效,请参阅 [4] 中的评论。

参考

[1] 来自 git 邮件列表 http://git.661346.n2.nabble.com/Bug-Files-are-losing-history-after-subtree-merge-td7597197.html

[2] 来自 git 邮件列表 http://git.661346.n2.nabble.com/gsoc-Better-git-log-follow-support-td6188083.html#a6188352

[3]git log --follow已在 Google Summer of Code https://git.wiki.kernel.org/index.php/SoC2011Ideas#Better_git_log_--follow_support

[4] https://saintgimp.org/2013/01/22/merging-two-git-repositories-into-one-repository-without-losing-file-history

于 2016-10-31T19:22:02.673 回答