git “无法从工作树历史记录中确定上游 SVN 信息”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9805980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 06:39:09  来源:igfitidea点击:

"Unable to determine upstream SVN information from working tree history"

gitgit-svn

提问by ams

I'm trying to use the GCC git mirror, documented here.

我正在尝试使用 GCC git 镜像,记录在此处

Some time ago, I cloned the git repository:

前段时间克隆了git仓库:

git clone git://gcc.gnu.org/git/gcc.git

Added the git-svn stuff:

添加了 git-svn 的东西:

git svn init -Ttrunk --prefix=origin/ svn+ssh://gcc.gnu.org/svn/gcc

And then git svn rebaseand git svn dcommitetc. all worked nicely.

然后git svn rebasegit svn dcommit等所有的工作很好。

Some months later, I've done various development work on local git branches, and I've come to commit more changes to upstream SVN:

几个月后,我在本地 git 分支上完成了各种开发工作,并且我开始对上游 SVN 进行更多更改:

  1. Update from the git miror:

    $ git rebase
    
  2. Ensure I have the absolute latest from SVN, but it doesn't work:

    $ git svn rebase -v
    Unable to determine upstream SVN information from working tree history
    
  1. 从 git 镜像更新:

    $ git rebase
    
  2. 确保我拥有 SVN 的绝对最新版本,但它不起作用:

    $ git svn rebase -v
    Unable to determine upstream SVN information from working tree history
    

Somehow I've broken the meta data! As well as the above, I think I did git svn fetchat some point, by mistake, but that shouldn't be harmful, should it?

我以某种方式破坏了元数据!除了上述内容,我想我git svn fetch在某个时候错误地做了,但这不应该是有害的,不是吗?

So, I tried creating a fresh branch from the remote git mirror:

因此,我尝试从远程 git 镜像创建一个新分支:

$ git branch svntrunk remotes/origin/trunk
$ git checkout svntrunk
$ git svn rebase
Unable to determine upstream SVN information from working tree history

A web search suggests that the branch history has somehow diverged from SVN, but I've checked git logand every commit has a corresponding git-svn-id, which seems to disprove that, no?

网络搜索表明分支历史记录以某种方式与 SVN 不同,但我已经检查过git log并且每个提交都有一个相应的git-svn-id,这似乎反驳了这一点,不是吗?

So, I tried a fresh clone from git://gcc.gnu.org/git/gcc.git, and in that repository git svn rebaseworks fine. How can the two repos, in which both have had git rebasefrom the same source, have different history? Presumably they can't, and the difference is in the local meta-data?

所以,我尝试了一个来自 git://gcc.gnu.org/git/gcc.git 的新克隆,并且在该存储库中git svn rebase工作正常。这两个git rebase来自同一来源的repos 怎么会有不同的历史?大概他们不能,区别在于本地元数据?

Now, I don't want to trash the repo that I've been working in (although I could), and exporting the patches to another repo to commit defeats the point of having git-svn in the first place. So, how can I repair it?

现在,我不想破坏我一直在使用的 repo(尽管我可以),并且将补丁导出到另一个 repo 以提交首先破坏了拥有 git-svn 的意义。那么,我该如何修复呢?

采纳答案by Tom Kerr

You should be able to do this with a graft. Grafting is designed to be used for bringing in legacy repositories is my understanding. It lets you manuallytell git that some ref has a common parent.

您应该可以通过移植来做到这一点。我的理解是嫁接旨在用于引入遗留存储库。它让你手动告诉 git 某些 ref 有一个共同的父级。

As mentioned in the comments, there may be a simpler solution. This would work if all else failed though.

正如评论中提到的,可能有一个更简单的解决方案。如果所有其他方法都失败了,这将起作用。

You'd pull down the current git repo (either with git or git-svn) and add your old git-svn repo as a remote. They won't be related, so gitk will look like this:

您将拉下当前的 git 存储库(使用 git 或 git-svn)并将旧的 git-svn 存储库添加为远程。它们不会相关,因此 gitk 将如下所示:

unrelated ancestry

不相关的血统

I had an incident at work where we had some do a file system copy instead of an svn copy, so some of my branch names allude to that. Hopefully it all makes sense anyway. Pretty lucky that I just happen to have all these images and story. What are the chances!? Probably pretty good, git-svn is easily confused.

我在工作中遇到了一个事件,我们让一些人做文件系统副本而不是 svn 副本,所以我的一些分支名称暗示了这一点。希望这一切都有意义。很幸运,我恰好拥有所有这些图像和故事。有什么机会!?可能还不错,git-svn 很容易混淆。

naming branches

命名分支

The copied_from branch is where they copied from. The graft_ref is where this met up. They had added a bunch of files, changes properties, and then changed some of the files. It was a bit of a mess.

copy_from 分支是他们复制的地方。嫁接参考是这相遇的地方。他们添加了一堆文件,更改了属性,然后更改了一些文件。这有点混乱。

The general idea is to get the index of the original source, but the file contents to match the modifications. So we start in the ref branch, then reset mixed to get the index.

