git-svn: what's the equivalent to `svn switch --relocate`?

20,121

Solution 1

This handles my situation pretty well:

https://git.wiki.kernel.org/index.php/GitSvnSwitch

I cloned using the file:// protocol, and wanted to switch to the http:// protocol.

It is tempting to edit the url setting in the [svn-remote "svn"] section of .git/config, but on its own this does not work. In general you need to follow the following procedure:

  1. Switch the svn-remote url setting to the new name.
  2. Run git svn fetch. This needs to fetch at least one new revision from svn!
  3. Change the svn-remote url setting back to the original URL.
  4. Run git svn rebase -l to do a local rebase (with the changes that came in with the last fetch operation).
  5. Change the svn-remote url setting back to the new URL.
  6. Now, git svn rebase should work again.

Adventurous souls may want to try --rewrite-root.

Solution 2

You can see if the following works OK:

  1. If svn-remote.svn.rewriteRoot does not exist in config file (.git/config):

    git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
    
  2. If svn-remote.svn.rewriteUUID does not exist in config file:

    git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
    

    The currentRepositoryUUID can be obtained from .git/svn/.metadata.

  3. git config svn-remote.svn.url <newRepositoryURL>

Solution 3

Unfortunately most of the links in these answers aren't working, so I'm going to duplicate a bit of information from the git wiki for future reference.

This solution worked for me:

  • Edit the svn-remote url (or fetch path) in .git/config to point to the new domain/url/path

  • Run git git svn fetch. This needs to fetch at least one new revision from svn!

  • If you attempt git svn rebase now, you'll get an error message like this:

    Unable to determine upstream SVN information from working tree history
    

    I think this is because git svn is confused by the fact that your latest commit prior to the fetch will have a git-svn-id pointing to the old path, which doesn't match the one found in .git/config.

  • As a workaround, change svn-remote url (or fetch path) back to the original domain/url/path

  • Now run git svn rebase -l again to do a local rebase with the changes that came in with the last fetch operation. This time it will work, apparently because git svn won't be confused by the fact that the git-svn-id of the new head doesn't match with that found in .git/config.

  • Finally, change svn-remote url (or fetch path) back to the new domain/url/path

  • At this point git svn rebase should work again!

The original information was found here.

Solution 4

Git svn relies heavily on the svn URL. Every commit that is imported from svn has a git-svn-id that includes the svn URL.

A valid relocations strategy is to call git-svn clone on the new repository and merge the changes onto that new close. For a more detailed procedure, see this article:

http://www.sanityinc.com/articles/relocating-git-svn-repositories

Solution 5

git filter-branch

This script, taken from a blog entry, has worked for me. Supply old and new repo URL as parameter, just like for svn switch --relocate.

The script calls git filter-branch to replace Subversion URLs in the git-svn-id in the commit messages, updates .git/config, and also updates git-svn metadata by recreating it using git svn rebase. While git svn clone might be the more robust solution, the filter-branch approach works much faster for huge repositories (hours vs. days).

#!/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
Share:
20,121
kch
Author by

kch

Updated on August 17, 2020

Comments

  • kch
    kch over 3 years

    An svn repository I'm mirroring through git-svn has changed URL.

    In vanilla svn you'd just do svn switch --relocate old_url_base new_url_base.

    How can I do this using git-svn?

    Simply changing the svn url in the config file fails.

  • Sakie
    Sakie over 15 years
    to be fair, this actually failed for me, and I ended up re-cloning the repo. It is hard to get git to handle it when the svn directory is renamed.
  • kch
    kch about 14 years
    I would prefer to accept a more detailed writeup, but fair enough, I'll accept it until a new answer comes along.
  • n8gray
    n8gray over 12 years
    Here's another description of that procedure: theadmin.org/articles/git-svn-switch-to-a-different-a-svn-ur‌​l
  • TcMaster
    TcMaster over 12 years
    the link provided in the accepted answer is outdated and the new one as of now is: git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html I followed the "General Case" and it was simple and really worked fine.
  • UncleZeiv
    UncleZeiv over 12 years
    @TcMaster: worked for me as well... but that's why answers should not contain only links, they get outdated and become useless... I'm going to add a community wiki answer.
  • sdaau
    sdaau about 11 years
    Fantastic - thanks, this worked great for me (cloned via file://, switch to svn+ssh); just noting that: this procedure does not need to "fetch at least one new revision from svn"; also ./.git/svn/.metadata after first svn rebase contains the <newRepository> as reposRoot - but this isn't enough to remove the rewrite* keys from .git/config; thus those keys should be kept permanently there, as far as I understand it.
  • Rafareino
    Rafareino over 8 years
    It worked to me too, like a charm. The OP should try this one and get it as the correct answer.
  • John_Smith
    John_Smith about 8 years
    Perfect. I had a big project with thousands of commits in the history so a new clone would have destroyed the history (or take a really long time to checkout). I'm using svn+ssh:// and our svn-server just changed domain from .se to .com to sanitize our internal naming.
  • David Victor
    David Victor about 8 years
    Worked a treat for me. Had a 2 year old repo with 1,000s of commits, the repo was moved to a new host, so this avoided a (dreaded) full svn clone.
  • sfera
    sfera almost 8 years
    it might be important to mention that the steps 4 to 6 will have to be applied on all locally tracked svn branches, otherwse git-svn operations on those branches will fail with the message 'Unable to determine upstream SVN information from working tree history'.
  • Micha Wiedenmann
    Micha Wiedenmann almost 8 years
    1. Do you start with a fresh clone of the new location to new? If yes, why are you not done at that point? 2. If you rebase new on old, do your old commits all mention the old URL in their svn-id commit log entry? 3. Is there any documentation that it is save to remove .git/svn? (3b: which command is rebuilding the git-svn metadata, git svn info?)
  • cody
    cody almost 6 years
    I had problems with this solution, on step 2 the error Invalid filesystem path syntax: Cannot replace a directory from within at /usr/share/perl5/Git/SVN/Ra.pm line 312. Anyone knows hot to fix this? why does this happen?