about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-05-05 17:49:43 +0000
committerEric Wong <e@80x24.org>2021-05-05 19:50:03 +0000
commit274d3476320aebc93ead7c5da4f716a12d43167f (patch)
tree6a93daf6b3ae57999df85da330dc4583eb7232ef /lib
parentf1921e46e16cabb6f705236581564b8fe901a76e (diff)
downloadpublic-inbox-274d3476320aebc93ead7c5da4f716a12d43167f.tar.gz
Don't lose file mode information when regenerating a diff.
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/LeiRediff.pm19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/PublicInbox/LeiRediff.pm b/lib/PublicInbox/LeiRediff.pm
index 6c734bef..d73e3e28 100644
--- a/lib/PublicInbox/LeiRediff.pm
+++ b/lib/PublicInbox/LeiRediff.pm
@@ -16,6 +16,8 @@ use PublicInbox::Import;
 use PublicInbox::LEI;
 use PublicInbox::SolverGit;
 
+my $MODE = '(100644|120000|100755|160000)';
+
 sub rediff_user_cb { # called by solver when done
         my ($res, $self) = @_;
         my $lei = $self->{lei};
@@ -69,7 +71,7 @@ EOM
         $tb =~ tr!A!B!;
         my $lei = $self->{lei};
         my $wait = delete($self->{-do_done}) ? $lei->{sto}->ipc_do('done') : 0;
-        while (my ($oid_a, $oid_b, $pa, $pb) = splice(@$ctxq, 0, 4)) {
+        while (my ($oid_a, $oid_b, $pa, $pb, $ma, $mb) = splice(@$ctxq, 0, 6)) {
                 my $xa = $blob->{$oid_a} //= solve_1($self, $oid_a,
                                                         { path_b => $pa });
                 my $xb = $blob->{$oid_b} //= solve_1($self, $oid_b, {
@@ -77,8 +79,8 @@ EOM
                                                 path_a => $pa,
                                                 path_b => $pb
                                         });
-                $ta .= "M 100644 $xa ".git_quote($pa)."\n" if $xa;
-                $tb .= "M 100644 $xb ".git_quote($pb)."\n" if $xb;
+                $ta .= "M $ma $xa ".git_quote($pa)."\n" if $xa;
+                $tb .= "M $mb $xb ".git_quote($pb)."\n" if $xb;
         }
         my $rw = $self->{gits}->[-1]; # has all known alternates
         if (!$rw->{-tmp}) {
@@ -148,6 +150,15 @@ sub extract_oids { # Eml each_part callback
                 if (scalar(@top) >= 4 &&
                                 $top[1] =~ $PublicInbox::ViewDiff::IS_OID &&
                                 $top[0] =~ $PublicInbox::ViewDiff::IS_OID) {
+                        my ($ma, $mb);
+                        $x =~ /^old mode $MODE/sm and $ma = $1;
+                        $x =~ /^new mode $MODE/sm and $mb = $1;
+                        if (!defined($ma) && $x =~
+                                /^index [a-z0-9]+\.\.[a-z0-9]+ $MODE/sm) {
+                                $ma = $mb = $1;
+                        }
+                        $ma //= '100644';
+                        $mb //= $ma;
                         my ($oid_a, $oid_b, $pa, $pb) = splice(@top, 0, 4);
                         $pa eq '/dev/null' or
                                 $pa = (split(m'/', git_unquote($pa), 2))[1];
@@ -155,7 +166,7 @@ sub extract_oids { # Eml each_part callback
                                 $pb = (split(m'/', git_unquote($pb), 2))[1];
                         $blobs->{$oid_a} //= undef;
                         $blobs->{$oid_b} //= undef;
-                        push @$ctxq, $oid_a, $oid_b, $pa, $pb;
+                        push @$ctxq, $oid_a, $oid_b, $pa, $pb, $ma, $mb;
                 } elsif ($ctxq) {
                         my @out;
                         for (split(/^/sm, $x)) {