2

我有一个独立的 Git 存储库,我想将其迁移到新的 SVN 存储库。至少,我想迁移具有完整历史记录的主分支,但理想情况下我想迁移所有分支和标签。我只需要做一次迁移;我不需要重复这个或做任何双向同步或类似的事情。

根据我在网上可以找到的内容,执行此操作的最佳工具似乎是 git-svn。我觉得我遗漏了一些明显的东西,有一些参数git svn init或者git svn dcommit我需要传递,这将使所有这些都正常工作,但我找不到它。

这是我到目前为止所做的尝试:

尝试 1: git svn dcommit 到一个空白的 svn repo。

[dyaw@localhost v1]$ mkdir svngit ; cd svngit
[dyaw@localhost svngit]$ git svn init svn://server/emptyRepo --stdlayout
Initialized empty Git repository in /home/dyaw/stackoverflow/v1/svngit/.git/
[dyaw@localhost svngit]$ git svn fetch
[dyaw@localhost svngit]$ git config receive.denyCurrentBranch ignore
[dyaw@localhost svngit]$ cd ..
[dyaw@localhost v1]$ git clone /mnt/sharedDrive/sharedRepo/ plaingit
Cloning into 'plaingit'...
done.
[dyaw@localhost v1]$ cd plaingit/
[dyaw@localhost plaingit]$ git remote add svntest /home/dyaw/stackoverflow/v1/svngit
[dyaw@localhost plaingit]$ git branch -a | grep remotes/origin | grep -v -- '->' | cut -d/ -f3 | xargs -L1 git checkout
Branch 'Foo' set up to track remote branch 'Foo' from 'origin'.
Switched to a new branch 'Foo'
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
[dyaw@localhost plaingit]$ git push svntest --all
Enumerating objects: 2719, done.
Counting objects: 100% (2719/2719), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2591/2591), done.
Writing objects: 100% (2719/2719), 4.67 MiB | 18.55 MiB/s, done.
Total 2719 (delta 2011), reused 237 (delta 123)
remote: Resolving deltas: 100% (2011/2011), done.
To /home/dyaw/stackoverflow/v1/svngit
 * [new branch]      Foo -> Foo
 * [new branch]      master -> master
[dyaw@localhost plaingit]$ git push svntest --tags
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.32 KiB | 1.32 MiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To /home/dyaw/stackoverflow/v1/svngit
 * [new tag]         Many tags pushed
[dyaw@localhost plaingit]$ cd ../svngit/
[dyaw@localhost svngit]$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    Every single file in the repository

[dyaw@localhost svngit]$ git reset --hard
HEAD is now at 3161afd
[dyaw@localhost svngit]$ git status
On branch master
nothing to commit, working tree clean
[dyaw@localhost svngit]$ git svn dcommit
Unable to determine upstream SVN information from HEAD history.
Perhaps the repository is empty. at /usr/libexec/git-core/git-svn line 872.
  • “也许存储库是空的。” 是的,它肯定是空的。这就是重点,我目前在 SVN 中的内容为零,我需要将所有工作移到那里。
  • 这是一个完全空的 SVN 存储库。甚至没有trunk/tags/branches 目录。

尝试 #2: git svn dcommit 到具有适当基本结构(主干/标签/分支)的存储库。

  • 相同的基本结果。
  • git svn fetch新创建的 svngit 工作副本 的输出是:
    [dyaw@localhost svngit]$ git svn fetch
    r1 = 81aad897c91af332c969ece7655a86f8f670bfec (refs/remotes/origin/trunk)
    Checked out HEAD:
      svn://server/basicRepo/trunk r1
    
  • 第一个git push svntest --all失败,“更新被拒绝,因为远程包含您在本地没有的工作。这通常是由另一个存储库推送到相同的参考引起的。您可能希望首先集成远程更改(例如,'git pull .. .') 在再次推动之前。”。在执行git pull svntest master --allow-unrelated-histories并提交该合并后,推送成功。
  • 最后,git svn dcommit给出了关于空存储库的相同错误。

