description | Detect SVN merges from their commit messages and re-create the merges in the Git side. |
homepage URL | http://tsunanet.net/ |
owner | tsuna@lrde.epita.fr |
last change | Tue, 22 Jan 2008 12:53:57 +0000 (22 13:53 +0100) |
URL | git://repo.or.cz/svn-merge2git.git |
| https://repo.or.cz/svn-merge2git.git |
push URL | ssh://repo.or.cz/svn-merge2git.git |
| https://repo.or.cz/svn-merge2git.git (learn more) |
bundle info | svn-merge2git.git downloadable bundles |
content tags
|
|
readme
This script can be used to import merges you've done on the SVN side to the Git side. It's especially useful when you're in process of converting a SVN repo to Git and you want to recreate a history similar to that of SVN. Alas, SVN does not record merges in any way so it's far from trivial to recover them on the Git side. This script assumes that you have been well behaved and that you always mentionned which revisions from which branch were merged. It uses one RE (RegExp) to match these commits from their commit messages (possibly excluding false positives with other REs) and then rewrites the entire history of your repo to add the merges detected in Git. Obviously, this requires that you've always formatted your merge commit messages in a similar way, but in practice this is common. Indeed, people often use scripts to diminish the pain of the famous "SVN merge hell". These scripts tend to record metadata as to what has been merged when. And they often generate the commit message which contains which revisions are being merged from which branch.
Full SVN to Git conversion, step by step:
git svn clone -s repo
- Repack:
git gc --prune --aggressive
- Rename all the remote SVN branches to local Git branches:
cd .git
mv refs/remotes/tags/* refs/tags/
mv refs/remotes/* refs/heads/
sed -i 's|refs/remotes/tags/|refs/tags/|;s|refs/remotes/|refs/heads/|' packed-refs
- Optionnaly: Rename the `trunk' branch to `master'
Make sure that git-svn created the `master' branch correctly.
Normally it should initialize it to SVN's `trunk' but I've seen cases
where it does not. Then issue
git branch -d trunk
- Convert SVN merges to Git merges:
svn-merge2git.sh --all --verbose --prune
. You might need to tweak the first few variables ($merge_pattern
, $exclude_pattern
and $log_exclude_pattern
). If the script could not find the parent of some merge commits, it will print them before re-writing the entire history and ask you whether it should continue or not. I suggest you tell it not to continue and have a look at each of the problematic commit and then invoke the script again with the proper --merge
arguments to manually indicate the merge points. For instance, if the script complains that it couldn't figure out the parent of the merge commit f309a61
, look at this commit with git show
and note down the SVN revision and branch that are being merged by this commit and re-invoke the script with --merge f309a61:51:branches/1.0
(if you found out that commit f309a61
was merging -r42:51
from the branch 1.0
)
- Get ready to re-distribute the repo:
git config core.bare true
git config core.sharedRepository true # Use this if needed (e.g. you use gitosis)
rm -f .git/{index,gitk*,qgit*,*_HEAD,BISECT_*,COMMIT_*}
mv .git ../repo.git
cd ..
rm -rf repo
cd repo.git
sed '/refs\/remotes/d' -i packed-refs
rm -rf refs/remotes/origin
git reflog expire --expire=0 --all
git gc --prune
- Now you're ready to distribute
repo.git
!
Send {comments,suggestions,bugs,feature requests,patches} to <tsuna at lrde dot epita dot fr>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-3285392-1");
pageTracker._initData();
pageTracker._trackPageview();
</script>