3

我有一个旧的 SVN 存储库,我使用git-svn它来检查它并推送到 Heroku。我正在做一个相当标准git push heroku master的舞蹈,一切都很好git svn rebasegit svn dcommit

但是,最近我一直在做一些 git 工作,并且有git svn rebase一段时间没有做。现在,当我尝试进行 rebase 时,由于合并冲突而失败,尽管我是唯一一个致力于 repo 并且只在 master 上工作的人。

认为这可能是工作副本的问题,我做了一个 newgit svn clone然后一个git remote add herokuand git pull heroku master。拉动可以毫无问题地进行快进合并,但git svn rebase仍然失败。

我做了一个简单的git log,我看到我有一些旧的提交缺少git-svn-ids:

commit def8bab861314c67d4e8227e03775d19045d21d1
Author: peterr
Date:   Fri Sep 21 16:17:33 2012 +0000

    PHP Cedar support.

    git-svn-id: http://vcp.unfuddle.com/svn/vcp_bbsit@24 b6b24ac3-8b7a-4c11-a811-49c5d0334e85

commit f51bd78fb07dde6ec1dc4e0ba51a48f2b6bd1bd6
Author: pr1001
Date:   Mon Aug 20 19:39:42 2012 +0200

    Specify port correctly

commit 153bb2929080898dcab46142120def0f4964dfab

...

commit 5a416fa3af9f64aa353d5171bedfaa563115ff62
Author: pr1001
Date:   Mon Aug 20 17:22:58 2012 +0200

    PHP Cedar support.

commit e0b35588d03082a3a4ab49a7b590f206346046c0
Author: j
Date:   Fri Aug 3 08:13:33 2012 +0000

    change email

    git-svn-id: http://vcp.unfuddle.com/svn/vcp_bbsit@23 b6b24ac3-8b7a-4c11-a811-49c5d0334e85

一个 SO 答案中,我收集到我可能能够重写提交消息以添加丢失的信息,但我想知道这是否会更糟。

查看消息,看起来我有一些重复的提交,例如“PHP Cedar 支持”。我真的很困惑为什么我有这些重复,尽管我怀疑它们可能会被转发给git push heroku master我前几天被告知存储库不同步的失败。git pull heroku master似乎完全没有带来任何变化并解决了这个问题,但也许它带来了重复的提交。

所以,鉴于这一切,我的问题很简单,我该如何进行?我在 Heroku 上有一个工作应用程序,在 SVN 存储库中有一个较旧的工作代码库,但我没有看到任何简单的方法可以将新的提交干净地提交到 SVN。我应该挑选它们吗?然后我是否需要对 Heroku 应用程序进行核对,以免重复项返回?

4

1 回答 1

4

很难猜测你是如何陷入这种情况的,但我认为这是因为当推送到 SVN 时,git-svn 替换(使用 rebase 或 reset)带有 git-svn-id 签名的提交,所以每个提交都有 2 个示例: “本地”——没有“git-svn-id”签名——和带有签名的远程。

恢复:

  1. 创建一个临时分支以保持当前状态(某种备份):git co -b backup
  2. 确保 refs/remotes/git-svn 指向与您的 subversion 存储库相对应的 git-svn-id 的最新提交,并且没有 git-svn-id 的提交显示为git log refs/remotes/git-svn

如果不是这样,您可以使用以下技巧来修复 refs/remotes/git-svn:更新 refs/remotes/git-svn 以指向一切正常的最新提交(在您的情况下,它对应于 r23):

$ git update-ref refs/remotes/git-svn e0b35588d03082a3a4ab49a7b590f206346046c0

将 .git/svn/metadata 修订版设置为指向该修订版:

[svn-remote "svn"]
        reposRoot = ...
        uuid = <UUID>
        branches-maxRev = 23
        tags-maxRev = 23

删除(或更好地移开)文件 .git/svn/refs/remotes/git-svn/.rev_map.UUID 现在运行

$ git svn fetch

您的 refs/remotes/git-svn 参考现在恢复到最新的有效 SVN 版本。

3. 无需合并即可从 Git 存储库中获取所有更改

$ git fetch heroku master

现在您所有的更改都在 refs/remotes/heroku/master 中。

4. 确保您没有本地更改(我建议您现在在 master 上)。将 refs/heads/master 重置为 refs/remotes/git-svn。做到这一点的方法之一:

$ git update-ref refs/heads/master refs/remotes/git-svn
$ git reset --hard HEAD

5. 查看 refs/remotes/heroku/master 和 refs/remotes/git-svn。Git 存储库中是否存在 refs/remotes/git-svn 中不存在的更改?如果是,请一一挑选。还请查看您的备份分支(仅在没有 git-svn-id 的提交中),如果它们还没有在 SVN 中,也可以挑选它们。

6. 现在您在 master 中有一些在 SVN 中还没有的更改。跑

$ git svn dcommit

将它们推送到 SVN。

7. 现在您的 SVN 相关分支已完全修复并具有所有更改。如果我理解正确,您希望 Git 存储库中的内容相同。用当前的主内容更好地替换 refs/remotes/heroku/master:

$ git push heroku master --force

现在您的 Git 存储库具有与 SVN 存储库相同的内容。

为了避免将来出现这些问题,请确保您永远不要将没有 git-svn-id 的提交推送到 Git(即,当您运行“git push”时,您的 master 仅包含带有 git-svn-id 签名的提交——如果不是——运行“git svn dcommit”先将它们推送到 SVN)。

于 2012-09-24T21:15:06.217 回答