尝试 #3:使用 GitHub 的 SVN 网桥

  • 可以通过 SVN 访问 GitHub 上的 Git 存储库。
  • 我将我的 Git 存储库推送到 GitHub,并且能够从 SVN 访问它。( svn co https://github.com....)
  • 通常,svnrdump可以在给定 URL 的情况下转储 SVN 存储库(而不是svnadmin dump需要将存储库作为本地文件系统中的文件提供),但 svnrdump 返回svnrdump: E200007: The requested report is unknown.
  • 我能够进行svnrdump dump -r一次修订。任何修订似乎都有效,但指定--incremental或一系列修订(-r 1:2或所有内容的默认值)会导致报告该错误。
  • 显然 GitHub 通过 HTTPS 实现的 SVN 不包括对增量转储的支持。
  • 我可以通过 HEAD 进行 1 的非增量转储,但我不知道有什么方法可以将这些连续的非增量转储转回增量转储,以便它可以拥有完整的历史记录。

尝试 #4:在 SVN 中进行初始提交,然后从那里 dcommit

根据 Jeff Mercado 的回答

在执行所有 git svn 内容之前,我在 SVN 的主干中创建了一个空文件。我第一次通过,dcommit 有到 SVN 的链接,但实际上并没有在初始分支上提交任何内容,然后在切换到另一个分支和切换回 master 时给出了错误。当我重复这些步骤以捕获输出以在此处发布时,它立即给出了错误。回顾命令历史,我看不出有什么不同。无论如何,我仍然无法提交。

[dyaw@localhost v4]$ svn co svn://server/emptyRepo svn
Checked out revision 0.
[dyaw@localhost v4]$ cd svn
[dyaw@localhost svn]$ mkdir trunk tags branches
[dyaw@localhost svn]$ svn add trunk tags branches
A         trunk
A         tags
A         branches
[dyaw@localhost svn]$ cd trunk/
[dyaw@localhost trunk]$ touch dummyMigrationFile
[dyaw@localhost trunk]$ svn add dummyMigrationFile
A         dummyMigrationFile
[dyaw@localhost trunk]$ svn ci -m "Added directory structure and dummy file"
Adding         .
Adding         dummyMigrationFile
Transmitting file data .done
Committing transaction...
Committed revision 1.
[dyaw@localhost trunk]$ cd ../..
[dyaw@localhost v4]$ mkdir svngit ; cd svngit
[dyaw@localhost svngit]$ git svn init svn://server/emptyRepo --stdlayout
Initialized empty Git repository in /home/dyaw/stackoverflow/v4/svngit/.git/
[dyaw@localhost svngit]$ git svn fetch
        A       dummyMigrationFile
r1 = a934fa2864bd46f0090c2cdf486c924ceb09fb52 (refs/remotes/origin/trunk)
Checked out HEAD:
  svn://svn1/Data/00000999-migrate/trunk r1
[dyaw@localhost svngit]$ git config receive.denyCurrentBranch ignore
[dyaw@localhost svngit]$ cd ..
[dyaw@localhost v4]$ git clone /mnt/sharedDrive/sharedRepo/ plaingit
Cloning into 'plaingit'...
done.
[dyaw@localhost v4]$ cd plaingit/
[dyaw@localhost plaingit]$ git remote add svntest /home/dyaw/stackoverflow/v4/svngit
[dyaw@localhost plaingit]$ git branch -a | grep remotes/origin | grep -v -- '->' | cut -d/ -f3 | xargs -L1 git checkout
Branch 'Foo' set up to track remote branch 'Foo' from 'origin'.
Switched to a new branch 'Foo'
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
[dyaw@localhost plaingit]$ git push svntest --all
Enumerating objects: 2719, done.
Counting objects: 100% (2719/2719), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2591/2591), done.
Writing objects: 100% (2719/2719), 4.67 MiB | 18.62 MiB/s, done.
Total 2719 (delta 2011), reused 237 (delta 123)
remote: Resolving deltas: 100% (2011/2011), done.
To /home/dyaw/stackoverflow/v4/svngit
 * [new branch]      Foo -> Foo
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '/home/dyaw/stackoverflow/v4/svngit'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
[dyaw@localhost plaingit]$ git pull svntest master --allow-unrelated-histories --no-edit
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/dyaw/stackoverflow/v4/svngit
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> svntest/master
Merge made by the 'recursive' strategy.
 dummyMigrationFile | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dummyMigrationFile