大体思路是获取原始源的索引,但是文件内容要匹配修改。所以我们从ref分支开始,然后reset mix得到索引。

$ git checkout graft_ref
$ git checkout -b graft_parent
$ git reset --mixed copied_from

reset mixed

重置混合

If you didn't make changes between the two branches when it was broken, then you shouldn't have to worry about this step.

如果在断掉的时候两个分支之间没有做改动,那么这一步就不用担心了。

$ git commit -a -m "svn_branch changes made on svn_trunk filesystem copy"

Now we need to do the actual graft. I trimmed the hashes here for readability.

现在我们需要做实际的移植。我在这里修剪了哈希值以提高可读性。

$ git log -1 --pretty=format:%H graft_ref
631d3c84e35de98236c3d36c08d14ec92f9c62ae
$ git log -1 --pretty=format:%H graft_parent
96a4e87b554e0030035d35ca3aac23e9d71962af
$ echo "631d3... 96a4e8..." > .git/info/grafts

grafted

嫁接的

Which looks about how you would expect. Now we just need to rebase the changes up the tree. My notes are missing for this, but I think this is what I would have done, hehe.

这看起来与您的期望有关。现在我们只需要重新调整树上的更改。我的笔记为此丢失了,但我认为这是我会做的,嘿嘿。

$ git checkout svn_branch/master
$ git checkout -b consolidate_changes

consolidated

综合

$ git rebase master

rebase

变基

You should be able to push these changes where ever. Grafts are not tracked by git though, so the grafted branch (svn_branch/master and friends) will break again. It is effectively a dead tree unless you do the graft again. For git-svn this isn't much of an issue because you just commit changes and then pull the source down again as a clean copy.

您应该能够随时随地推动这些更改。尽管 git 不跟踪嫁接,因此嫁接的分支(svn_branch/master 和朋友)将再次中断。除非您再次进行嫁接,否则它实际上是一棵死树。对于 git-svn,这不是什么大问题,因为您只需提交更改,然后再次将源作为干净的副本拉下来。

回答by iwein

The simplest thing that might work is to run git svn fetch. If you re-attach an existing git repo to svn, you'll get this error for no good reason when you git svn rebase. Underlying problem is that git-svn makes assumptions about the state of your repo that don't always hold if you didn't start from a clean svn clone.

可能有效的最简单的方法是运行git svn fetch. 如果您将现有的 git 存储库重新附加到 svn,当您使用git svn rebase. 潜在的问题是 git-svn 对你的 repo 状态做出假设,如果你不是从一个干净的 svn 克隆开始,这些假设并不总是成立。

The next option is to backup master git branch master-bkp. And then run git reset --hard <way-back>. Then run git svn rebase.

下一个选项是备份 master git branch master-bkp。然后运行git reset --hard <way-back>。然后运行git svn rebase

Only if you're working on a git repo that you can in no way attach back to svn in a normal way, you can try grafting. Grafting is clever and complex, but possible. It's also hard to do right, easy to screw up, and verytime consuming. Not recommended as a first option.

只有当您正在处理一个无法以正常方式附加回 svn 的 git 存储库时,您才可以尝试嫁接。嫁接既聪明又复杂,但也是可能的。它也很难做对,容易搞砸,而且非常耗时。不推荐作为第一选择。

回答by MrGomez

This is a fairly common scenario. I, too, have run into this when attempting to synchronize my newer Git repositories against my older, SVN-backed data store.

这是一个相当普遍的场景。当我尝试将我的新 Git 存储库与我的旧的 SVN 支持的数据存储同步时,我也遇到了这个问题。

The secret is to keep SVN consistent with the working master branch in Git. The common commands to do so are, as you mentioned, git svn rebase(to unwind your changes and synchronize back with SVN) and git reset --hard(to perform a hard rollback to a previous revision when your internal index is in an inconsistent state). It took a great deal of searching to root this procedure out for me. (Take a backup copy before you perform either of these.)

秘诀是让 SVN 与 Git 中工作的 master 分支保持一致。正如您所提到的,执行此操作的常用命令是git svn rebase(展开您的更改并与 SVN 同步)和git reset --hard(当您的内部索引处于不一致状态时执行硬回滚到先前的修订版)。花了大量的时间为我找出这个程序。(在执行其中任何一项之前,请备份副本。)

The reason this appears to happen is Git becomes deeply confused when you manage two or more change histories simultaneously against the same working branch, which should be HEADby default. If something changes in the upstream SVN repository and downstream change histories that Git cannot reconcile, it loses its place and throws the error you've listed above.

出现这种情况的原因是当您针对同一个工作分支同时管理两个或多个更改历史时,Git 会变得非常困惑HEAD,默认情况下应该是这样。如果上游 SVN 存储库和下游更改历史发生了 Git 无法协调的变化,它就会失去位置并抛出您在上面列出的错误。

This problem is additionally addressed here. As mentioned in the top answer, you'll want to rule out the possibility that your version of git needs to be upgraded and attempt the fixes they've recommended, as well.

此问题在此处另外解决。正如顶级答案中提到的,您需要排除您的 git 版本需要升级并尝试他们推荐的修复程序的可能性。