4

我正在尝试通过“子树合并”将外部 SVN 存储库用作我的存储库中的子树。我相信这应该保持库中文件的历史完整,但它不起作用 - 来自合并到我的主分支中的子树的库没有历史记录,但在我添加它们时提交 - 这是一个历史记录来说明我的意思,正是我将要达到的状态如下。

lappy8086:YACYAML jamie$ git log --graph 
* commit 0cc6c4e5061741e67d009f3375ce1d2bcd3ab540
| Author: James Montgomerie
| Date:   Thu May 17 12:04:43 2012 +0100
| 
|     Subtree-merge in libYAML (from a git-svn checkout).
|  
* commit b5af5af109d77f6adafebc3dcf5a4796a5035a2e
Author: James Montgomerie
Date:   Thu May 17 11:47:32 2012 +0100

First commit, add .gitignore.

这就是我正在做的尝试让它发挥作用:

# check out SVN repo
git svn clone http://svn.pyyaml.org/libyaml/branches/stable libYAML

# create my repo
mkdir YACYAML
cd YACYAML
git init
touch .gitignore
git add .gitignore
git commit -m "First commit, add .gitignore"

# Fetch from git-svn repo I got earlier
git remote add libyaml-svn ../libYAML/
git fetch libyaml-svn
git checkout -b libyaml-svn libyaml-svn/master

# Switch back to master, and try to merge in subtree
git checkout master
git read-tree --prefix=libYAML/ -u libyaml-svn/master
git commit -m "Merge in libYAML as subtree (from git-svn checkout of SVN repo)"

这“有效”,但是,正如我所说,当我查看我的历史记录时,我希望从 libYAML 存储库中看到完整的历史记录,但我没有 - 如上所述。

4

2 回答 2

2

git log [--follow] <filename>当合并包括子目录内的树的重新父级时,行为方式似乎不一致,就像这样git subtree做一样。

我进行了一些实验,如果您在第一个子树合并之前在源代码行上引入合成的重新父级提交,那么历史开始通过git log --follow <filename>.

我可以看到的选项:

  1. 修复以跟随合并期间git log发生的重命名
  2. 更改git subtree为为每个添加创建两个提交,首先在一个提交中重新设置树,然后在之后合并重新设置的提交
  3. .git/info/grafts通过使用and完成 #2 手动解决问题git filter-branch

解决方法:

$ git log --grep git-subtree-mainline
commit 8789f3c80122d1fc52ff43ab776a7b186f51c3c6
Merge: 0c11300 4757376
Author: John Sumsion <email>
Date:   Wed Apr 17 09:43:21 2013

    Add 'some-subdir/' from commit 'f54875a391499f910eeb8d6ff3e6b00f9778a8ab'

    git-subtree-dir: some-subdir
    git-subtree-mainline: 0c113003278e58d32116c8bd5a60f2c848b61bbb
    git-subtree-split: f54875a391499f910eeb8d6ff3e6b00f9778a8ab
$ git checkout -b fix 
Switched to a new branch 'fix'
$ mkdir -p some-subdir
$ git mv <files> some-subdir
$ git commit -m "Re-parenting files before subtree merge to preserve 'git log --follow' history"
$ echo <orig_merge> <orig_parent> <fixed_merge_parent> >> .git/info/grafts
$ git filter-branch --index-filter true --tag-name-filter cat master

以下提交是:

  • orig_merge: 8789f3c80122d1fc52ff43ab776a7b186f51c3c6
  • orig_parent: 0c113003278e58d32116c8bd5a60f2c848b61bbb
  • fixed_merge_parent: 沙从git commit

不幸的是,git subtree在第一个子树合并之后合并到 via 中的后续更改似乎不会被报告 via,git log --follow <filename>即使第一个子树合并被综合地重新设置为父级。

出于某种原因,我似乎记得这在 Git 1.7.x 时间范围内运行良好,但这是我没有时间研究的遥远过去的模糊记忆。以上是在 Git 1.8.3.2 中观察到的。

于 2013-07-03T05:39:06.247 回答
2

好吧,一个答案是安装 git-subtree 并将其用于:

git subtree add --prefix=libYAML/ ../libYAML master

这导致我手动执行它正在寻找(和预期):

lappy8086:YACYAML jamie$ git log --graph
*   commit 453d464cfc140c798d0dea85ab667fe16250181d
|\  Merge: 9fb083d 0ca365a
| | Author: James Montgomerie 
| | Date:   Thu May 17 14:32:36 2012 +0100
| | 
| |     Add 'libYAML/' from commit '0ca365adeb5711bf918d4401e98fce00bab8b3ec'
| |     
| |     git-subtree-dir: libYAML
| |     git-subtree-mainline: 9fb083d923011dd990222da2a58eda42e5220cde
| |     git-subtree-split: 0ca365adeb5711bf918d4401e98fce00bab8b3ec
| |   
| * commit 0ca365adeb5711bf918d4401e98fce00bab8b3ec
| | Author: xi
| | Date:   Sun May 29 05:52:36 2011 +0000
| | 
| |     Bumped the version number and updated the announcement.
| |     
| |     git-svn-id: http://svn.pyyaml.org/libyaml/branches/stable@374 18f92427-320e-0410-9341-c67f048884a3
| |   
| * commit 210b313e5ab158f32d8f09db6a8df8cb9bd6a982
| | Author: xi
| | Date:   Sun May 29 05:29:39 2011 +0000
| | 
| |     Added support for pkg-config.
| |     
| |     git-svn-id: http://svn.pyyaml.org/libyaml/branches/stable@373 18f92427-320e-0410-9341-c67f048884a3
...etc...

我仍然想知道在不依赖 git-subtree 的情况下执行此操作的正确方法。

于 2012-05-17T13:35:56.007 回答