我正在镜像 Subversion 存储库标签,svn2git
并且我想确保当我签出特定修订时,我从 git 镜像获得的修订与从 Subversion 获得的修订一致。我的主要问题是 subversion 标签可以更新,我需要确保在 git 镜像中检查匹配的标签,与 Subversion 分支中的等效标签相匹配。
是否有一些工具可以有效地进行这些检查?源码比较多,有很多小文件。关于这个主题有很多答案diff
,但我想知道是否有更优化的工具来完成这项工作。
答案1
diff -qrN
大约与比较两个目录树一样快。该-q
选项使其在文件不同时提前退出。由于您希望文件在大多数情况下都是相同的,因此这并不重要:无论如何,比较工具都必须读取并比较整个文件。
您可以做出的唯一改进diff
是避免从两个存储库中签出。让 git 来完成这项工作那么可能会更快。
答案2
有趣的问题。使用 Git 本身可能是一个简单的解决方案。下面演示一下之间的比较Redmine的 Subversion 存储库https://svn.redmine.org/redmine及其 GitHub 镜像https://github.com/redmine/redmine对于标签3.0.3
:
$ git clone https://github.com/redmine/redmine
$ cd redmine
$ git checkout 3.0.3
$ find -mindepth 1 -maxdepth 1 ! -name .git | xargs rm -rf
... remove files and dirs except .git
$ svn checkout https://svn.redmine.org/redmine/tags/3.0.3 .
$ git status
HEAD detached at 3.0.3
Untracked files:
(use "git add <file>..." to include in what will be committed)
.svn/
nothing added to commit but untracked files present (use "git add" to track)
此输出意味着 git 和 svn 签出 tag 之间没有区别3.0.3
,并.gitignore
考虑过。您可能想添加/.svn
到.gitignore
.
更新:完整脚本:
#!/bin/sh
gitrepo=https://github.com/redmine/redmine
svnrepo=https://svn.redmine.org/redmine
tmpdir=$(mktemp -d)
trap "rm -rf $tmpdir" EXIT
git clone $gitrepo $tmpdir
cd $tmpdir
git tag -l |
while read tag; do
echo
echo "git checking out $tag" &&
git checkout -q $tag >/dev/null &&
find -mindepth 1 -maxdepth 1 ! -name .git | xargs rm -rf &&
echo "svn checking out $tag" &&
svn checkout $svnrepo/tags/$tag . >/dev/null &&
git status --porcelain &&
echo "done $tag"
done
输出:
$ ./compare.sh
Cloning into '/tmp/tmp.BYnBNQqB7I'...
remote: Counting objects: 120652, done.
remote: Total 120652 (delta 0), reused 0 (delta 0), pack-reused 120652
Receiving objects: 100% (120652/120652), 39.16 MiB | 6.40 MiB/s, done.
Resolving deltas: 100% (91652/91652), done.
Checking connectivity... done.
git checking out 0.2.0
svn checking out 0.2.0
?? .svn/
done 0.2.0
git checking out 0.3.0
svn checking out 0.3.0
?? .svn/
done 0.3.0
git checking out 0.4.0
svn checking out 0.4.0
?? .svn/
done 0.4.0
...