我使用git-svn来保存共享Subversion存储库的克隆。最近有人编辑了修订版(la this SO question)的提交消息,之后我对git svn fetch
ed进行了修订。如何更正我的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
没有输出(或者自从我上次运行以来就有提交,但它只是获取新提交,而不是重新提交旧提交),特别是在sleske的例子中没有rereading
消息。
如果相关,我使用的是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
的完整输出,因为它有很多,但这就是它真正有趣的地方,所以我会发布我所做的一切列表:
git svn reset
没有任何区别:remotes/origin/branchname
继续指出最近的提交。不出所料,git svn fetch
什么也没做。remotes/origin/branchname
并再次运行git svn reset
。这有效:remotes/origin/branchname
指出了duff提交的父母。git svn fetch
。这绝对没有任何结果:没有提交任何提交,remotes/origin/branchname
没有移动。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点看到的并不是应该发生的事情,至少我的理解是这样。
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 manpage中,在“reset”子命令一节中对此进行了很好的解释。
git svn reset <revision-number>
工作,但您必须指定一个早于违规提交的修订号,然后重新执行git svn fetch
。假设更改的提交是R.100,您需要git svn reset 99
然后执行git svn fetch
,只会重新获取新更改的提交。
从你的730c2ab
包含压缩b89af06
到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会将更改与下一次提取的下一次提交压缩在一起。要解决此问题,您可以重置为上一次提交,然后重新获取
编辑:
之前我没有注意到ce51022
已经脱离了你的主要分支。 SVN的分支方式不同,git-svn将无法在svn上保留你的git分支。当你执行git svn dcommit或git svn fetch / rebase时,这也会导致压缩提交
如果您遇到与我相同的问题,可能是由此帮助文档中有关更新branches-maxrev的注释引起的。
https://git-scm.com/docs/git-svn
“请注意,git-svn会跟踪分支或标记出现的最高版本。如果在获取后更改了分支或标记的子集,则必须手动编辑$ GIT_DIR / svn / .metadata以删除(或重置)branches-maxRev和/或tags-maxRev视情况而定。“
在我的情况下,分支历史记录已经改变,并且重置不够智能,无法将其重新设置为跨分支以重新捕获修订版,而是使用另一个分支的最高转速。