Git-svn: what is equivalent to `svn switch -relocate`?

The svn repository that I am viewing through git-svn has changed the URL.

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

How to do this using git-svn?

A simple change to the svn url in the configuration file is not performed.

+84
git version-control git-svn
Nov 06 '08 at 13:44
source share
8 answers

This does a good job of my situation:

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 change the url parameter in the [svn-remote "svn"] .git/config section, but this alone does not work. In general, you need to perform the following procedure:

  • Switch the svn-remote url parameter to the new name.
  • Run git svn fetch . This is necessary to get at least one new revision from svn!
  • Change the svn-remote url parameter to the original URL.
  • Run git svn rebase -l to perform local redirection (with the changes made with the last fetch operation).
  • Change the svn-remote url parameter to the new url.
  • Now git svn rebase should work again.

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

+57
Nov 06 '08 at 13:55
source share

You can see if the following works:

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

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

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

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

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

+32
Oct 31 '10 at 1:45
source share

Unfortunately, most of the links in these answers do not work, so I'm going to duplicate the information from the git wiki for reference in the future.

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 . For this you need to get at least one new revision from svn!

  • If you try git svn rebase , you will receive an error message that resembles the following:

     Unable to determine upstream SVN information from working tree history 

    I think this is due to the fact that git svn confused by the fact that your last commit before extraction will have git-svn-id pointing to the old path that does not match the one found in .git/config .

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

  • Now run git svn rebase -l again to perform a local reboot with the changes made with the last extraction operation. This time it will work, apparently, because git svn will not be confused by the fact that the git-svn-id new chapter does not match what is found in .git/config .

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

  • At this point, git svn rebase should work again!

Background information was found here .

+20
Nov 15 '11 at 12:28
source share

Git svn is highly dependent on the svn url. Each commit imported from svn has a git-svn-id that includes the svn url.

A valid move strategy is to call git-svn clone in the new repository and merge the changes with this new closure. For a more detailed procedure, see this article:

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

+3
Nov 06 '08 at 13:46
source share

git filter-branch

This script , taken from a blog post , worked for me. Set the old and new repo urls as parameters, just like for svn switch --relocate .

calls git filter-branch to replace Subversion URLs with git-svn-id in commit messages, update .git/config , and also update git-svn metadata by recreating it with git svn rebase . Although git svn clone may be a more robust solution, the filter-branch approach is much faster for huge repositories (hours versus 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 
+2
Aug 22 '13 at 13:22
source share

git_fast_filter

However, faster than git-filter-branch (i.e. minutes instead of hours), but similarly, git_fast_filter should be used. However, this requires a bit more coding, and there is no neat turnkey solution. Unlike git-filter-branch , this will create a new repo from the old. Master is supposed to point to the last commit of SVN.

  • Clone git_fast_filter from the Gitorious repository.
  • Create a Python script in the same directory where you cloned git_fast_filter based on this Gist , set the executable bit using chmod +x . Adapt old and new repository paths. (The contents of the script are also inserted below).
  • Initialize a new target repository using git init , change the working directory to this new repo.
  • Run the following channel:

     (cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \ path/to/git_fast_filter/commit_filter.py | git-fast-import 
  • Copy .git/config and possibly other relevant files in .git/info from the old repo to the new repo.

  • Remove .git/svn .
  • Make git-svn aware of mapping new version numbers

    • Run git branch refs/remotes/git-svn master

      • Your empty refs/remotes/git-svn buttons may be called differently than refs/remotes/git-svn , see .git/config , svn-remote sections
    • Run git svn info . If this command freezes, something is wrong. It should rebuild the version number display.

    • Delete the fake branch refs/remotes/git-svn , it will recreate git-svn

  • Sync by calling git svn rebase .

The following is the contents of commit_filter.py , replace the values โ€‹โ€‹of IN_REPO and OUT_REPO accordingly:

 #!/usr/bin/python from git_fast_filter import Commit, FastExportFilter import re import sys IN_REPO = "https://svn.code.sf.net/p/matsim/code" OUT_REPO = "https://svn.code.sf.net/p/matsim/source" IN_REPO_RE = re.compile("^git-svn-id: %s" % re.escape(IN_REPO), re.M) OUT_REPO_RE = "git-svn-id: %s" % OUT_REPO def my_commit_callback(commit): commit.message = IN_REPO_RE.sub(OUT_REPO_RE, commit.message) sys.stderr.write(".") filter = FastExportFilter(commit_callback = my_commit_callback) filter.run() 
+1
Aug 22 '13 at 16:00
source share

The above git svn rebase -l does not work for me. I decided to go differently:

  • Clone an old SVN repo in git repo old and a new SVN in git repo new
  • Extract old to new
    • cd new
    • git fetch ../old
    • git tag old FETCH_HEAD
  • Rebase new on top of old (should succeed because the trees at the root of new and the tip of old identical)
    • git checkout master (It is assumed that the master branch points to the SVN head. This will happen with a clean clone, otherwise dcommit before starting.)
    • git rebase --root --onto old
  • Restore git-svn new metadata to account for forwarding
    • git update-ref --no-deref refs/remotes/git-svn master (adjust the remote ref depending on how you cloned, for example, it can be refs/remotes/svn/trunk )
    • rm -r .git/svn
    • git svn info
0
Jan 02 '14 at 9:42 on
source share

Based on some other answers to this question, I came up with a Ruby script that handles the movement of git-svn. You can find it at https://gist.github.com/henderea/6e779b66be3580c9a584 .

It handles the move without checking another copy, and even handles the case when undefined changes occur in one or more branches (since this violates the regular logic). It uses material from the responder to the git filter responder (for the main logic) and the answer about copying branches from one repo instance to another (for copying branches with inaccurate changes).

I used this to move the bunch of git-svn repos that I have to work, and this version of the script (I went through countless iterations) seems to work for me. It is not very fast, but it seems to cope with all the cases that I encountered, and as a result of a completely reorganized repo.

The script gives you the option to create a copy of the repo before making any changes, so you can use this option to create a backup. Creating a copy is required if you have unspecified changes in any branches.

The script does not use any stones or other libraries that are not included in a typical Ruby MRI installation. It uses the readline and fileutils libraries included in the MRI.

Hope my script will prove useful to someone else. Feel free to make changes to the script.

NOTE. I tested only this script with git 2.3.0 / 2.3.1 and Ruby 2.2.0 on OS X 10.10 Yosemite (since I use the environment), but I expect it to work in other environments as well. However, there are no guarantees regarding Windows.

0
Feb 26 '15 at 17:03
source share



All Articles