git-svn:相当于`svn switch --relocate`吗?


88

我通过git-svn镜像的svn存储库已更改URL。

在香草svn中,您只需要这样做即可svn switch --relocate old_url_base new_url_base

如何使用git-svn执行此操作?

仅更改配置文件中的svn url失败。


您应该尝试并可能接受以下答案:stackoverflow.com/a/4061493/1221661
Fritz

最新答案:stackoverflow.com/a/40523789/537554。同样的问题,但是从Git用户的角度提出。
ryenus

Answers:


61

这可以很好地处理我的情况:

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

我使用该file://协议进行了克隆,并想切换到该http://协议。

尝试url在中的[svn-remote "svn"]部分中编辑设置很诱人.git/config,但仅此操作不起作用。通常,您需要遵循以下过程:

  1. 将svn-remoteurl设置切换为新名称。
  2. 运行git svn fetch。这需要从svn获取至少一个新修订!
  3. 将svn-remoteurl设置更改回原始URL。
  4. 运行git svn rebase -l以进行本地变基(使用上一次获取操作所带来的更改)。
  5. 将svn-remoteurl设置更改回新的URL。
  6. 现在,git svn rebase应该重新工作。

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


2
公平地说,这实际上对我来说是失败的,我最终重新克隆了该存储库。重命名svn目录时,很难让git处理它。
Gregg Lind

我希望接受更详细的文章,但是很公平,我会接受它直到出现新的答案。
2010年

2

接受的答案中提供的链接已经过时,到目前为止,新的链接是:git.wiki.kernel.org/articles/g/i/t/GitSvnSwitch_8828.html我遵循了“一般情况”,它很简单,而且确实工作正常。
TcMaster

2
@TcMaster:也为我工作...但这就是为什么答案不应该包含链接,它们会过时并变得无用的原因...我将添加社区Wiki答案。
UncleZeiv

37

您可以查看以下各项是否正常:

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

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

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

    currentRepositoryUUID可以从获得.git/svn/.metadata

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


