将两个具有共同历史记录的 svn 存储库迁移到 git

发布于 2024-11-30 23:02:01 字数 790 浏览 0 评论 0 原文

我正在计划使用 svn 来 git 迁移一堆存储库。其中两个处于特定状态。

已经在 svn 仓库中开发了一个项目。由于各种限制,该项目在某个时候被分叉了。该 fork 是通过复制 svn 存储库制作的。此后,这两个项目分别发展。除了主干之外,两个存储库中都不存在任何分支或标签。

原始项目已经开发了一个重要的功能,需要移植到分支上。在当前情况下,这可以通过从各种修订创建补丁并将其应用到分叉项目来完成。在当前情况下,这具有短期简单的优点,但从长期来看会产生许多难以处理的后果。

我们可以有两个不同的 git 存储库,并通过拉取请求进行跨叉移植,但这可能缺乏可用性(我们不使用 github)。此外,由于模块化设计重构,有时我们可能希望将分叉重新集成到父项目中。另一种方法是将两个 svn 存储库作为不同的分支合并到一个 git 存储库中,并从那里管理后续合并(具有它提供的所有优点)。

理想情况下,我想重新创建项目的真实历史,即拥有一个 git 存储库,其中包含:

  • 单个分支由直至分叉的提交组成
  • 两个不同的分支由父级和分叉提交组成,直至 HEAD

一个有趣的事实可能会有所帮助,以下命令为常见提交生成相同的 SHA1:

git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo/path git_migration

我不关心 --no-metadata 因为它是单向迁移。

如果可能的话,我怎样才能达到这样的结果呢?

I am planning a svn to git migration of a bunch of repositories. Two of them are in a particular state.

A project has been developped in a svn repo. Due to various constraints, the project has been forked at some point. The fork has been made by duplicating the svn repo. After that point, the two projects evolved separately. No branches or tags exist in either repo besides the trunk.

A significant functionality has been developed for the original project and needs to be ported to the fork. In the current situation this could be done by creating a patch from the various revisions and applying it on the forked project. This has the advantage of short term simplicity in the current situation but has a number of unwieldy consequences on the long term.

We could have two distinct git repos and do cross-fork porting via pull requests, but this could lack usability (we're not using github). Besides there may come a time where we might want to reintegrate the fork into the parent project thanks to modular design refactoring. Another approach would be to merge the two svn repositories into a single git repository as distinct branches, and manage subsequent merges from there (with all the advantages that it gives).

Ideally I'd like to recreate the true history of the project, that is have a git repo with:

  • a single branch comprised of commits up to the fork
  • two distinct branches comprised of parent and fork commits up to HEADs

An interesting fact that might help, the following command produces identical SHA1s for the common commits:

git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo/path git_migration

I don't care about --no-metadata because it's a one-way migration.

How could I achieve such a result, if even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

因为看清所以看轻 2024-12-07 23:02:01

由于您有办法使用相同的哈希值来克隆 SVN 存储库以进行常见提交,因此这应该可行。

git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo1/path git_migration
git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo2/path git_migration-2
cd git_migration
git branch repo1 # Branch for first repo
git reset --hard <highest_common_hash> # To have only common history on master
git checkout -b repo2 # Branch for second repo
git pull ../git_migration-2 master

现在,您必须在 master 和不同 SVN 存储库的 2 个分支中拥有共同的历史记录。

Since you have a way to clone the SVN repos with identical hashes for common commits, this should work.

git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo1/path git_migration
git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo2/path git_migration-2
cd git_migration
git branch repo1 # Branch for first repo
git reset --hard <highest_common_hash> # To have only common history on master
git checkout -b repo2 # Branch for second repo
git pull ../git_migration-2 master

Now you must have common history in master and 2 branches for the different SVN repos.

弱骨蛰伏 2024-12-07 23:02:01

通常可以使用 git 移植点

我建议您参考

https://git.wiki.kernel.org /index.php/GraftPoint

中简单地说,您只需告诉 git 哪些修订版共享某个父修订版(如果您愿意的话,这是一个神奇的“合并”结果)。 git filter-branch 示例将其付诸实践。

一旦您满意,您就可以使用 “nofollow”>man git-filter-branch

echo "$commit-id $graft-id" >> .git/info/grafts
git filter-branch $graft-id..HEAD

Joining history to a single root in general can usually be done using git Graft Points

Il refer you to

https://git.wiki.kernel.org/index.php/GraftPoint

In simplistic terms, you just tell git which revisions share a certain parent revision (a magic 'merge' result if you will). Once you're happy you can cast it in stone using git filter-branch

Sample from man git-filter-branch

echo "$commit-id $graft-id" >> .git/info/grafts
git filter-branch $graft-id..HEAD
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文