我正在尝试使用GCC git镜像,记录为here。
前一段时间,我克隆了git存储库:
git clone git://gcc.gnu.org/git/gcc.git
添加了git-svn的东西:
git svn init -Ttrunk --prefix=origin/ svn+ssh://gcc.gnu.org/svn/gcc
然后git svn rebase
和git svn dcommit
等都很好用。
几个月后,我在本地git分支上完成了各种开发工作,并且我已经对上游SVN做出了更多的更改:
从git miror更新:
$ git rebase
确保我拥有SVN的最新版本,但不起作用:
$ git svn rebase -v
Unable to determine upstream SVN information from working tree history
不知何故,我打破了元数据!除了上述内容之外,我认为我错误地在某个时刻做过git svn fetch
,但这不应该是有害的,是吗?
所以,我尝试从远程git镜像创建一个新的分支:
$ git branch svntrunk remotes/origin/trunk
$ git checkout svntrunk
$ git svn rebase
Unable to determine upstream SVN information from working tree history
网络搜索表明分支历史记录在某种程度上偏离了SVN,但我检查了git log
并且每个提交都有相应的git-svn-id
,这似乎反驳了这一点,没有?
所以,我尝试了一个来自git://gcc.gnu.org/git/gcc.git的新克隆,并在该存储库中git svn rebase
正常工作。两个来自同一来源的git rebase
的回购有哪些历史记录?据推测他们不能,而区别在于本地的元数据?
现在,我不想废弃我一直在工作的回购(尽管我可以),并将修补程序导出到另一个回购提交失败了首先使用git-svn。那么,我该如何修复呢?
答案 0 :(得分:12)
你应该能够用移植物做到这一点。嫁接旨在用于引入遗留存储库是我的理解。它允许你手动告诉git某些ref有一个共同的父。
正如评论中所提到的,可能有一个更简单的解决方案。如果所有其他方法都失败了,这将有效。
你可以下载当前的git repo(使用git或git-svn)并将旧的git-svn repo添加为远程。它们不相关,所以gitk看起来像这样:
我在工作中遇到了一些事件,我们有一些文件系统副本而不是svn副本,因此我的一些分支名称暗示了这一点。无论如何,希望这一切都有意义。很幸运,我碰巧拥有所有这些图像和故事。有什么机会!?可能相当不错,git-svn很容易混淆。
copied_from分支是他们从中复制的地方。 graft_ref就是这里遇到的地方。他们添加了一堆文件,更改了属性,然后更改了一些文件。这有点乱。
一般的想法是获取原始源的索引,但文件内容与修改匹配。所以我们从ref分支开始,然后重置混合以获得索引。
$ git checkout graft_ref
$ git checkout -b graft_parent
$ git reset --mixed copied_from
如果两个分支在断开时没有进行更改,那么您不必担心这一步。
$ git commit -a -m "svn_branch changes made on svn_trunk filesystem copy"
现在我们需要做实际的移植。为了便于阅读,我在这里修剪了哈希。
$ git log -1 --pretty=format:%H graft_ref
631d3c84e35de98236c3d36c08d14ec92f9c62ae
$ git log -1 --pretty=format:%H graft_parent
96a4e87b554e0030035d35ca3aac23e9d71962af
$ echo "631d3... 96a4e8..." > .git/info/grafts
看看你会怎么想。现在我们只需要修改树上的更改。我的笔记因此缺失,但我认为这就是我本来会做的,呵呵。
$ git checkout svn_branch/master
$ git checkout -b consolidate_changes
$ git rebase master
你应该能够将这些变化推向何方。虽然git没有跟踪移植,但是移植的分支(svn_branch / master和friends)会再次中断。除非你再次进行移植,否则它实际上是一棵死树。对于git-svn来说,这不是什么大问题,因为你只是提交了更改,然后再次将源拉下来作为一个干净的副本。
答案 1 :(得分:3)
这是一种相当常见的情况。我也尝试将我的新Git存储库与我的旧的SVN支持的数据存储同步。
秘诀是让SVN与Git中的工作主分支保持一致。正如您所提到的,执行此操作的常用命令是git svn rebase
(用于展开更改并与SVN同步)和git reset --hard
(在内部索引处于执行状态时执行硬回滚到先前的修订)不一致的状态)。我需要进行大量的搜索才能找到这个程序。 (在执行其中任何一项之前,请先备份一份。)
出现这种情况的原因是当您同时针对同一工作分支管理两个或更多变更历史时,Git会变得非常困惑,默认情况下该分支应为HEAD
。如果上游SVN存储库中的某些内容发生变化,而Git无法协调下游更改历史记录,则会失去其位置并抛出您在上面列出的错误。
另外解决了这个问题here。正如在最佳答案中所提到的,您将要排除您的git版本需要升级并尝试他们推荐的修补程序的可能性。
答案 2 :(得分:3)
最简单的方法是运行git svn fetch
。如果您将现有的git repo重新附加到svn,那么当您git svn rebase
时,您将无缘无故地收到此错误。潜在的问题是,如果你没有从一个干净的svn克隆开始,git-svn会假设你的repo状态并不总是成立。
下一个选项是备份主git branch master-bkp
。然后运行git reset --hard <way-back>
。然后运行git svn rebase
。
只有当你正在使用git repo,你才能以正常方式附加回svn时,你可以尝试嫁接。嫁接既聪明又复杂,但可能。它也很难做正确,容易搞砸,而且非常耗费时间。不推荐作为第一选择。