8

我使用 git-svn 来保存共享 Subversion 存储库的克隆。最近有人在我编辑该修订后编辑了修订的提交消息(这个SO 问题git svn fetch。如何更正我的 Git 克隆以获得正确的提交消息?

我曾期望git svn reset随后git svn fetch重新获取此提交并更新内容,让我只需要修复我的本地分支,但这实际上似乎并没有做任何事情;git svn fetch不会重新获取我重置的提交。

(是的,我认为更改提交消息是个坏主意,但这不是我可以控制的。)

更新:我尝试了 sleske 建议的过程(实际上,我在提出问题之前已经尝试过,但我只是再次尝试以防万一),但没有运气。我得到如下输出:

me_and@centos ~/code ((358a2dd...)) Fri 16 Jan 15:31:27
$ git svn reset -p 55102
r55094 = 25d126219f7eeddfc7d0842704c7efcc0443dd70     (refs/remotes/origin/branchname)

me_and@centos ~/code ((358a2dd...)) Fri 16 Jan 15:33:06
$ git svn fetch

me_and@centos ~/code ((358a2dd...)) Fri 16 Jan 15:33:08
$ 

没有输出git svn fetch(或者自从我上次运行它以来是否有提交,但它只是获取新的提交,而不是重新获取旧的提交),特别rereading是在 sleske 的示例中没有消息。

如果它是相关的,我正在使用 Git v2.0.4。

更新 2:以下略作编辑.git/config

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[svn-remote "svn"]
    url = http://server/repos/repo
    fetch = trunk:refs/remotes/origin/trunk
    branches = branches/*:refs/remotes/origin/*
    tags = tags/v10/*:refs/remotes/origin/tags/*
    tags = tags/v11/*:refs/remotes/origin/tags/*
    tags = tags/v12/*:refs/remotes/origin/tags/*
    tags = tags/v13/*:refs/remotes/origin/tags/*

我不会发布 的完整输出git branch -avv,因为它有很多,但这就是它变得非常有趣的地方,所以我将发布我所做的所有事情的列表:

  1. 我有一个分支的结帐,而不是有错误的分支。运行git svn reset没有区别:remotes/origin/branchname继续指向最近的提交。不出所料,git svn fetch什么都没做。

  2. 我检查remotes/origin/branchnamegit svn reset再次运行。这有效:remotes/origin/branchname指向 duff 提交的父级。

  3. 我跑了git svn fetch。这完全没有做任何事情:没有提交被提取并且remotes/origin/branchname没有移动。

  4. 我在 Subversion 存储库的那个分支上创建了几个虚拟提交(一个添加了一个空文件,下一个又删除了它),然后运行git svn fetch again​​.

    这是真正奇怪的地方:没有重新获取 duff 提交。相反,提取从我添加虚拟文件的提交开始,在该过程中报告了“索引不匹配”。git show在添加虚拟文件的提交上运行会显示我重置到的提交和虚拟提交之间的所有差异.

    现在,运行git log --graph --decorate --pretty=oneline --abbrev-commit HEAD origin/branchname看起来像这样:

    * 7b12bbc (origin/branchname) Remove dummy file
    * 730c2ab Add dummy file  # But `git show 730c2ab` includes the diffs between b89af06 and 93920f9 as well
    | * 93920f9 (HEAD) Uninteresting commit
    | * 91c7163 Uninteresting commit
    | * ce51022 Commit with the changed commit message
    |/
    * b89af06 Uninteresting commit
    

    请注意,除了 之外HEAD,现在没有任何内容指向此分支上的某些提交。

我很快得出结论,至少这种行为中的一些只是git svn. 当然,我在上面第 4 点看到的事情根本不应该发生,至少根据我的理解。

4

3 回答 3

2

git svn reset确实是正确的方法。假设 SVN 修订版 4711 已更改,步骤为:

1) 丢弃更改后的 SVN 修订版(以及之后的所有内容):

$ git svn reset -p 4711
r1 = 18614es3df44c30da07 (refs/remotes/git-svn)

2)获取更改的修订:

$ git svn fetch
rereading 18614es3df44c30da07 
        A       trunk/a
r4711 = 8dfb7d0758dbbc1d06004 (refs/remotes/git-svn)
        A       trunk/b
r4712 = e7337af3743e48c90ef3fa09906378b95997314c (refs/remotes/git-svn)
[...]

3) 现在 git-svn 的数据已修复。您仍然必须修理当地的分支机构。例如,如果 master 跟踪 SVN 中继,请运行:

git rebase remotes/git-svn

(其中“remotes/git-svn”是由创建的远程跟踪分支git svn- 它可能有不同的名称)。

这在git svn 手册页的“reset”子命令部分中得到了很好的解释。

于 2015-01-16T15:00:06.233 回答
2

git svn reset <revision-number>有效,但您必须指定一个早于有问题的提交的修订号,然后重新执行git svn fetch. 假设更改的提交是 R.100,git svn reset 99然后您需要这样做git svn fetch,只有这样才能重新获取新的更改提交。

至于您730c2ab包含 squashed of b89af06to的情况93920f9

 * 7b12bbc (origin/branchname) Remove dummy file
 * 730c2ab Add dummy file  # But `git show 730c2ab` includes the diffs 
     between b89af06 and 93920f9 as well
 | * 93920f9 (HEAD) Uninteresting commit
 | * 91c7163 Uninteresting commit
 | * ce51022 Commit with the changed commit message
 |/
 * b89af06 Uninteresting commit

git-svn 偶尔会在已更改的提交上执行此操作。我不确定具体细节,但我偶尔会遇到当 svn 上特定提交的工作副本自上次提取以来发生更改时,git svn 将在下一次提取时将更改与下一次提交一起压缩。要解决这个问题,可以重置到之前的commit,然后重新取回

编辑:

我之前没有注意到它ce51022已经与您的主分支分离。SVN 的分支方式不同,git-svn 将无法在 svn 上保留您的 git 分支。当您执行 git svn dcommit 或 git svn fetch/rebase 时,这也会导致压缩提交

于 2018-01-04T02:03:43.400 回答
0

如果你遇到和我一样的问题,可能是这个帮助文档中关于更新branches-maxrev 的说明引起的。

https://git-scm.com/docs/git-svn

“请注意,git-svn 会跟踪出现分支或标签的最高版本。如果分支或标签的子集在获取后发生更改,则必须手动编辑 $GIT_DIR/svn/.metadata 以删除(或重置) 适当的分支-maxRev 和/或标签-maxRev。”

在我的例子中,分支历史已经改变并且 reset 不够聪明,无法跨分支设置它以重新捕获修订,而是使用另一个分支的最高转速。

于 2019-04-16T12:44:22.297 回答