@@ -1765,7 +1765,7 @@ sub read_all_remotes {
17651765 my $use_svm_props = eval { command_oneline(qw/ config --bool
17661766 svn.useSvmProps/ ) };
17671767 $use_svm_props = $use_svm_props eq ' true' if $use_svm_props ;
1768- my $svn_refspec = qr {\s */? (.*?)\s *:\s *(.+?)\s *} ;
1768+ my $svn_refspec = qr {\s *(.*?)\s *:\s *(.+?)\s *} ;
17691769 foreach (grep { s / ^svn-remote\. // } command(qw/ config -l/ )) {
17701770 if (m ! ^(.+)\. fetch=$svn_refspec $ ! ) {
17711771 my ($remote , $local_ref , $remote_ref ) = ($1 , $2 , $3 );
@@ -1979,7 +1979,7 @@ sub find_ref {
19791979 my ($ref_id ) = @_ ;
19801980 foreach (command(qw/ config -l/ )) {
19811981 next unless m ! ^svn-remote\. (.+)\. fetch=
1982- \s */? (.*?)\s *:\s *(.+?)\s *$ ! x ;
1982+ \s *(.*?)\s *:\s *(.+?)\s *$ ! x ;
19831983 my ($repo_id , $path , $ref ) = ($1 , $2 , $3 );
19841984 if ($ref eq $ref_id ) {
19851985 $path = ' ' if ($path =~ m # ^\. /?# );
@@ -2878,14 +2878,157 @@ sub check_author {
28782878 $author ;
28792879}
28802880
2881+ sub find_extra_svk_parents {
2882+ my ($self , $ed , $tickets , $parents ) = @_ ;
2883+ # aha! svk:merge property changed...
2884+ my @tickets = split " \n " , $tickets ;
2885+ my @known_parents ;
2886+ for my $ticket ( @tickets ) {
2887+ my ($uuid , $path , $rev ) = split /:/, $ticket ;
2888+ if ( $uuid eq $self -> ra_uuid ) {
2889+ my $url = $self -> rewrite_root || $self -> {url };
2890+ my $repos_root = $url ;
2891+ my $branch_from = $path ;
2892+ $branch_from =~ s { ^/} {} ;
2893+ my $gs = $self -> other_gs($repos_root ." /" .$branch_from ,
2894+ $url ,
2895+ $branch_from ,
2896+ $rev ,
2897+ $self -> {ref_id });
2898+ if ( my $commit = $gs -> rev_map_get($rev , $uuid ) ) {
2899+ # wahey! we found it, but it might be
2900+ # an old one (!)
2901+ push @known_parents , $commit ;
2902+ }
2903+ }
2904+ }
2905+ for my $parent ( @known_parents ) {
2906+ my @cmd = (' rev-list' , $parent , map { " ^$_ " } @$parents );
2907+ my ($msg_fh , $ctx ) = command_output_pipe(@cmd );
2908+ my $new ;
2909+ while ( <$msg_fh > ) {
2910+ $new =1;last ;
2911+ }
2912+ command_close_pipe($msg_fh , $ctx );
2913+ if ( $new ) {
2914+ print STDERR
2915+ " Found merge parent (svk:merge ticket): $parent \n " ;
2916+ push @$parents , $parent ;
2917+ }
2918+ }
2919+ }
2920+
2921+ # note: this function should only be called if the various dirprops
2922+ # have actually changed
2923+ sub find_extra_svn_parents {
2924+ my ($self , $ed , $mergeinfo , $parents ) = @_ ;
2925+ # aha! svk:merge property changed...
2926+
2927+ # We first search for merged tips which are not in our
2928+ # history. Then, we figure out which git revisions are in
2929+ # that tip, but not this revision. If all of those revisions
2930+ # are now marked as merge, we can add the tip as a parent.
2931+ my @merges = split " \n " , $mergeinfo ;
2932+ my @merge_tips ;
2933+ my @merged_commit_ranges ;
2934+ my $url = $self -> rewrite_root || $self -> {url };
2935+ for my $merge ( @merges ) {
2936+ my ($source , $revs ) = split " :" , $merge ;
2937+ my $path = $source ;
2938+ $path =~ s { ^/} {} ;
2939+ my $gs = Git::SVN-> find_by_url($url .$source , $url , $path );
2940+ if ( !$gs ) {
2941+ warn " Couldn't find revmap for $url$source \n " ;
2942+ next ;
2943+ }
2944+ my @ranges = split " ," , $revs ;
2945+ my ($tip , $tip_commit );
2946+ # find the tip
2947+ for my $range ( @ranges ) {
2948+ my ($bottom , $top ) = split " -" , $range ;
2949+ $top ||= $bottom ;
2950+ my $bottom_commit =
2951+ $gs -> rev_map_get($bottom , $self -> ra_uuid) ||
2952+ $gs -> rev_map_get($bottom +1, $self -> ra_uuid);
2953+ my $top_commit =
2954+ $gs -> rev_map_get($top , $self -> ra_uuid);
2955+
2956+ unless ($top_commit and $bottom_commit ) {
2957+ warn " W:unknown path/rev in svn:mergeinfo "
2958+ ." dirprop: $source :$range \n " ;
2959+ next ;
2960+ }
2961+
2962+ push @merged_commit_ranges ,
2963+ " $bottom_commit ..$top_commit " ;
2964+
2965+ if ( !defined $tip or $top > $tip ) {
2966+ $tip = $top ;
2967+ $tip_commit = $top_commit ;
2968+ }
2969+ }
2970+ unless (!$tip_commit or
2971+ grep { $_ eq $tip_commit } @$parents ) {
2972+ push @merge_tips , $tip_commit ;
2973+ } else {
2974+ push @merge_tips , undef ;
2975+ }
2976+ }
2977+ for my $merge_tip ( @merge_tips ) {
2978+ my $spec = shift @merges ;
2979+ next unless $merge_tip ;
2980+ my @cmd = (' rev-list' , " -1" , $merge_tip ,
2981+ " --not" , @$parents );
2982+ my ($msg_fh , $ctx ) = command_output_pipe(@cmd );
2983+ my $new ;
2984+ while ( <$msg_fh > ) {
2985+ $new =1;last ;
2986+ }
2987+ command_close_pipe($msg_fh , $ctx );
2988+ if ( $new ) {
2989+ push @cmd , @merged_commit_ranges ;
2990+ my ($msg_fh , $ctx ) = command_output_pipe(@cmd );
2991+ my $unmerged ;
2992+ while ( <$msg_fh > ) {
2993+ $unmerged =1;last ;
2994+ }
2995+ command_close_pipe($msg_fh , $ctx );
2996+ if ( $unmerged ) {
2997+ warn " W:svn cherry-pick ignored ($spec )\n " ;
2998+ } else {
2999+ warn
3000+ " Found merge parent (svn:mergeinfo prop): " ,
3001+ $merge_tip , " \n " ;
3002+ push @$parents , $merge_tip ;
3003+ }
3004+ }
3005+ }
3006+ }
3007+
28813008sub make_log_entry {
28823009 my ($self , $rev , $parents , $ed ) = @_ ;
28833010 my $untracked = $self -> get_untracked($ed );
28843011
3012+ my @parents = @$parents ;
3013+ my $ps = $ed -> {path_strip } || " " ;
3014+ for my $path ( grep { m /$ps / } %{$ed -> {dir_prop }} ) {
3015+ my $props = $ed -> {dir_prop }{$path };
3016+ if ( $props -> {" svk:merge" } ) {
3017+ $self -> find_extra_svk_parents
3018+ ($ed , $props -> {" svk:merge" }, \@parents );
3019+ }
3020+ if ( $props -> {" svn:mergeinfo" } ) {
3021+ $self -> find_extra_svn_parents
3022+ ($ed ,
3023+ $props -> {" svn:mergeinfo" },
3024+ \@parents );
3025+ }
3026+ }
3027+
28853028 open my $un , ' >>' , " $self ->{dir}/unhandled.log" or croak $! ;
28863029 print $un " r$rev \n " or croak $! ;
28873030 print $un $_ , " \n " foreach @$untracked ;
2888- my %log_entry = ( parents => $ parents || [] , revision => $rev ,
3031+ my %log_entry = ( parents => \ @ parents , revision => $rev ,
28893032 log => ' ' );
28903033
28913034 my $headrev ;
0 commit comments