55use strict;
66use vars qw/ $AUTHOR $VERSION
77 $sha1 $sha1_short $_revision $_repository
8- $_q $_authors %users/ ;
8+ $_q $_authors $_authors_prog %users/ ;
99$AUTHOR = ' Eric Wong <normalperson@yhbt.net>' ;
1010$VERSION = ' @@GIT_VERSION@@' ;
1111
3939use IO::File qw/ / ;
4040use File::Basename qw/ dirname basename/ ;
4141use File::Path qw/ mkpath/ ;
42+ use File::Spec;
4243use Getopt::Long qw/ :config gnu_getopt no_ignore_case auto_abbrev/ ;
4344use IPC::Open3;
4445use Git;
7677 ' ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
7778my %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
263265version() if $_version;
264266usage(1) unless defined $cmd ;
265267load_authors() if $_authors;
268+ if (defined $_authors_prog) {
269+ $_authors_prog = " '" . File::Spec-> rel2abs($_authors_prog) . " '" ;
270+ }
266271
267272unless ($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
366372sub 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+
26662688sub 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
0 commit comments