[dyaw@localhost plaingit]$ git push svntest --all
Enumerating objects: 593, done.
Counting objects: 100% (593/593), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (552/552), done.
Writing objects: 100% (552/552), 4.05 MiB | 19.00 MiB/s, done.
Total 552 (delta 417), reused 0 (delta 0)
remote: Resolving deltas: 100% (417/417), completed with 30 local objects.
To /home/dyaw/stackoverflow/v4/svngit
   a934fa2..127ed95  master -> master
[dyaw@localhost plaingit]$ git push svntest --tags
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.32 KiB | 1.32 MiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To /home/dyaw/stackoverflow/v4/svngit
 * [new tag]         Lots of tags
[dyaw@localhost plaingit]$ cd ../svngit/
[dyaw@localhost svngit]$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    All the files that were in the original git

[dyaw@localhost svngit]$ git reset --hard
HEAD is now at 127ed95 Merge branch 'master' of /home/dyaw/stackoverflow/v4/svngit
[dyaw@localhost svngit]$ git status
On branch master
nothing to commit, working tree clean
[dyaw@localhost svngit]$ git svn dcommit
Unable to determine upstream SVN information from HEAD history.
Perhaps the repository is empty. at /usr/libexec/git-core/git-svn line 872.

[dyaw@localhost svngit]$ ll
total 4128
-rw-r--r--. 1 dyaw domain users       0 Aug 12 12:47 dummyMigrationFile
-rw-r--r--. 1 dyaw domain users     553 Aug 12 12:48 All the files of the original git
[dyaw@localhost svngit]$ git log | head -n 20
commit 127ed959dd48230e100b24878014b290f795d298
Merge: 3161afd a934fa2
Author: David Yaw <dyaw@localhost>
Date:   Wed Aug 12 12:47:49 2020 -0400

    Merge branch 'master' of /home/dyaw/stackoverflow/v4/svngit

commit a934fa2864bd46f0090c2cdf486c924ceb09fb52
Author: (no author) <(no author)@057915ec-d7cd-45ea-bdf3-a57c6415ee48>
Date:   Wed Aug 12 16:13:26 2020 +0000

    Added directory structure and dummy file

    git-svn-id: svn://server/emptyRepo/trunk@1 057915ec-d7cd-45ea-bdf3-a57c6415ee48

commit 3161afdcb9272a6b047725ccbd1f125b973c7d68
Author: someone else
Date:   Mon May 11 10:10:26 2020 -0400

    This is the last commit on master of the original git repo
[dyaw@localhost svngit]$
4

1 回答 1

0

为了让 git-svn 工作,它必须首先与现有的 svn 存储库同步,这样它就知道当前的修订是什么,并且可以创建新的提交。如果存储库完全空白并且没有初始提交,那么它就无法与之同步。

您应该在 SVN 存储库中创建一个空白的初始提交,然后从那里同步和 dcommit。


否则,如果您坚持与空白 svn 存储库同步,您可以尝试手动更新 refs 以使其看起来像有一个基本的 svn 提交。然后,当您执行 dcommit 时,git-svn 将看到“假基础提交”并将您的更改提交为 svn 提交。唯一需要注意的是,您必须从这个空提交中重新设置您的 repo。我什至不确定 SVN 存储库是否会接受提交。

于 2020-08-12T05:10:09.793 回答