git-svn:与svn switch –relocate相当的是什么?

我通过git-svn镜像的svn仓库已经改变了URL。

在香草svn你只是做svn switch --relocate old_url_base new_url_base

我怎样才能做到这一点使用git-svn?

只需更改configuration文件中的svn url即可。

这很好地处理我的情况:

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

我克隆使用file://协议,并希望切换到http://协议。

编辑.git/config[svn-remote "svn"]部分的url设置是很诱人的,但是它本身不起作用。 一般来说,您需要遵循以下步骤:

  1. 将svn-remote url设置切换到新名称。
  2. 运行git svn fetch 。 这需要从svn获取至less一个新版本!
  3. 将svn-remote url设置更改回原始URL。
  4. 运行git svn rebase -l来执行本地rebase(使用最后一次fetch操作中的更改)。
  5. 将svn-remote url设置更改回新的URL。
  6. 现在, git svn rebase应该可以再次运行。

冒险的灵魂可能想尝试--rewrite-root

你可以看看下面的工作是否正常:

  1. 如果svn-remote.svn.rewriteRoot在configuration文件( .git/config )中不存在:

     git config svn-remote.svn.rewriteRoot <currentRepositoryURL> 
  2. 如果svn-remote.svn.rewriteUUID在configuration文件中不存在:

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

    currentRepositoryUUID可以从.git/svn/.metadata

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

不幸的是,这些答案中的大部分链接都不起作用,所以我将从git wiki中复制一些信息以供将来参考。

这个解决scheme为我工作:

  • 编辑.git/configsvn-remote url (或fetchpath)指向新的域/ url /path

  • 运行git git svn fetch这需要从svn获取至less一个新版本!

  • 如果你现在尝试git svn rebase ,你会得到这样的错误信息:

     Unable to determine upstream SVN information from working tree history 

    我认为这是因为git svn被这样一个事实所困惑,即在获取之前你的最新提交将会有一个指向旧path的git-svn-id ,这个path与.git/configfind的path不匹配。

  • 作为解决方法,将svn-remote url (或fetchpath)更改回原始域/ url /path

  • 现在再次运行git svn rebase -l来执行一个本地rebase,并在最后一次fetch操作中进行更改。 这一次它工作,显然是因为git svn不会被新头的git-svn-id.git/config中的git-svn-id不匹配的事实混淆。

  • 最后,将svn-remote url (或fetchpath)更改回新的域/ url /path

  • 在这一点上git svn rebase应该再次工作!

原始信息在这里find。

Git svn严重依赖于svn的URL。 每个从svn导入的提交都有一个包含svn URL的git-svn-id

一个有效的重定位策略是在新的仓库上调用git-svn clone ,并将这些更改合并到新的仓库中。 有关更详细的过程,请参阅此文章:

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

git filter-branch

这个脚本 ,从博客条目 ,已经为我工作。 提供旧的和新的repo URL作为参数,就像svn switch --relocate

该脚本调用git filter-branch来replace提交消息中的git-svn-id中的Subversion URL,更新.git/config ,并使用git svn rebase重新创buildgit-svn元数据。 虽然git svn clone可能是更强大的解决scheme,但是filter-branch方法对于巨大的存储库(几个小时与几天)来说工作得更快。

 #!/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 

git_fast_filter

但比git-filter-branch (即分钟而不是小时)更快,但在精神上相似,则是使用git_fast_filter 。 但是,这需要更多的编码,并且没有整齐的随时可用的解决scheme。 与git-filter-branch ,这将创build一个旧的回购。 假设master节点指向最后一个SVN提交。

  1. 从Gitorious回购中克隆git_fast_filter
  2. 在克隆git_fast_filter的同一目录下创build一个Python脚本,使用chmod +x设置可执行位。 调整旧的和新的存储库path。 (脚本的内容也粘贴在下面。)
  3. 使用git init初始化一个新的目标仓库,将工作目录更改为这个新的仓库。
  4. 执行以下pipe道:

     (cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \ path/to/git_fast_filter/commit_filter.py | git-fast-import 
  5. 复制.git/config ,以及其他相关的文件.git/info从旧的回购到新的回购。

  6. 删除.git/svn
  7. git-svn知道新的版本号映射

    1. 执行git branch refs/remotes/git-svn master

      • 你的git-svn遥控器可能与refs/remotes/git-svn ,请咨询.git/configsvn-remote部分
    2. 执行git svn info 。 如果这个命令冻结,有些事情是错误的。 它应该重build修订号映射。

    3. 删除假分支refs/remotes/git-svn ,它会被git-svn重新创build

  8. 通过调用git svn rebase同步。

以下是commit_filter.py的内容,根据需要replaceIN_REPOOUT_REPO的值:

 #!/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() 

上面的git svn rebase -l解决scheme对我不起作用。 我决定以不同的方式去做:

  1. 克隆旧的SVN回购成git回购新old SVN到git回购new
  2. old变成new
    • cd new
    • git fetch ../old
    • git tag old FETCH_HEAD
  3. old (因为old根目录中的树木是相同的)
    • git checkout master (假设master分支指向SVN头,干净的克隆就是这种情况,否则在你启动之前需要提交dcommit)。
    • git rebase --root --onto old
  4. 重新构buildnew的git-svn元数据来考虑rebase
    • git update-ref --no-deref refs/remotes/git-svn master (根据你的克隆方式调整远程ref,例如可以是refs/remotes/svn/trunk
    • rm -r .git/svn
    • git svn info

基于对这个问题的其他一些反应,我想出了一个处理git-svn重定位的Ruby脚本。 你可以在https://gist.github.com/henderea/6e779b66be3580c9a584find它。;

它处理重定位而不检出另一个副本,甚至可以处理在一个或多个分支中存在未被推入的更改(因为中断了常规逻辑)的情况。 它使用git filter-branch回答(对于主要逻辑)的东西,以及将分支从一个回购实例复制到另一个实例(用于以未推送的更改复制分支)的答案。

我一直在使用它来重新定位一堆我工作的git-svn repos,而这个版本的脚本(我已经经历了无数次的迭代)似乎对我有用。 这不是超快的,但它似乎处理我遇到的所有情况,并导致完全重新安置的回购。

该脚本使您可以select在进行任何更改之前创build回购副本,以便您可以使用此选项创build备份。 如果您在任何分支中有未取消推送的更改,则需要创build副本。

该脚本不使用普通MRI Ruby安装中没有包含的任何gem或其他库。 它使用MRI中包含的readline和fileutils库。

希望我的脚本能够certificate对别人有用。 随意对脚本进行更改。

注意:我只在OS X 10.10 Yosemite上使用git 2.3.0 / 2.3.1和Ruby 2.2.0testing了这个脚本(因为这是我使用的环境),但我也希望它能在其他环境中工作。 虽然没有关于Windows的保证。