Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

git-svn

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

Some time ago, I cloned the git repository:

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

Added the git-svn stuff:

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

And then git svn rebase and git svn dcommit etc. all worked nicely.

Some months later, I've done various development work on local git branches, and I've come to commit more changes to upstream 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
    

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

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

$ 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 log and every commit has a corresponding git-svn-id, which seems to disprove that, no?

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

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?

like image 644
ams Avatar asked Mar 21 '12 13:03

ams


1 Answers

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 manually tell git that some ref has a common parent.

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:

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.

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.

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.

$ 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.

like image 107
Tom Kerr Avatar answered Sep 22 '22 21:09

Tom Kerr