简体   繁体   English

在历史Subversion修订版更改后修复git-svn存储库

[英]Repairing git-svn repository after historical Subversion revision changed

I use git-svn to keep a clone of a shared Subversion repository. 我使用git-svn来保存共享Subversion存储库的克隆。 Recently someone edited the commit message of a revision ( a la this SO question ) after I had git svn fetch ed that revision. 最近有人编辑的修订提交的信息( 一拉 这太问题 )我以后git svn fetch版那个版本。 How can I correct my Git clone to have the correct commit message? 如何更正我的Git克隆以获得正确的提交消息?

I had expected git svn reset followed by git svn fetch to refetch this commit and update things, leaving me to only need to fix up my local branches, but that doesn't actually seem to do anything; 我原本期望git svn reset然后是git svn fetch来重新获取这个提交并更新一些东西,让我只需要修复我的本地分支,但实际上并没有做任何事情; the git svn fetch doesn't refetch the commits I reset to. git svn fetch不会重新获取我重置的提交。

(Yes I think changing the commit message was a bad idea, but that's not something I have control over.) (是的,我认为更改提交消息是一个坏主意,但这不是我可以控制的。)

Update : I tried the process that sleske suggested (in fact, I'd tried it before asking the question, but I just tried again just in case), but with no luck. 更新 :我尝试了sleske建议的过程(事实上,我在问这个问题之前尝试过,但我只是为了以防再次尝试),但没有运气。 I get output like the below: 我得到如下输出:

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
$ 

There's no output from git svn fetch (or there is if there has been commits since I last ran it, but it's just fetching the new commits, not refetching the old ones), and in particular there's no rereading message as in sleske's example. git svn fetch没有输出(或者自从我上次运行以来就有提交,但它只是获取新提交,而不是重新提交旧提交),特别是没有像sleske的例子那样rereading读取消息。

In case it's relevant, I'm using Git v2.0.4. 如果相关,我使用的是Git v2.0.4。

Update 2 : Slightly redacted .git/config below: 更新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/*

I'll not post the full output of git branch -avv , because there's a lot of it, but that's where it gets really interesting, so I'll post a list of everything I did: 我不会发布git branch -avv的完整输出,因为它有很多,但这就是它真正有趣的地方,所以我会发布我做的所有事情的列表:

  1. I had a checkout of a branch other than the branch with the error. 我有一个除了分支以外的分支检查错误。 Running git svn reset made no difference: remotes/origin/branchname continued to point at a more recent commit. 运行git svn reset没有任何区别: remotes/origin/branchname继续指向更近期的提交。 Unsurprisingly, git svn fetch did nothing. 不出所料, git svn fetch什么也没做。

  2. I checked out remotes/origin/branchname and ran git svn reset again. 我检查了remotes/origin/branchname并再次运行git svn reset This worked: remotes/origin/branchname pointed at the parent of the duff commit. 这工作: remotes/origin/branchname指向duff commit的父级。

  3. I ran git svn fetch . 我跑了git svn fetch This did absolutely nothing: no commits were fetched and remotes/origin/branchname didn't move. 这绝对没有任何结果:没有提交任何提交,并且remotes/origin/branchname没有移动。

  4. I created a couple of dummy commits on that branch in the Subversion repository (one added an empty file, the next deleted it again), then ran git svn fetch again . 我在Subversion存储库中的那个分支上创建了几个虚拟提交(一个添加了一个空文件,然后再删除它),然后再次运行git svn fetch again

    Here's where it gets really odd: the duff commit wasn't refetched. 这里真的很奇怪:没有重新提交duff提交。 Instead, the fetch started at the commit where I added the dummy file, reported an "Index mismatch" in the process.Running git show on the commit that added the dummy file shows it with all the diffs between the commit I reset to and the dummy commit. 相反,提取开始于我添加虚拟文件的提交,在进程中报告了“索引不匹配”。在添加虚拟文件的提交上运行git show了我重置的提交与之间的所有差异虚拟提交。

    Now, running git log --graph --decorate --pretty=oneline --abbrev-commit HEAD origin/branchname looks like this: 现在,运行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 

    Note that, other than HEAD , there is now nothing pointing to some of the commits on this branch. 请注意,除了HEAD ,现在没有任何内容指向此分支上的某些提交。

I'm rapidly coming to the conclusion that at least some of this behaviour is simply a bug in git svn . 我很快得出结论,至少有一些这种行为只是git svn一个错误。 Certainly what I saw in point 4 above is not something that should happen at all, at least by my understanding. 当然,我在上面第4点看到的并不是应该发生的事情,至少我的理解是这样。

git svn reset is indeed the right way to do it. git svn reset确实是正确的方法。 Assuming SVN revision 4711 was changed, the steps are: 假设SVN修订版4711已更改,则步骤为:

1) Discard the changed SVN revision (and everything after it): 1)丢弃已更改的SVN修订版(及其后的所有内容):

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

2) Fetch the changed revision: 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) Now git-svn's data is repaired. 3)现在git-svn的数据被修复了。 You must still repair your local branches. 您仍然必须修复您当地的分支机构。 For example, if master tracks the SVN trunk, run: 例如,如果master跟踪SVN中继,请运行:

git rebase remotes/git-svn

(where "remotes/git-svn" is the remote-tracking branch created by git svn - it may have a different name). (其中“remotes / git-svn”是由git svn创建的远程跟踪分支 - 它可能有不同的名称)。

This is explained quite well in the git svn manpage , in the section on the "reset" subcommand. 这在git svn联机帮助页的“reset”子命令一节中有很好的解释。

git svn reset <revision-number> works, but you have to specify a revision number that is earlier than the offending commit, and then re-do git svn fetch . git svn reset <revision-number>有效,但您必须指定早于违规提交的修订号,然后重新执行git svn fetch Let's say the changed commit is R.100, you'll need to git svn reset 99 then do git svn fetch , only that will re-fetch the new changed commit. 假设更改的提交是R.100,你需要git svn reset 99然后执行git svn fetch ,只会重新获取新更改的提交。

As of your case of 730c2ab containing squashed of b89af06 to 93920f9 : 截至您的730c2ab包含压扁b89af0693920f9

 * 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 occasionally do that on commits that has changed. git-svn偶尔会在已经改变的提交上执行此操作。 I am not sure of the specifics, but I encountered occasionally when the working copy of a particular commit on the svn has changed since the last fetch, git svn will squash the changes together with the next commit on the next fetch. 我不确定具体细节,但是偶尔遇到自上次提取以来svn上特定提交的工作副本发生了变化时,git svn会将更改与下一次提取的下一次提交压缩在一起。 To solve this problem, you can reset to the previous commit, and re-fetch again 要解决此问题,您可以重置为上一次提交,然后重新获取

EDIT: 编辑:

I didn't notice previously that ce51022 is already detached from your main branch. 之前我没有注意到ce51022已经与主分支分离了。 SVN does branching differently and git-svn will not be able to persist your git branches on svn. SVN的分支方式不同,git-svn将无法在svn上保留你的git分支。 This will also result in squashed commit too when you do git svn dcommit or git svn fetch/rebase 当你执行git svn dcommit或git svn fetch / rebase时,这也会导致压缩提交

If you ran in to the same problem as me, it may be caused by the note on this help document about updating branches-maxrev. 如果您遇到与我相同的问题,可能是由此帮助文档中有关更新branches-maxrev的注释引起的。

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

"Note that git-svn keeps track of the highest revision in which a branch or tag has appeared. If the subset of branches or tags is changed after fetching, then $GIT_DIR/svn/.metadata must be manually edited to remove (or reset) branches-maxRev and/or tags-maxRev as appropriate." “请注意,git-svn会跟踪分支或标记出现的最高版本。如果在获取后更改了分支或标记的子集,则必须手动编辑$ GIT_DIR / svn / .metadata以删除(或重置)branches-maxRev和/或tags-maxRev视情况而定。“

In my case, the branch history had changed and reset wasn't smart enough to set it back across branches to have revisions re-captured, but instead was using the highest rev of another branch. 在我的情况下,分支历史记录已经改变,并且重置不够智能,无法将其重新设置为跨分支以重新捕获修订版,而是使用另一个分支的最高转速。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM