Skip to content

Commit 581412c

Browse files
committed
Merge git://git.bogomips.org/git-svn
* git://git.bogomips.org/git-svn: git-svn: add --authors-prog option git-svn: Set svn.authorsfile if it is passed to git svn clone git-svn: Correctly report max revision when following deleted paths git-svn: Fix for svn paths removed > log-window-size revisions ago git-svn testsuite: use standard configuration for Subversion tools
2 parents fe87c92 + 36db1ed commit 581412c

32 files changed

+334
-211
lines changed

Documentation/git-svn.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,14 @@ after the authors-file is modified should continue operation.
398398

399399
config key: svn.authorsfile
400400

401+
--authors-prog=<filename>::
402+
403+
If this option is specified, for each SVN committer name that does not
404+
exist in the authors file, the given file is executed with the committer
405+
name as the first argument. The program is expected to return a single
406+
line of the form "Name <email>", which will be treated as if included in
407+
the authors file.
408+
401409
-q::
402410
--quiet::
403411
Make 'git-svn' less verbose. Specify a second time to make it

git-svn.perl

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use strict;
66
use vars qw/ $AUTHOR $VERSION
77
$sha1 $sha1_short $_revision $_repository
8-
$_q $_authors %users/;
8+
$_q $_authors $_authors_prog %users/;
99
$AUTHOR = 'Eric Wong <[email protected]>';
1010
$VERSION = '@@GIT_VERSION@@';
1111

@@ -39,6 +39,7 @@
3939
use IO::File qw//;
4040
use File::Basename qw/dirname basename/;
4141
use File::Path qw/mkpath/;
42+
use File::Spec;
4243
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
4344
use IPC::Open3;
4445
use Git;
@@ -76,6 +77,7 @@ BEGIN
7677
'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
7778
my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
7879
'authors-file|A=s' => \$_authors,
80+
'authors-prog=s' => \$_authors_prog,
7981
'repack:i' => \$Git::SVN::_repack,
8082
'noMetadata' => \$Git::SVN::_no_metadata,
8183
'useSvmProps' => \$Git::SVN::_use_svm_props,
@@ -263,6 +265,9 @@ BEGIN
263265
version() if $_version;
264266
usage(1) unless defined $cmd;
265267
load_authors() if $_authors;
268+
if (defined $_authors_prog) {
269+
$_authors_prog = "'" . File::Spec->rel2abs($_authors_prog) . "'";
270+
}
266271

