0

我的 git repo 正在跟踪一个 SVN repo。我的 git 分支之一,我们称之为“latest_tag”,它指向源代码,因为它位于最新的 SVN 标记中。创建新的 SVN 标签时,我想合并“latest_tag”中的更改。当我尝试这样做时,git 抱怨合并冲突,就好像它不了解 SVN 历史一样。

SVN repo 使用标准结构。

树干/
标签/
 - v1
分支机构/

我以通常的方式创建了我的 git repo。

git svn clone --stdlayout url_to_svn_repo git_repo

我为每个 SVN 标签创建了 git 分支,并创建了一个“latest_tag”分支。

git branch v1 tags/v1
git branch latest_tag v1

当在 SVN 存储库(例如 v2)中添加新标签时,我可以将它导入到我的 git 存储库中。

git svn fetch
git branch v2 tags/v2

但是,如果我尝试将“latest_tag”分支从 v1 快进到 v2,则会出现错误。

$ git checkout latest_tag
$ git merge v2
Auto-merging source.py
CONFLICT (add/add): Merge conflict in source.py
Automatic merge failed; fix conflicts and then commit the result.

当我查看冲突时,看起来 git 认为 v1 和 v2 之间的所有更改都是不相关的,尽管它们有共同的历史。

这是重新创建问题的最小脚本。

# Create the svn repo and its first tag.
svnadmin create svn_repo/
svn checkout "file:///${PWD}/svn_repo/" svn_working_copy
( cd svn_working_copy ; mkdir -p trunk tags branches ; svn add * ; svn commit -m 'Initialize SVN repo' ; cd trunk ; echo "print 'Hello v1'" >source.py ; svn add * ; svn commit -m 'Development for v1' ; cd .. ; svn cp trunk/ tags/v1 ; svn commit -m 'Tag v1' ; sed --in-place 's/v1/v2/' trunk/* ; svn commit -m 'Development for v2' ; )

# Create a git repo from the svn repo.
git svn clone --stdlayout "file://${PWD}/svn_repo/" git_repo
( cd git_repo ; git branch v1 tags/v1 ; git branch latest_tag v1 )

# Create tag v2 in svn.
( cd svn_working_copy ; svn cp trunk/ tags/v2 ; svn commit -m 'Tag v2' )

# Merge or rebase 'latest_tag' git branch on svn tag v2.
( cd git_repo ; git svn fetch ; git branch v2 tags/v2 ; git checkout latest_tag ; git merge v2 )

编辑 我确认 git 似乎对两个 SVN 标签之间的共同历史毫无意义。

$ git log --oneline master
bd050cd Development for v2
373f808 Development for v1
3b92703 Initialize SVN repo
$ git log --oneline remotes/tags/v1
31f9fff Tag v1
3b92703 Initialize SVN repo
$ git log --oneline remotes/tags/v2
b717759 Tag v2
3b92703 Initialize SVN repo

如果 git 理解 SVN 历史,它会输出这个。

$ git log --oneline remotes/tags/v1
31f9fff Tag v1
373f808 Development for v1
3b92703 Initialize SVN repo
$ git log --oneline remotes/tags/v2
b717759 Tag v2
bd050cd Development for v2
373f808 Development for v1
3b92703 Initialize SVN repo
4

1 回答 1

1

我发现了为什么 git 似乎对 svn 的历史一无所知。答案是:这取决于你如何创建你的 svn 标签。

查看 svn 历史,我看到 svn 标签是作为来自不同修订版的文件的组合创建的,而不是作为给定修订版的快照创建的。

$ svn log -v
------------------------------------------------------------------------
r3 | lacton | 2013-07-27 18:15:20 | 1 line
Changed paths:
   A /tags/v1 (from /trunk:1)
   A /tags/v1/source.py (from /trunk/source.py:2)

Tag v1
------------------------------------------------------------------------

尽管 svn 似乎对此非常满意,但 git-svn 对此感到困惑。

在创建标签之前添加一个可以svn update解决此问题。

$ svn up
At revision 2.
$ svn cp trunk/ tags/v1
A         tags/v1
$ svn commit -m 'Tag v1'
Adding         tags/v1

Committed revision 3
$ svn up
At revision 3.
$ svn log -v -r HEAD
------------------------------------------------------------------------
r3 | lacton | 2013-07-27 18:20:26 | 1 line
Changed paths:
   A /tags/v1 (from /trunk:2)

Tag v1
------------------------------------------------------------------------

通过此修复,git-svn 可以正确解释 svn 标签历史,并且不再存在合并冲突。

svn update这是初始问题提供的最小脚本的“git-friendly”版本(即,在创建标签之前)。

# Create the svn repo and its first tag.
svnadmin create svn_repo/
svn checkout "file:///${PWD}/svn_repo/" svn_working_copy
( cd svn_working_copy ; mkdir -p trunk tags branches ; svn add * ; svn commit -m 'Initialize SVN repo' ; cd trunk ; echo "print 'Hello v1'" >source.py ; svn add * ; svn commit -m 'Development for v1' ; cd .. ; svn up ; svn cp trunk/ tags/v1 ; svn commit -m 'Tag v1' ; sed --in-place 's/v1/v2/' trunk/* ; svn commit -m 'Development for v2' ; )

# Create a git repo from the svn repo.
git svn clone --stdlayout "file://${PWD}/svn_repo/" git_repo
( cd git_repo ; git branch v1 tags/v1 ; git branch latest_tag v1 )

# Create tag v2 in svn.
( cd svn_working_copy ; svn up ; svn cp trunk/ tags/v2 ; svn commit -m 'Tag v2' )

# Merge or rebase 'latest_tag' git branch on svn tag v2.
( cd git_repo ; git svn fetch ; git branch v2 tags/v2 ; git checkout latest_tag ; git merge v2 )
于 2013-07-28T11:34:56.500 回答