我通过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仓库中newold入new
cd newgit fetch ../oldgit tag old FETCH_HEADnew上的顶部old(应成功,因为在根目录中的树木new和的尖端old是相同的)
git checkout master(假设master分支指向SVN头。纯净克隆就是这种情况;否则请在开始之前进行dcommit。)git rebase --root --onto oldnew以解决基准问题
git update-ref --no-deref refs/remotes/git-svn master(根据您的克隆方式调整远程引用,例如refs/remotes/svn/trunk)rm -r .git/svngit 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。