太棒了-谢谢,这对我非常有用(通过克隆file://,切换到svn+ssh);只是要注意:此过程不需要“从svn获取至少一个新修订”;也./.git/svn/.metadata第一次后svn rebase包含<newRepository>reposRoot-但这是不够的,除去rewrite*从键.git/config; 据我所知,这些密钥应永久保存在此处。
sdaau

1
它对我也很有效,就像一种魅力。OP应该尝试此操作并将其作为正确答案。
拉法雷诺2015年

完善。我有一个大项目,在历史记录中有成千上万次提交,因此新的克隆将破坏历史记录(或花费很长时间才能结帐)。我正在使用svn+ssh://,我们的svn服务器刚刚将域从更改.se.com来清理内部命名。
UlfR '16

为我工作了。如果有一个2年历史的回购,提交次数为1,000,则该回购已移至新主机,因此避免了(可怕的)完整svn克隆。
大卫·维克多

21

不幸的是,这些答案中的大多数链接都无法正常工作,因此我将复制git wiki中的一些信息以供将来参考。

此解决方案为我工作:

  • 编辑svn-remote url(或fetch路径).git/config以指向新的域/ URL /路径

  • 运行git git svn fetch这需要从svn获取至少一个新修订!

  • 如果立即尝试git svn rebase,您将收到以下错误消息:

    Unable to determine upstream SVN information from working tree history
    

    我认为这是因为git svn对以下事实感到困惑,因为您在提取之前的最新提交将git-svn-id指向旧路径,该旧路径与中的路径不匹配.git/config

  • 解决方法是将svn-remote url(或fetch路径)更改回原始域/ URL /路径

  • 现在,git svn rebase -l再次运行以对上一次获取操作所带来的更改进行本地重新配置。这次它将正常工作,显然是因为git svn不会被git-svn-id新头像的和与中找到的不匹配的事实所迷惑.git/config

  • 最后,改变 svn-remote url(或fetch路径)回到新的域/ URL /路径

  • 此时git svn rebase应重新工作!

原始信息在这里找到。



2

git filter-branch

该脚本(来自博客条目)对我有用。提供旧的和新的repo URL作为参数,就像svn switch --relocate

该脚本调用git filter-branch来替换git-svn-id提交消息中的Subversion URL ,进行更新.git/config,并git-svn通过使用重新创建元数据来更新元数据git svn rebase。尽管git svn clone可能是更健壮的解决方案,但该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

1

git_fast_filter

使用的速度要比git-filter-branch(而不是数小时,而不是数小时)快,但是在精神上是相似的git_fast_filter。但是,这需要更多的编码,并且不存在整齐的现成解决方案。与相比git-filter-branch,这将从旧的仓库创建新的仓库。假定master指向最后的SVN提交。

  1. 克隆 git_fast_filter从Gitorious回购中。
  2. git_fast_filter基于此Gist进行克隆的目录中创建Python脚本使用设置可执行位chmod +x。调整新旧存储库路径。(脚本的内容也粘贴在下面。)
  3. 使用以下内容初始化新的目标存储库 git init,将工作目录更改为该新。
  4. 执行以下管道:

    (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。如果此命令冻结,则说明有问题。它应该重建版本号映射。

    3. 删除假分支refs/remotes/git-svn,它将通过以下方式重新创建git-svn

  8. 通过调用进行同步git svn rebase

以下是内容commit_filter.py,取代的价值IN_REPO,并OUT_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()

0

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

  1. 将旧的SVN仓库克隆到git仓库中old,将新的SVN克隆到git仓库中new
  2. oldnew
    • cd new
    • git fetch ../old
    • git tag old FETCH_HEAD
  3. 变基new上的顶部old(应成功,因为在根目录中的树木new和的尖端old是相同的)
    • git checkout master(假设master分支指向SVN头。纯净克隆就是这种情况;否则请在开始之前进行dcommit。)
    • git rebase --root --onto old
  4. 重建的git-svn元数据new以解决基准问题
    • git update-ref --no-deref refs/remotes/git-svn master(根据您的克隆方式调整远程引用,例如refs/remotes/svn/trunk
    • rm -r .git/svn
    • git svn info

1.您是否从将新位置复制到新位置开始?如果是,那您为什么还没做完呢?2.如果您以旧为基础建立新的基础,那么您的旧提交是否全部在其svn-id提交日志条目中提及了旧URL?3.是否保存了删除.git / svn的任何文档?(3b:哪个命令正在重建git-svn元数据,git svn信息?)
Micha Wiedenmann

0

基于对该问题的其他一些回答,我提出了一个处理git-svn重定位的Ruby脚本。您可以在https://gist.github.com/henderea/6e779b66be3580c9a584找到它

它可以处理重定位而无需签出另一份副本,甚至可以处理一个或多个分支中未经推送的更改(因为这破坏了常规逻辑)。它使用git filter-branch答案(用于主逻辑)中的内容以及有关将分支从回购实例复制到另一个实例(用于复制具有非推送更改的分支)的答案。

我一直在使用它来重新定位我需要工作的一堆git-svn仓库,这个版本的脚本(我经历了无数次迭代)似乎对我来说很有效。它不是超级快,但是它确实可以处理我遇到的所有情况并导致完全重定位的存储库。

该脚本为您提供了在进行任何更改之前创建存储库副本的选项,因此您可以使用此选项来创建备份。如果您在任何分支机构中都没有进行任何更改,则需要创建副本。

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

希望我的脚本对其他人有用。随时更改脚本。

注意:我只在OS X 10.10 Yosemite上使用git 2.3.0 / 2.3.1和Ruby 2.2.0测试了该脚本(因为这是我使用的环境),但是我希望它也可以在其他环境下工作。但是,不能保证Windows。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.