267272
unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) {
268273
Git::SVN::Migration::migration_check();
@@ -361,6 +366,7 @@ sub cmd_clone {
361366
$path = basename($url) if !defined $path || !length $path;
362367
cmd_init($url, $path);
363368
Git::SVN::fetch_all($Git::SVN::default_repo_id);
369+
command_oneline('config', 'svn.authorsfile', $_authors) if $_authors;
364370
}
365371

366372
sub cmd_init {
@@ -2663,12 +2669,33 @@ sub other_gs {
26632669
$gs
26642670
}
26652671

2672+
sub call_authors_prog {
2673+
my ($orig_author) = @_;
2674+
my $author = `$::_authors_prog $orig_author`;
2675+
if ($? != 0) {
2676+
die "$::_authors_prog failed with exit code $?\n"
2677+
}
2678+
if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
2679+
my ($name, $email) = ($1, $2);
2680+
$email = undef if length $2 == 0;
2681+
return [$name, $email];
2682+
} else {
2683+
die "Author: $orig_author: $::_authors_prog returned "
2684+
. "invalid author format: $author\n";
2685+
}
2686+
}
2687+
26662688
sub check_author {
26672689
my ($author) = @_;
26682690
if (!defined $author || length $author == 0) {
26692691
$author = '(no author)';
2670-
} elsif (defined $::_authors && ! defined $::users{$author}) {
2671-
die "Author: $author not defined in $::_authors file\n";
2692+
}
2693+
if (!defined $::users{$author}) {
2694+
if (defined $::_authors_prog) {
2695+
$::users{$author} = call_authors_prog($author);
2696+
} elsif (defined $::_authors) {
2697+
die "Author: $author not defined in $::_authors file\n";
2698+
}
26722699
}
26732700
$author;
26742701
}
@@ -4438,6 +4465,7 @@ sub gs_fetch_loop_common {
44384465
my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
44394466
my $longest_path = longest_common_path($gsv, $globs);
44404467
my $ra_url = $self->{url};
4468+
my $find_trailing_edge;
44414469
while (1) {
44424470
my %revs;
44434471
my $err;
@@ -4455,8 +4483,10 @@ sub gs_fetch_loop_common {
44554483
sub { $revs{$_[1]} = _cb(@_) });
44564484
if ($err) {
44574485
print "Checked through r$max\r";
4486+
} else {
4487+
$find_trailing_edge = 1;
44584488
}
4459-
if ($err && $max >= $head) {
4489+
if ($err and $find_trailing_edge) {
44604490
print STDERR "Path '$longest_path' ",
44614491
"was probably deleted:\n",
44624492
$err->expanded_message,
@@ -4468,13 +4498,14 @@ sub gs_fetch_loop_common {
44684498
my $ok;
44694499
$self->get_log([$longest_path], $min, $hi,
44704500
0, 1, 1, sub {
4471-
$ok ||= $_[1];
4501+
$ok = $_[1];
44724502
$revs{$_[1]} = _cb(@_) });
44734503
if ($ok) {
44744504
print STDERR "r$min .. r$ok OK\n";
44754505
last;
44764506
}
44774507
}
4508+
$find_trailing_edge = 0;
44784509
}
44794510
$SVN::Error::handler = $err_handler;
44804511

t/lib-git-svn.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ fi
2626

2727
svnrepo=$PWD/svnrepo
2828
export svnrepo
29+
svnconf=$PWD/svnconf
30+
export svnconf
2931

3032
perl -w -e "
3133
use SVN::Core;
@@ -54,6 +56,19 @@ poke() {
5456
test-chmtime +1 "$1"
5557
}
5658

59+
# We need this, because we should pass empty configuration directory to
60+
# the 'svn commit' to avoid automated property changes and other stuff
61+
# that could be set from user's configuration files in ~/.subversion.
62+
svn_cmd () {
63+
[ -d "$svnconf" ] || mkdir "$svnconf"
64+
orig_svncmd="$1"; shift
65+
if [ -z "$orig_svncmd" ]; then
66+
svn
67+
return
68+
fi
69+
svn "$orig_svncmd" --config-dir "$svnconf" "$@"
70+
}
71+
5772
for d in \
5873
"$SVN_HTTPD_PATH" \
5974
/usr/sbin/apache2 \

t/t9100-git-svn-basic.sh

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ test_expect_success \
3131
echo "zzz" > bar/zzz &&
3232
echo "#!/bin/sh" > exec.sh &&
3333
chmod +x exec.sh &&
34-
svn import -m "import for git svn" . "$svnrepo" >/dev/null &&
34+
svn_cmd import -m "import for git svn" . "$svnrepo" >/dev/null &&
3535
cd .. &&
3636
rm -rf import &&
3737
git svn init "$svnrepo"'
@@ -51,7 +51,7 @@ test_expect_success "$name" '
5151
git commit -m "$name" &&
5252
git svn set-tree --find-copies-harder --rmdir \
5353
${remotes_git_svn}..mybranch &&
54-
svn up "$SVN_TREE" &&
54+
svn_cmd up "$SVN_TREE" &&
5555
test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a'
5656

5757

@@ -118,7 +118,7 @@ test_expect_success "$name" '
118118
git commit -m "$name" &&
119119
git svn set-tree --find-copies-harder --rmdir \
120120
${remotes_git_svn}..mybranch5 &&
121-
svn up "$SVN_TREE" &&
121+
svn_cmd up "$SVN_TREE" &&
122122
test ! -x "$SVN_TREE"/exec.sh'
123123

124124

@@ -129,7 +129,7 @@ test_expect_success "$name" '
129129
git commit -m "$name" &&
130130
git svn set-tree --find-copies-harder --rmdir \
131131
${remotes_git_svn}..mybranch5 &&
132-
svn up "$SVN_TREE" &&
132+
svn_cmd up "$SVN_TREE" &&
133133
test -x "$SVN_TREE"/exec.sh'
134134

135135

@@ -141,7 +141,7 @@ test_expect_success "$name" '
141141
git commit -m "$name" &&
142142
git svn set-tree --find-copies-harder --rmdir \
143143
${remotes_git_svn}..mybranch5 &&
144-
svn up "$SVN_TREE" &&
144+
svn_cmd up "$SVN_TREE" &&
145145
test -L "$SVN_TREE"/exec.sh'
146146

147147
name='new symlink is added to a file that was also just made executable'
@@ -153,7 +153,7 @@ test_expect_success "$name" '
153153
git commit -m "$name" &&
154154
git svn set-tree --find-copies-harder --rmdir \
155155
${remotes_git_svn}..mybranch5 &&
156-
svn up "$SVN_TREE" &&
156+
svn_cmd up "$SVN_TREE" &&
157157
test -x "$SVN_TREE"/bar/zzz &&
158158
test -L "$SVN_TREE"/exec-2.sh'
159159

@@ -166,7 +166,7 @@ test_expect_success "$name" '
166166
git commit -m "$name" &&
167167
git svn set-tree --find-copies-harder --rmdir \
168168
${remotes_git_svn}..mybranch5 &&
169-
svn up "$SVN_TREE" &&
169+
svn_cmd up "$SVN_TREE" &&
170170
test -f "$SVN_TREE"/exec-2.sh &&
171171
test ! -L "$SVN_TREE"/exec-2.sh &&
172172
test_cmp help "$SVN_TREE"/exec-2.sh'

t/t9101-git-svn-props.sh

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ EOF
4848
printf "\r\n" > empty_crlf
4949
a_empty_crlf=`git hash-object -w empty_crlf`
5050

51-
svn import --no-auto-props -m 'import for git svn' . "$svnrepo" >/dev/null
51+
svn_cmd import --no-auto-props -m 'import for git svn' . "$svnrepo" >/dev/null
5252
cd ..
5353

5454
rm -rf import
@@ -57,13 +57,13 @@ test_expect_success 'setup some commits to svn' \
5757
'cd test_wc &&
5858
echo Greetings >> kw.c &&
5959
poke kw.c &&
60-
svn commit -m "Not yet an Id" &&
60+
svn_cmd commit -m "Not yet an Id" &&
6161
echo Hello world >> kw.c &&
6262
poke kw.c &&
63-
svn commit -m "Modified file, but still not yet an Id" &&
64-
svn propset svn:keywords Id kw.c &&
63+
svn_cmd commit -m "Modified file, but still not yet an Id" &&
64+
svn_cmd propset svn:keywords Id kw.c &&
6565
poke kw.c &&
66-
svn commit -m "Propset Id" &&
66+
svn_cmd commit -m "Propset Id" &&
6767
cd ..'
6868

6969
test_expect_success 'initialize git svn' 'git svn init "$svnrepo"'
@@ -83,16 +83,16 @@ test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'"
8383

8484
test_expect_success "propset CR on crlf files" \
8585
'cd test_wc &&
86-
svn propset svn:eol-style CR empty &&
87-
svn propset svn:eol-style CR crlf &&
88-
svn propset svn:eol-style CR ne_crlf &&
89-
svn commit -m "propset CR on crlf files" &&
86+
svn_cmd propset svn:eol-style CR empty &&
87+
svn_cmd propset svn:eol-style CR crlf &&
88+
svn_cmd propset svn:eol-style CR ne_crlf &&
89+
svn_cmd commit -m "propset CR on crlf files" &&
9090
cd ..'
9191

9292
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
9393
'git svn fetch &&
9494
git pull . ${remotes_git_svn} &&
95-
svn co "$svnrepo" new_wc'
95+
svn_cmd co "$svnrepo" new_wc'
9696

9797
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
9898
do
@@ -106,11 +106,11 @@ cd test_wc
106106
a_cr=`printf '$Id$\r\nHello\r\nWorld\r\n' | git hash-object --stdin`
107107
a_ne_cr=`printf '$Id$\r\nHello\r\nWorld' | git hash-object --stdin`
108108
test_expect_success 'Set CRLF on cr files' \
109-
'svn propset svn:eol-style CRLF cr &&
110-
svn propset svn:eol-style CRLF ne_cr &&
111-
svn propset svn:keywords Id cr &&
112-
svn propset svn:keywords Id ne_cr &&
113-
svn commit -m "propset CRLF on cr files"'
109+
'svn_cmd propset svn:eol-style CRLF cr &&
110+
svn_cmd propset svn:eol-style CRLF ne_cr &&
111+
svn_cmd propset svn:keywords Id cr &&
112+
svn_cmd propset svn:keywords Id ne_cr &&
113+
svn_cmd commit -m "propset CRLF on cr files"'
114114
cd ..
115115
test_expect_success 'fetch and pull latest from svn' \
116116
'git svn fetch && git pull . ${remotes_git_svn}'
@@ -140,10 +140,10 @@ test_expect_success 'test show-ignore' "
140140
cd test_wc &&
141141
mkdir -p deeply/nested/directory &&
142142
touch deeply/nested/directory/.keep &&
143-
svn add deeply &&
144-
svn up &&
145-
svn propset -R svn:ignore 'no-such-file*' .
146-
svn commit -m 'propset svn:ignore'
143+
svn_cmd add deeply &&
144+
svn_cmd up &&
145+
svn_cmd propset -R svn:ignore 'no-such-file*' .
146+
svn_cmd commit -m 'propset svn:ignore'
147147
cd .. &&
148148
git svn show-ignore > show-ignore.got &&
149149
cmp show-ignore.expect show-ignore.got

t/t9102-git-svn-deep-rmdir.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test_expect_success 'initialize repo' '
99
mkdir -p deeply/nested/directory/number/2 &&
1010
echo foo > deeply/nested/directory/number/1/file &&
1111
echo foo > deeply/nested/directory/number/2/another &&
12-
svn import -m "import for git svn" . "$svnrepo" &&
12+
svn_cmd import -m "import for git svn" . "$svnrepo" &&
1313
cd ..
1414
'
1515

@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' '
2323
git rm -f deeply/nested/directory/number/2/another &&
2424
git commit -a -m "remove another" &&
2525
git svn set-tree --rmdir HEAD &&
26-
svn ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1
26+
svn_cmd ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1
2727
'
2828

2929

t/t9103-git-svn-tracked-directory-removed.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ test_expect_success 'make history for tracking' '
1010
mkdir import &&
1111
mkdir import/trunk &&
1212
echo hello >> import/trunk/README &&
13-
svn import -m initial import "$svnrepo" &&
13+
svn_cmd import -m initial import "$svnrepo" &&
1414
rm -rf import &&
15-
svn co "$svnrepo"/trunk trunk &&
15+
svn_cmd co "$svnrepo"/trunk trunk &&
1616
echo bye bye >> trunk/README &&
17-
svn rm -m "gone" "$svnrepo"/trunk &&
17+
svn_cmd rm -m "gone" "$svnrepo"/trunk &&
1818
rm -rf trunk &&
1919
mkdir trunk &&
2020
echo "new" > trunk/FOLLOWME &&
21-
svn import -m "new trunk" trunk "$svnrepo"/trunk
21+
svn_cmd import -m "new trunk" trunk "$svnrepo"/trunk
2222
'
2323

2424
test_expect_success 'clone repo with git' '

0 commit comments

Comments
 (0)