@@ -2918,6 +2918,93 @@ sub find_extra_svk_parents {
29182918 }
29192919}
29202920
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+
29213008sub make_log_entry {
29223009 my ($self , $rev , $parents , $ed ) = @_ ;
29233010 my $untracked = $self -> get_untracked($ed );
@@ -2930,6 +3017,12 @@ sub make_log_entry {
29303017 $self -> find_extra_svk_parents
29313018 ($ed , $props -> {" svk:merge" }, \@parents );
29323019 }
3020+ if ( $props -> {" svn:mergeinfo" } ) {
3021+ $self -> find_extra_svn_parents
3022+ ($ed ,
3023+ $props -> {" svn:mergeinfo" },
3024+ \@parents );
3025+ }
29333026 }
29343027
29353028 open my $un , ' >>' , " $self ->{dir}/unhandled.log" or croak $! ;
0 commit comments