tags:

views:

141

answers:

2

A SVN repo I use git-svn to track was recently corrupted and a backup was recovered. However, a week's worth of commits were lost in the recovery. Is it possible to recover those lost commits using git-svn dcommit on my local git repo? Is it sufficient to run git-svn dcommit with the SHA1 of the last recovered commit in SVN? eg.

> svn info http://tracked-svn/trunk | sed -n "s/Revision: //p"
252
> git log --grep="git-svn-id:.*@252" --format=oneline | cut -f1 -d" "
55bb5c9cbb5fe11a90ec2e9e1e0c7c502908cf9a
> git svn dcommit 55bb5c9cbb5fe11a90ec2e9e1e0c7c502908cf9a

Or will the git-svn-id need to be stripped from the intended commits?

I tried this using --dry-run but couldn't tell whether it would try to submit all commits:

> git svn dcommit --verbose --dry-run 55bb5c9cbb5fe11a90ec2e9e1e0c7c502908cf9a
Committing to http://tracked-svn/trunk ...
dcommitted on a detached HEAD because you gave a revision argument.
The rewritten commit is: 55bb5c9cbb5fe11a90ec2e9e1e0c7c502908cf9a

Thanks for your help.

+1  A: 

Not a complete answer, but that thread may explain a bit the error message:

'git svn dcommit' takes an optional revision argument, but the meaning of it was rather scary.
It completely ignored the current state of the HEAD, only looking at the revisions between SVN and $rev.
If HEAD was attached to $branch, the branch lost all commits $rev..$branch in the process.

Considering that 'git svn dcommit HEAD^' has the intuitive meaning "dcommit all changes on my branch except the last one", we change the meaning of the revision argument.
git-svn temporarily checks out $rev for its work, meaning that:

  • if a branch is specified, that branch (not the HEAD) is rebased as part of the dcommit,
  • if some other revision is specified, as in the example, all work happens on a detached HEAD and no branch is affected.

I am not sure if that patch has been integrated in version Git, but if you test your dcommit, make sure to git branch -b after the dcommit, to reference the current HEAD with a branch.
Will it work on the SVN side? I don't know.

VonC
A: 

Here is how I achieved what I wanted:

  1. Re-cloned http://tracked-svn/trunk in a fresh git-svn repo.
  2. Added my old git-svn repo as a remote to the fresh repo. (eg. git remote add -f up-to-date /path/to/repo)
  3. git merge remotes/up-to-date/master
  4. git svn dcommit

Rebasing on my old repo gives no errors, and dcommit works as expected.

This might not be the best way to recover commits, but it got me what I wanted.

Ian Stevens