#!/bin/bash NEWSVNURL="file:///home/colin/svn-git/soft" SOFTWARE= if [ -d ".git" -a -f ".git/config" -a -f ".git/svn/.metadata" ]; then SOFTWARE=$(grep "fetch = " .git/config | cut -d'=' -f2- | cut -d':' -f1 | sed 's,/trunk,,' | trim) fi if [ -z "$SOFTWARE" ]; then echo "You must run this in a git-svn clone folder." >&2 exit 1 fi if [ -d ../$SOFTWARE.git ]; then echo "It seems the converted git repository already exists (../$SOFTWARE.git)" exit 1 fi echo -n "Finding UUID for SVN Repository $NEWSVNURL... " NEWSVNUUID=$(svn info $NEWSVNURL | grep "^Repository UUID:" | sed 's/Repository UUID: //') echo $NEWSVNUUID echo -n "Updating SVN Remote config (old value: $(git config svn-remote.svn.url))... " git config svn-remote.svn.url $NEWSVNURL echo "done" echo -n "Updating Internal SVN metadata... " sed -i "s,reposRoot = .*$,reposRoot = $NEWSVNURL,;s,uuid = .*$,uuid = $NEWSVNUUID," .git/svn/.metadata echo "done" echo echo "OK now the fun stuff beings. You need to find the git commit at which you want to" echo "start the magiea import. This will typically require some investigation but the" echo "date will be around February 2011." echo "I will drop you to a shell. When you are done, simply copy the SHA1 sum and exit." echo "The commands you like want are 'git log trunk' and 'git show SHA1'" echo echo "Press any key to contiue." read -n 1 bash echo echo "OK you're back :)" echo "What was the SHA1?" read resetsha1 if [ -z "$resetsha1" ]; then echo "You did not give any SHA1 sum. I will not reset the git repository and carry on importing" echo "from it's current state. You can quit this script and start again if this is incorrect." else echo "I got SHA1 '$resetsha1'. I hope that's correct". echo echo "I will now reset your git trunk and master branches. Is this OK? (press ctrl+c if not)" read -n 1 git update-ref -m "Rewind SVN Git to pre-Magiea import" refs/remotes/trunk $resetsha1 git checkout master git reset --hard trunk fi echo echo "I will now run 'svn log' on the software. You should be able to guess the right revision" echo "to base the import on. When done, simply copy (or remember) the revision number and enter it" echo "into this script." echo echo "Press any key to contiue." read -n 1 svn log $NEWSVNURL/$SOFTWARE | less echo echo "OK you're back :)" echo "What was the revision number?" read revision revision=$(( $revision + 0 )) echo "I got revision '$revision'. I hope that's correct". echo echo "The next step is the dangerous bit. We will clear out all files in the current" echo "working copy, run an svn export and then drop you to a shell to investigate the differences" echo "In that shell you must git add any new files that appear and ensure you are happy with" echo "the generate state of things." echo echo "Continue? (press ctrl+c if not)" read -n 1 git reset --hard trunk resetsha1=$(git rev-list --max-count=1 HEAD) # The below is a "safer" verion of rm -rf * that also deletes hidden files find . -depth -not -iwholename '.' -not -iwholename "./.git" -not -iwholename "./.git/*" -not -iwholename "./.git/.*" -delete svn export --force --ignore-keywords --ignore-externals -r $revision $NEWSVNURL/$SOFTWARE/trunk . echo echo "Dropping you to a shell. Use 'git status', 'git diff' and 'git add'." echo "DO NOT run 'git commit', I'll do that later for you." bash echo echo "OK you're back :)" echo "If everything is OK, and you're ready to continue, then hit return." read -n 1 COMMITTXT=$(mktemp /tmp/commitmsg.XXXXXX) cat >$COMMITTXT <>$COMMITTXT COMMITDATE=$(svn log -r $revision $NEWSVNURL/$SOFTWARE | head -n2 | tail -n1| cut -d'|' -f3 | cut -d'(' -f1 | trim) git commit --author="Mageia SVN-Git Migration " --date="$COMMITDATE" --file=$COMMITTXT -a rm -f $COMMITTXT echo echo "OK, looks like we're good to go :)" echo "Press any key to continue with the subversion import process". read -n 1 git svn gc sha1=$(git rev-list --max-count=1 HEAD) echo echo -n "Updating trunk branch to include synthesised commit $sha1... " git update-ref -m "Reset to synthesized commit representing Magiea cleaned import (SVN Git)" refs/remotes/trunk $sha1 echo "done" echo -n "Faking git-svn metadata to allow continuation... " printf "0000000: %08x%s\t................" $revision $sha1 | xxd -r -c24 >.git/svn/refs/remotes/trunk/.rev_map.$NEWSVNUUID echo "done" # Keep a small log of the sha1's etc. if [ ! -f ../svn-import.log ]; then echo "software,startingcommit,startingrevision,fakecommit" >../svn-import.log fi echo "drakx,$resetsha1,$revision,$sha1" >>../svn-import.log echo "Continuing svn fetch" git svn fetch -A ../authors-transform.txt -r $(( $revision + 1 )):HEAD git reset --hard trunk echo echo "done" echo echo "Now creating bare git repository" git init --bare ../$SOFTWARE.git git remote rm origin git remote add origin ../$SOFTWARE.git #git push --set-upstream master git push origin master 'refs/remotes/*:refs/heads/*' pushd ../$SOFTWARE.git git branch -D trunk git branch -D origin/master git for-each-ref --format='%(refname)' refs/heads/tags | cut -d / -f 4 | \ while read ref; do git tag "$ref" "refs/heads/tags/$ref" git branch -D "tags/$ref" done git gc --aggressive popd