@@ -374,16 +374,9 @@ sub cmd_dcommit {
374
374
die " Unable to determine upstream SVN information from " ,
375
375
" $head history\n " ;
376
376
}
377
- my $c = $refs [-1];
378
377
my $last_rev ;
379
- foreach my $d (@refs ) {
380
- if (!verify_ref(" $d ~1" )) {
381
- fatal " Commit $d \n " ,
382
- " has no parent commit, and therefore " ,
383
- " nothing to diff against.\n " ,
384
- " You should be working from a repository " ,
385
- " originally created by git-svn\n " ;
386
- }
378
+ my ($linear_refs , $parents ) = linearize_history($gs , \@refs );
379
+ foreach my $d (@$linear_refs ) {
387
380
unless (defined $last_rev ) {
388
381
(undef , $last_rev , undef ) = cmt_metadata(" $d ~1" );
389
382
unless (defined $last_rev ) {
@@ -405,6 +398,9 @@ sub cmd_dcommit {
405
398
svn_path => ' ' );
406
399
if (!SVN::Git::Editor-> new(\%ed_opts )-> apply_diff) {
407
400
print " No changes\n $d ~1 == $d \n " ;
401
+ } elsif ($parents -> {$d } && @{$parents -> {$d }}) {
402
+ $gs -> {inject_parents_dcommit }-> {$last_rev } =
403
+ $parents -> {$d };
408
404
}
409
405
}
410
406
}
@@ -831,6 +827,59 @@ sub working_head_info {
831
827
(undef , undef , undef , undef );
832
828
}
833
829
830
+ sub read_commit_parents {
831
+ my ($parents , $c ) = @_ ;
832
+ my ($fh , $ctx ) = command_output_pipe(qw/ cat-file commit/ , $c );
833
+ while (<$fh >) {
834
+ chomp ;
835
+ last if ' ' ;
836
+ / ^parent ($sha1 )/ or next ;
837
+ push @{$parents -> {$c }}, $1 ;
838
+ }
839
+ close $fh ; # break the pipe
840
+ }
841
+
842
+ sub linearize_history {
843
+ my ($gs , $refs ) = @_ ;
844
+ my %parents ;
845
+ foreach my $c (@$refs ) {
846
+ read_commit_parents(\%parents , $c );
847
+ }
848
+
849
+ my @linear_refs ;
850
+ my %skip = ();
851
+ my $last_svn_commit = $gs -> last_commit;
852
+ foreach my $c (reverse @$refs ) {
853
+ next if $c eq $last_svn_commit ;
854
+ last if $skip {$c };
855
+
856
+ unshift @linear_refs , $c ;
857
+ $skip {$c } = 1;
858
+
859
+ # we only want the first parent to diff against for linear
860
+ # history, we save the rest to inject when we finalize the
861
+ # svn commit
862
+ my $fp_a = verify_ref(" $c ~1" );
863
+ my $fp_b = shift @{$parents {$c }} if $parents {$c };
864
+ if (!$fp_a || !$fp_b ) {
865
+ die " Commit $c \n " ,
866
+ " has no parent commit, and therefore " ,
867
+ " nothing to diff against.\n " ,
868
+ " You should be working from a repository " ,
869
+ " originally created by git-svn\n " ;
870
+ }
871
+ if ($fp_a ne $fp_b ) {
872
+ die " $c ~1 = $fp_a , however parsing commit $c " ,
873
+ " revealed that:\n $c ~1 = $fp_b \n BUG!\n " ;
874
+ }
875
+
876
+ foreach my $p (@{$parents {$c }}) {
877
+ $skip {$p } = 1;
878
+ }
879
+ }
880
+ (\@linear_refs , \%parents );
881
+ }
882
+
834
883
package Git::SVN ;
835
884
use strict;
836
885
use warnings;
@@ -1551,6 +1600,11 @@ sub get_commit_parents {
1551
1600
if (my $cur = ::verify_ref($self -> refname.' ^0' )) {
1552
1601
push @tmp , $cur ;
1553
1602
}
1603
+ if (my $ipd = $self -> {inject_parents_dcommit }) {
1604
+ if (my $commit = delete $ipd -> {$log_entry -> {revision }}) {
1605
+ push @tmp , @$commit ;
1606
+ }
1607
+ }
1554
1608
push @tmp , $_ foreach (@{$log_entry -> {parents }}, @tmp );
1555
1609
while (my $p = shift @tmp ) {
1556
1610
next if $seen {$p };
0 commit comments