2

I am mirroring a Subversion repository tag with svn2git and I want to be sure that when I checkout particular revisions, those I obtain from the git mirror match those from Subversion. My main problem is that subversion tags can be updated, and I need to ensure that checking out the matching tag in the git mirror, matches the equivalent one in the Subversion branch.

Are there some tools that can make those checks efficiently? The source is quite a lot with many small files. There are quite a few answers here on the subject involving diff, but I wonder if there are more optimized tools for the job.

2

diff -qrN is about as fast as it gets to compare two directory trees. The -q option makes it quit early when files differ. Since you expect the files to be identical most of the time, it doesn't matter all that much: the comparison tool has to read and compare the whole files anyway.

The only improvement you can make on diff is to avoid checking out from both repositories. Getting git to do the job may be faster then.

2

Interesting problem. Using Git itself might be an easy solution. The following demonstrates the comparison between Redmine's Subversion repository https://svn.redmine.org/redmine and its GitHub mirror https://github.com/redmine/redmine for tag 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)

This output means there's no difference between git and svn checkouts of tag 3.0.3, with .gitignore considered. You might want to add /.svn in .gitignore.

UPDATE: Complete script:

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

Output:

$ ./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

...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.