如何使用SVN存储库重新连接GIT存储库



我使用 git svn将现有的颠覆存储库导入git。然后,我将其推到GIT服务器上的Git Repo。在过去的几个月中,该软件的更改都是在颠覆和GIT存储库中进行的。不幸的是,我的本地副本具有SVN和GIT之间的链接。

我尝试再次使用git svn重新创建本地副本,但是当我从GIT服务器中进行拉动时,它会抱怨warning: no common conflicts,最终我在开始时将两个单独的分支合并为相同的提交。这样:

F
|
| 
E  D
|  |
C  C
|  |
B  B
|  |
A  A

如何像原始回购中的分支上一样对待SVN的变化?

F
|
| 
E  D
| /
|/
C
|
B
|
A

默认情况下,git-svn在提交消息中存储svn修订版和git提交之间的映射。您是否在原始GIT存储库中看到了这些git-svn-id行?在这里,我的意思是托管在Git Server上的Git存储库,而不是最近从SVN获取的git存储库。

如果是这样,您实际上并没有失去任何链接,而git-svn应该能够从历史记录中恢复必要的数据。尽管由于不同版本的git-svn之间的兼容性问题,但这可能有些棘手:

  1. 克隆您的原始git存储库:

    $ git clone $GIT_SERVER repo
    $ cd repo
    
  2. .git/config:

    中更新git-svn配置
    $ git config svn-remote.svn.url $SVN_URL
    $ git config svn-remote.svn.fetch trunk:refs/remotes/trunk
    $ git config svn-remote.svn.branches branches/*:refs/remotes/*
    $ git config svn-remote.svn.tags tags/*:refs/remotes/tags/*
    
  3. 现在,您必须将refs/remotes/* refs更新到使用git-svn-id行的最新提交:

    $ git log --first-parent refs/heads/master
    commit d566edf5f77ae0a2f7418c40949757e75ef8e83c
    D
    commit 4df9f21346526c6505a954d8310637864710308d
    C
    git-svn-id: $SVN_URL .../trunk@3...
    commit 116a6760d3e278aa4d54f5bb22e531d30d731661
    B
    git-svn-id: $SVN_URL .../trunk@2...
    commit d8bb201c6fd55ea5e645f2d8a07248593d177910
    A
    git-svn-id: $SVN_URL .../trunk@1...
    

    您可以看到Commit d没有GIT-SVN-ID行,但Commit C有一个,该行是指中继线,因此您必须更新refs/cop/promotes/trunk才能提交C:

    $ git update-ref refs/remotes/trunk 4df9f21346526c6505a954d8310637864710308d
    
  4. 如果您有很多分支和标签,请相对于我们上面指定的映射重复相同的步骤:

    • branches/foo => refs/remotes/foo

    • 标签/1.0 => refs/remotes/tags/1.0

  5. 最后一步是在.git/svn目录中还原映射:

    $ git svn fetch
    Migrating from a git-svn v1 layout...
    Data from a previous version of git-svn exists, but
        .git/svn
        (required for this version (X.Y.Z) of git-svn) does not exist.
    Done migrating from a git-svn v1 layout
    Rebuilding .git/svn/refs/remotes/trunk/.rev_map.694389ff-b137-4359-84f9-4d1a25628e89...
    r1 = d8bb201c6fd55ea5e645f2d8a07248593d177910
    r2 = 116a6760d3e278aa4d54f5bb22e531d30d731661
    r3 = 4df9f21346526c6505a954d8310637864710308d
    Done rebuilding .git/svn/refs/remotes/trunk/.rev_map.694389ff-b137-4359-84f9-4d1a25628e89
    

最后一个命令还从SVN服务器中获取了新的修订。命令完成后,您将拥有一个subversion存储库的git-svn克隆。该存储库中的历史记录有所不同,因此您必须像通常一样同步SVN和GIT存储库之间的更改:

$ git svn rebase
$ git svn dcommit

希望会有所帮助。

首先,我会检查git svn info命令的输出。你在那里看到一些奇怪的东西吗?

第二,最好的主意不是一个辅助GIT存储库以外的 git svn

原因是,在每个git svn dcommit GIT自动重写您之前所做的所有提交之后:首先,它将其归还给SVN,然后添加consit的SVN修订号(在称为唯一的标识符中git-svn-id)。

在您制作新dcommit的存储库中应该是这样的东西:

$ git log -1
commit 1234abc...
Author: ...
Date:   ...
Some commit message
git-svn-id: http://your.svn.repo/svn/trunk@10 1234abc

关于详细信息,这是《进程书》中的一部分。

您写的错误消息可能是warning: no common commits(不是您在问题中写的conflicts),我的印象是Git没有将这些元数据推入远程仓库。

我认为您可以从死者那里提出此SVN链接,但要小心,将其放在存储库的单独克隆上,并仔细阅读文档有关所需的元数据。在git中,您可以使用管道工具做很多事情,看看它们。

顺便说一句,您不能简单地克隆远程git repo并使用它?

希望这对某事有所帮助,或者至少给您一些想法,您可以开始寻找解决方案。

来自提交图形

F
|
| 
E   D
|   |
C1  C2
|   |
B1  B2
|   |
A1  A2

使用以下命令

git checkout <SHA1-B1>
git checkout -b new
git cherry-pick <SHA1-C2> <SHA1-D>
git checkout <SHA1-F>
git checkout -b position_f
git merge new

完成。无论如何,我还没有尝试。首先备份您的存储库。

最简单的解决方案是将您的本地git-svn分支推向您的git服务器,例如:

git push <git-server> <branch-name>:<branch-name>

它将与您的本地分支覆盖Git-Server分支。

只有当您确定git-svn分支具有GIT服务器所具有的所有提交。

怎么样:

  • 备份!
  • 将SVN历史记录到git
  • 将您的旧分支和新分支机
  • F之前,您的分支倒流到提交
  • 之前
  • C以来,在新近svn的C
  • 之上,重新考虑分支机构的所有更改
  • 重新进行合并

如果这不起作用,则可以尝试替换git,但这可能是一个坏主意。

最新更新