我通过git-svn镜像的svn存储库已更改URL。
在香草svn中,您只需要这样做即可svn switch --relocate old_url_base new_url_base
。
如何使用git-svn执行此操作?
仅更改配置文件中的svn url失败。
我通过git-svn镜像的svn存储库已更改URL。
在香草svn中,您只需要这样做即可svn switch --relocate old_url_base new_url_base
。
如何使用git-svn执行此操作?
仅更改配置文件中的svn url失败。
Answers:
这可以很好地处理我的情况:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
我使用该file://
协议进行了克隆,并想切换到该http://
协议。
尝试url
在中的[svn-remote "svn"]
部分中编辑设置很诱人.git/config
,但仅此操作不起作用。通常,您需要遵循以下过程:
url
设置切换为新名称。git svn fetch
。这需要从svn获取至少一个新修订!url
设置更改回原始URL。git svn rebase -l
以进行本地变基(使用上一次获取操作所带来的更改)。url
设置更改回新的URL。git svn rebase
应该重新工作。冒险的灵魂可能要尝试--rewrite-root
。
您可以查看以下各项是否正常:
如果svn-remote.svn.rewriteRoot
配置文件(.git/config
)中不存在:
git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
如果svn-remote.svn.rewriteUUID
配置文件中不存在:
git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
在currentRepositoryUUID
可以从获得.git/svn/.metadata
。
git config svn-remote.svn.url <newRepositoryURL>
file://
,切换到svn+ssh
);只是要注意:此过程不需要“从svn获取至少一个新修订”;也./.git/svn/.metadata
第一次后svn rebase
包含<newRepository>
的reposRoot
-但这是不够的,除去rewrite*
从键.git/config
; 据我所知,这些密钥应永久保存在此处。
svn+ssh://
,我们的svn服务器刚刚将域从更改.se
为.com
来清理内部命名。
不幸的是,这些答案中的大多数链接都无法正常工作,因此我将复制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
应重新工作!
原始信息在这里找到。
Git svn严重依赖svn URL。从svn导入的每个提交都有一个git-svn-id
包含svn URL的提交。
有效的搬迁策略是致电 git-svn clone
新的存储库,并将更改合并到该新的关闭中。有关更详细的过程,请参阅本文:
http://www.sanityinc.com/articles/relocating-git-svn-repositories
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
git_fast_filter
使用的速度要比git-filter-branch
(而不是数小时,而不是数小时)快,但是在精神上是相似的git_fast_filter
。但是,这需要更多的编码,并且不存在整齐的现成解决方案。与相比git-filter-branch
,这将从旧的仓库创建新的仓库。假定master
指向最后的SVN提交。
git_fast_filter
从Gitorious回购中。git_fast_filter
基于此Gist进行克隆的目录中创建Python脚本使用设置可执行位chmod +x
。调整新旧存储库路径。(脚本的内容也粘贴在下面。)git init
,将工作目录更改为该新。执行以下管道:
(cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
path/to/git_fast_filter/commit_filter.py | git-fast-import
复制.git/config
,以及其他相关文件.git/info
从旧存储库到新存储库。
.git/svn
。请git-svn
知道新的版本号映射
执行 git branch refs/remotes/git-svn master
refs/remotes/git-svn
,咨询.git/config
,svn-remote
各节执行git svn info
。如果此命令冻结,则说明有问题。它应该重建版本号映射。
删除假分支refs/remotes/git-svn
,它将通过以下方式重新创建git-svn
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()
上面的git svn rebase -l
解决方案对我不起作用。我决定以不同的方式去做:
old
,将新的SVN克隆到git仓库中new
old
入new
cd new
git fetch ../old
git tag old FETCH_HEAD
new
上的顶部old
(应成功,因为在根目录中的树木new
和的尖端old
是相同的)
git checkout master
(假设master
分支指向SVN头。纯净克隆就是这种情况;否则请在开始之前进行dcommit。)git rebase --root --onto old
new
以解决基准问题
git update-ref --no-deref refs/remotes/git-svn master
(根据您的克隆方式调整远程引用,例如refs/remotes/svn/trunk
)rm -r .git/svn
git svn info
基于对该问题的其他一些回答,我提出了一个处理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。