3

I have an old SVN repository that I checked out using git-svn in order to work on it and push to Heroku. I was doing a pretty standard git push heroku master, git svn rebase, git svn dcommit dance and things were fine.

However, recently I've been doing a fair bit of git work and hadn't done a git svn rebase in a while. Now when I try to do a rebase it fails because of merge conflicts, despite me being the only person committing to the repo and only working on master.

Figuring that it might be the working copy that's the problem I did a new git svn clone and then a git remote add heroku and git pull heroku master. The pull does a fast-forward merge with no problems, but git svn rebase still fails.

I did a simple git log and I see that I have some old commits missing git-svn-ids:

commit def8bab861314c67d4e8227e03775d19045d21d1
Author: peterr
Date:   Fri Sep 21 16:17:33 2012 +0000

    PHP Cedar support.

    git-svn-id: http://vcp.unfuddle.com/svn/vcp_bbsit@24 b6b24ac3-8b7a-4c11-a811-49c5d0334e85

commit f51bd78fb07dde6ec1dc4e0ba51a48f2b6bd1bd6
Author: pr1001
Date:   Mon Aug 20 19:39:42 2012 +0200

    Specify port correctly

commit 153bb2929080898dcab46142120def0f4964dfab

...

commit 5a416fa3af9f64aa353d5171bedfaa563115ff62
Author: pr1001
Date:   Mon Aug 20 17:22:58 2012 +0200

    PHP Cedar support.

commit e0b35588d03082a3a4ab49a7b590f206346046c0
Author: j
Date:   Fri Aug 3 08:13:33 2012 +0000

    change email

    git-svn-id: http://vcp.unfuddle.com/svn/vcp_bbsit@23 b6b24ac3-8b7a-4c11-a811-49c5d0334e85

From an SO answer I gather that I might be able to rewrite the commit messages to add the missing information, but I wonder whether that wouldn't be even worse.

Looking at the messages, it looks like I have some duplicate commits, such as the 'PHP Cedar support' one. I'm really perplexed why I have these duplicates, though I suspect that they may be relayed to the failed git push heroku master I had the other day in which I was told the repositories were out of sync. git pull heroku master seemed to bring in absolutely no changes and fixed the issue, but perhaps it brought in the duplicate commits.

So, given all this my question is simply, how might I proceed? I have a working app on Heroku and an older working code base in the SVN repo, but I don't see any easy way how to cleanly get the newer commits into SVN. Should I cherry-pick them? Would I then need to nuke the Heroku app in order to not have the duplicates come back?

Community
  • 1
  • 1
pr1001
  • 21,727
  • 17
  • 79
  • 125

1 Answers1

4

It's not easy to guess how you got into this situation, but I think this is because when pushing to SVN git-svn replaces (using rebase or reset) commits with git-svn-id signature so there're 2 exemplars of each commits: "local" -- without "git-svn-id" signature --- and remote with the signature.

To recover:

  1. Create a temp branch to keep your current state (some kind of backup): git co -b backup
  2. Make sure that refs/remotes/git-svn points to the latest commit with git-svn-id corresponding to your subversion repository and there's no commits without git-svn-id are shown by git log refs/remotes/git-svn

If this is not true, you may use the following trick to repair refs/remotes/git-svn: update refs/remotes/git-svn to point to the latest commit where everything was ok (in your situation it corresponds to r23):

$ git update-ref refs/remotes/git-svn e0b35588d03082a3a4ab49a7b590f206346046c0

Set .git/svn/metadata revisions to point to that revision:

[svn-remote "svn"]
        reposRoot = ...
        uuid = <UUID>
        branches-maxRev = 23
        tags-maxRev = 23

Remove (or better move away) file .git/svn/refs/remotes/git-svn/.rev_map.UUID Now run

$ git svn fetch

Your refs/remotes/git-svn reference is now restored to the latest valid SVN revision.

3 . Get all changes from the Git repository without merging

$ git fetch heroku master

Now all your changes are in refs/remotes/heroku/master.

4 . Make sure you have no local changes (I suggest you're on master now). Reset refs/heads/master to refs/remotes/git-svn. One of the ways to do that:

$ git update-ref refs/heads/master refs/remotes/git-svn
$ git reset --hard HEAD

5 . Have a look at refs/remotes/heroku/master and at refs/remotes/git-svn. Are there changes in the Git repository that are not present in refs/remotes/git-svn? If yes, cherry-pick them one-by-one. Also have a look at your backup branch (only at commits without git-svn-id), if they are not in SVN yet, cherry-pick them too.

6 . Now you have some changes in master that are not in SVN yet. Run

$ git svn dcommit

to push them to SVN.

7 . Now your SVN-related branch is fully repaired and has all the changes. If I understand correctly, you want the same content in the Git repository. Better replace refs/remotes/heroku/master with current master contents:

$ git push heroku master --force

Now your Git repository has the same contents as SVN repository.

To avoid these problems in future make sure that you never push commits without git-svn-id to Git (i.e. that when you run "git push" your master consists of commits with git-svn-id signatgures only -- if not -- run "git svn dcommit" to push them to SVN first).

Dmitry Pavlenko
  • 8,530
  • 3
  • 30
  • 38
  • 1
    I had a completely different issue, but this gave me the info I needed about git-svn to fix it. Thanks! :) – Doug Paul Dec 17 '13 at 04:25