33

我在网上阅读了大量“从 svn 到 git”和其他“git-svn 工作流程”的文章,但我仍然认为它们经常处理过于简单的情况。他们通常针对那些只想在本地使用 git 和 hack 的人,而不使用 git 的全部功能,例如在多个开发人员之间进行 pull、fetch、merge 等,他们都将使用 git-svn 克隆 svn 存储库,然后仍然希望能够随时将他们的更改推送到(官方)svn 存储库,并回到在 git 中工作并分享他们的东西等。

每当这些文章承认你不能在纯 git 中做所有事情时,后果和可能的错误永远不会被清楚地解释(或者也许只是我?)。甚至 git-svn 手册页也提到了警告,但并没有以广泛的方式。

根据我所阅读的内容,我觉得以这种特定方式使用 git-svn 可能会出现问题,我将在下面进行描述。有人可以告诉我我是否正确吗?

这是“想要”的做事方式:

  1. 我们在 svn 存储库中有一个项目
  2. 开发人员 git-svn-clone 是 svn 存储库。他开始在本地破解东西
  3. 开发者 B git-svn-clone 是同一个 svn repo。他开始自己破解东西。
  4. 在这样做了一段时间后,可能会添加开发人员 C/D/...,并让其他开发人员对原始存储库执行“标准”svn 提交,git 用户会想要共享他们的代码并做各种 git 魔术.
  5. 这些 git 用户中的任何一个都希望能够将现在合并的更改推送到 svn(dcommit?)

我的问题是:我在做梦吗?我前段时间在一本 git 书中读到,我认为 git-svn-clone 可以创建 git 存储库,这些存储库当然是 svn 存储库的“镜像”,但是不同开发人员以这种方式创建的 git 存储库会有不同的“ ids”和提交会有不同的哈希值。所以我的理解是,那些 git repos 不会共享任何共同的 git 祖先,因此无法使用您需要共享、合并等的所有 git 命令。是真的吗,我们会面临这个工作流程的问题吗?

有时我读到这可以做到,至少使用一个“官方”裸 git 存储库,这将是唯一一个被 git-svn-clone 的,所有 git 用户都必须从这个开始。然后你需要一个负责这个中央 git 存储库的人,并收集 git 开发人员之间的更改,然后将所有内容提交到 svn 存储库。这将是 git 用户“不知道”原始 git repo 来自 svn 的唯一方法,并允许他们随意使用所有 git 命令。唯一需要精通 git 和 svn(并了解 git-svn 警告)的人将是“合并经理”(或他所谓的任何东西)。

我完全误解了 git-svn 警告吗?有没有更简单的方法来做到这一点?

4

7 回答 7

23

我最近对此进行了很多试验,并认为我设法提出了一个有点工作的设置。是的,这是一个严格的 rebase-only 制度,是的,它很复杂,但你确实可以使用 Git 在本地工作(速度、历史记录、存储、索引等)。

我认为,当您与团队中的其他 Git 用户协作时,您可以在幕后使用分支,但个人并没有对此进行过多的实验。只要在 dcommitting 之前对日志进行线性化,它就可以工作。

这是简短的版本(重复了很多已经说过的内容):

  1. 将 Subversion 存储库克隆到中央服务器上的“获取”存储库中
  2. 在同一台服务器上初始化一个“裸”repo
  3. 从 fecting 仓库推送到裸仓库
  4. 让开发人员克隆裸仓库,然后
    1. git svn init svnurl配置 git-svn 远程,和
    2. git update-ref refs/remotes/git-svn refs/remotes/origin/master所以 git-svn 有一个指向修订的指针
  5. 自动(提交钩子)拥有“获取”repo svn rebase,并推送到裸仓库
  6. 开发人员从裸仓库中提取git pull --rebase
  7. 如果有来自 SVN 的更新版本,首先运行的开发人员git svn dcommit必须重复上述操作。update-ref

此页面上有一个工作流程说明(我需要更多的信誉点才能内联图像)。更新:我们开始:

于 2010-08-06T09:15:09.867 回答
19

问题当然是第 4 步。dcommit 尝试将您的本地历史记录重播到服务器。Dcommit 假装你是一个 SVN 客户端。现在,如果您提交的代码不仅来自您,那将很难提交给 SVN。

