Today we changed the URL of our Subversion server at work to a new domain. Subversion and TortoiseSVN offer a separate relocate command for that, which basically updates the local working copy metadata.
Not so for Git. Git keeps SVN metadata in two places: the commit log messages themselves which hold a git-svn-id entry for all commits that have been pushed to SVN, and in the .git/config file.
commit e82751b4872142679ba61e26fc0c57e97c698e8f
Author: agross
Date: Thu Jun 25 16:44:55 2009 +0000
Adding FxCop to the code quality task
git-svn-id: https://your.svn-server/svn/Crimson/trunk@67 8ed4a44c-bfb4-4748-a28a-fad9255c4788
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
ignorecase = true
[svn-remote "svn"]
url = https://your.svn-server/svn/Crimson/trunk
fetch = :refs/remotes/git-svn
To update the SVN URL it’s required to update the Git configuration file (an easy edit) and also to rewrite the commit log messages, updating the values of git-svn-id to reflect the new SVN server URL. The latter can be achieved with the git-filter-branch command which allows you to dissect the project history in interesting ways.
Having several local Git repositories to update, I went for the scripted solution. I found this article on how to change the SVN repository URL and added some scripting goodness to it (aside from fixing the syntactic errors). It worked pretty good for my ~10 repositories.
- You pass two arguments:
- The old SVN URL, i.e. http://old.server
- The new SVN URL, i.e. https://new.server
- The old URL will be matched against
git-svn-id entries with a regular expression, and the matched parts get replaced with the new URL.
- Rewrite the commit log messages, thus updating
git-svn-id
- Create a backup copy of .git/config
- Replace the old SVN URL in .git/config
- Delete all metadata Git has aquired about SVN
- Rebase against SVN, recreating the SVN metadata
#!/bin/sh
# Must be called with two command-line args.
# Example: git-svn-relocate.sh http://old.server https://new.server
if [ $# -ne 2 ]
then
echo "Please invoke this script with two command-line arguments (old and new SVN URLs)."
exit $E_NO_ARGS
fi
# Prepare URLs for regex search and replace.
oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'`
newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'`
filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\""
git filter-branch --msg-filter "$filter" -- --all
sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config
rm -rf .git/svn
git svn rebase