git-svn和远程git仓库同步

12

在我的工作中,我们使用SVN进行版本控制。当我发现git-svn时,我开始使用它,最近我决定将一些私有分支同步到另一个远程git仓库。因此,工作流程包括通过git-svn从SVN repo进行变基和推送,同时在单独的私有特性分支上工作,这些分支会被推送到远程git repo,以便在家中如果需要可以继续工作。

现在,每次我从git-svn进行变基时,我的远程git repo都要求先进行拉取。有时,进行拉取时更改无法干净地合并,尽管远程repo应该包含与我的本地repo同步的相同提交。最近我不得不删除远程分支,然后再次推送它们到远程repo,但这肯定不是正确的做法。

是git没有为这种工作流程设置好呢,还是我做错了什么?

谢谢!

3个回答

8

首先,感谢Matthew提供的链接——它们对我解决这个问题非常有帮助。

虽然可能需要一些小心和很可能存在与提交者数量有关的限制,但这是可以做到的。我的用例基本上就像mitjak描述的那样;单个用户需要或希望利用两个远程存储库,一个是SVN,另一个是Git。在我的情况下,前者位于防火墙后面的工作场所,而后者则在外部(也是私人的)。目标是能够使用Git在本地副本上工作并使两个远程存储库保持同步。

我的步骤:

所有操作都依赖于一个事实:git svn dcommit会更改与原始git提交相关联的SHA1。牢记这一点之后,在本地进行提交后,我[可选git svn rebase然后] git svn dcommit,生成最终的SHA1。此时,我将其推送到我的远程git存储库中。如果像Chacon所说的那样,你只想使用git提供更高效的克隆点,那么你已经完成了。但是,你可能还希望能够:

  1. 从另一个本地“纯git”存储库推送到远程git存储库,然后
  2. 同步混合git/svn存储库,然后
  3. 将这些更改推送到SVN存储库。

第1步没有问题;在本地“纯git”存储库提交后,git push到远程git存储库。

第2步也没有问题;回到你的混合git/svn存储库,在远程git存储库中git pull更改。此时,新拉取的修订版本关联的SHA1与远程git存储库中的SHA1同步。

第3步是整个过程变得有点棘手的地方。你可以像上面描述的那样使用git svn dcommit将这些更改推送到SVN存储库,但此时情况与上述情况有所不同。在这种情况下,你现在在远程SVN和git存储库中拥有相同的修订版本,但由于dcommit,它们具有不同的SHA1。我以以下方式处理:

在第2步中进行拉取时,我注意到相关的起始SHA1;例如,

  git pull
  输入someone@example.org的密码:
  远程:对象计数:5,完成。
  远程:压缩对象:100%(3/3),完成。
  远程:总共3个(增量0),重用0个(增量0)
  解包对象:100%(3/3),完成。
  来自ssh://example.org/pub/scm/demonstrate
    34b6260..17cd887  master     -> origin/master
  更新34b6260..17cd887
  快速前进
    file3 |    2 +-
    1个文件已更改,插入1个(+),删除1个(-)

所以这里感兴趣的SHA1是34b6260。 git log origin 应该会确认这是远程git存储库中具有与之关联的git-svn-id的最后一次提交。然后我执行以下操作:

git push -f origin 34b6260:master

执行强制更新远程存储库,以排除我从“纯git”本地存储库中进行的“纯git”提交--请小心使用!在这种情况下,我知道我在本地拥有这些提交;它们只是具有不同的SHA1与dcommit。然后,我git push到远程存储库,添加刚刚删除的提交的“git-svn-id”版本,远程存储库同步。

重新将“纯git”本地存储库与远程git存储库同步是最后一步,但类似的注意会产生令人满意的结果。在这种情况下,远程git存储库现在包含提交的“git-svn-id”版本,而本地的“纯git”存储库仍然包含原始SHA1。处理这种情况最简单的方法是从远程git存储库中git fetch,然后使用git reset --hard origin强制本地git存储库镜像远程状态。


1
这非常详细,几乎完全符合我的要求。我很犹豫该选择哪个回复作为答案 :) - dmkc

5
在《Pro Git》的第9.1章中(译者注:原文链接),Scott Chacon指出:

不要重写你的历史记录并尝试再次推送,也不要将其推送到并行的Git存储库以与其他Git开发人员协作。Subversion只能有一个线性历史记录,很容易混淆。如果你正在与团队一起工作,有些人使用SVN,而其他人使用Git,请确保每个人都使用SVN服务器进行协作-这样做会让你的生活更轻松。

基于以下声明:
  1. “不要将其推送到并行的Git存储库”,以及
  2. “Subversion只能有一个线性历史记录”,
看起来,除非从远程git repo拉取数据,否则Subversion无法处理您所需的工作流程,以使其具有单一的线性历史记录。

更新于 01-Sep-10, 8:37 PM

您可能想查看Daya Bay的文章Synchronizing Repositories中的高级:将另一个远程GIT存储库链接到您的GIT和GIT-SVN部分。


那似乎很有道理。我猜删除分支并重新推送是它将要处理的方式,除非我创建一个中间服务器来镜像 SVN 并完全隐藏它,让我纯粹使用 git。不过,如果 SVN 重写提交记录,那我仍然不确定它会怎么样。 - dmkc
关于你的更新,那似乎过于复杂了。我想现在我会尽量避免这种情况。谢谢! - dmkc

0

也许这个线程会有所帮助,尽管 git-svn 可能已经发生了变化。

我还会使用 fetch 而不是 pull,并在合并之前使用像 gitk 这样的工具快速查看是否会有冲突。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接