以下是大师就此事写的:

  • 为了简单和与 SVN 互操作,建议所有 git-svn 用户直接从 SVN 服务器(即远程 SVN 存储库)克隆、获取和 dcommit,避免所有 git-clone/pull/merge/push git 存储库和分支之间的操作,这些操作可以通过 git svn clone 检索,也用于将变更集推回远程 SVN 存储库。
  • 在 git 分支和用户之间交换代码的推荐方法是 git format-patch 和 git am,或者只是 git svn dcommit 到 SVN 存储库。
  • 由于 git svn dcommit 在内部使用 git svn rebase,我们在 git svn dcommit 之前 git 推送到的任何 git 分支都需要强制覆盖远程存储库上的现有 ref。这通常被认为是不好的做法,有关详细信息,请参阅 git-push 文档。
  • 不建议在我们计划从中执行 git svn dcommit 的分支上运行 git merge 或 git pull 。SVN 不以任何合理或有用的方式表示合并,因此使用 SVN 的用户看不到我们所做的任何合并。此外,如果我们从作为 SVN 分支镜像的 git 分支执行 git merge 或 git pull , git svn dcommit 可能会提交到错误的分支。
  • git clone 不会克隆 refs/remotes/ 层次结构或任何 git-svn 元数据或配置下的分支。因此,使用 git-svn 创建和管理的存储库应该使用rsync 进行克隆,如果要进行克隆的话。
  • 我们不应该对我们已经提交的更改使用 git commit 的 --amend 选项。--amend 我们已经为其他用户推送到远程存储库的提交被认为是不好的做法,SVN 的 dcommit 与此类似。有关这方面的更多信息,请参阅修改单个提交和 重写历史记录问题
于 2009-12-10T11:55:03.370 回答
3

我以前做的是创建一个初始的 git svn clone,然后使用 git 在开发人员之间共享他的 .git,所以我们有完全相同的引用。

它似乎可以正常工作,因为我们能够在 git 用户之间使用“特定的 git 功能”,只要我们停留在线性树中(即变基而不是合并)。

于 2009-12-10T11:44:28.137 回答
2

有一个工具可以解决共享与 Subversion 存储库同步的 Git 存储库的问题。

SubGit是一个 Git-SVN 双向服务器端镜像。

可以将 SubGit 安装到 Subversion 存储库中,并使 Git 存储库自动与 SVN 同步:

$ subgit configure $SVN_REPOS
# Adjust $SVN_REPOS/conf/subgit.conf to specify branches, tags and other options;
# Adjust $SVN_REPOS/conf/authors.txt to specify git & svn authors mapping
$ subgit install $SVN_REPOS
...
$ INSTALLATION SUCCESSFUL

SubGit 将 pre-commit 和 post-commit 挂钩安装到 Subversion 存储库中,将 pre-receive 和 post-receive 挂钩安装到 Git 存储库中。结果,它立即翻译来自 SVN 和 Git 端的传入修改。安装 SubGit 后,开发人员可以使用任何 Git 客户端来克隆和使用 Git 存储库。

SubGit 不依赖 git-svn,它使用我们团队开发的自己的翻译引擎。您可以在SubGit 与 git-svn比较中找到更多详细信息。有关 SubGit 的一般文档可在此处获得。

SubGit 1.0 版需要对Subversion 存储库进行本地访问,即SVN 和Git 存储库必须驻留在同一主机上。但是在 2.0 版本中,我们将引入 Git 代理模式,此时 Subversion 和 Git 存储库可以位于任何地方,并且只有 Git 存储库安装了 SubGit,即 Subversion 存储库保持不变。

SubGit 是一个商业产品。它对开源、学术项目以及最多 10 个提交者的项目都是免费的。

免责声明:我是 SubGit 开发人员之一。

于 2012-10-11T14:57:47.440 回答
2

我发现这篇博客文章建议保留一个单独的分支以与 Subversion 存储库同步,这样它仍然可以在主分支中进行推送/拉取。

于 2010-06-11T18:53:55.433 回答
2

一旦你介入“分布式”问题,你最好在开发人员之间克隆一个裸 git repo。
关于到公共 SVN 存储库的导出-导入阶段,对于其他使用,脚本
git2svn 和 svn2git可以帮助封装魔法。

在 Git 和 SVN 存储库中工作时的其他注意事项可在问题“工作流程和 git 帮助、2 个 svn 项目和单个“工作副本””中找到

于 2009-12-10T11:49:34.473 回答
1

我认为 git-svn 的问题之一是它将 git-svn-id 存储在提交注释中;因为这会重写该提交,它会更改它的 SHA1,所以你不能将它推送到人们将共享它的任何地方。

我实际上更喜欢 bzr-svn,因为它使用 SVN 修订属性功能将 bzr revid 存储在远程 SVN 修订中,这意味着没有本地修订重写。它还具有所需的属性,即同一 SVN 分支的两个独立拉动将产生相同且可互操作的 bzr 分支。

于 2010-10-18T15:36:41.760 回答