问题
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-id
s:
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?
回答1:
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:
- Create a temp branch to keep your current state (some kind of
backup):
git co -b backup
- 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).
来源:https://stackoverflow.com/questions/12571730/git-svn-id-is-missing-from-some-commits