chiark / gitweb /
git-debrebase: WIP classification core done?
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 29 Jan 2017 18:46:13 +0000 (18:46 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 16 Jun 2018 11:25:49 +0000 (12:25 +0100)
git-debrebase

index 8911c05..bb2d91a 100755 (executable)
@@ -46,11 +46,126 @@ sub get_commit ($) {
     return ($`,$');
 }
 
-memoize('get_commit');
+sub D_DEB ()     { return 0x1; }
+sub D_UPS ()     { return 0x2; }
+sub D_PAT_ADD () { return 0x4; }
+sub D_PAT_OTH () { return 0x8; }
 
-sub DDEB () { return 0x1; }
-sub DUPS () { return 0x2; }
-sub DPAT () { return 0x4; }
+sub classify ($) {
+    my ($objid) = @_;
+
+    my ($h,$m) = get_commit $objid;
+
+    my ($t) = $h =~ m/^tree (\w+)$/m or die $cur;
+    my (@ph) = $h =~ m/^parent (\w+)$/m;
+    my @p;
+
+    my $r = {
+       CommitId => $objid,
+       Hdr => $hdr,
+       Msg => $m,
+       Parents => \@p,
+    };
+
+    foreach my $ph (@ph) {
+       push @p, {
+            Ix => $#p,
+            CommitId => $ph,
+            Differs => (get_differs $t, $ph),
+        };
+    }
+
+    if (@p == 1) {
+       my $d = $r->{Parents}[0]{Differs};
+       if ($d == D_DPAT_ADD) {
+           return $classify->(qw(AddPatches));
+       } elsif ($d & (D_DPAT_ADD|D_DPAT_OTH)) {
+           return $unknown->("edits debian/patches");
+       } elsif ($d == D_DEB) {
+           return $classify->(qw(Packaging));
+       } elsif ($d == D_UPS) {
+           return $classify->(qw(Upstream));
+       } elsif ($d == D_DEB|D_UPS) {
+           return $classify->(qw(Mixed));
+       } elsif ($d == 0) {
+           return $unknown->("no changes");
+       } else {
+           confess "internal error $objid ?";
+       }
+    }
+    if (!@p) {
+       return $unknown->("origin commit");
+    }
+
+    my @identical = grep { !$_->{Differs} } @p;
+    if (@p == 2 && @identical == 1) {
+       my @overwritten = grep { $_->{Differs} } @p;
+       confess "internal error $objid ?" unless @overwritten==1;
+       return $classify->(qw(Pseudomerge),
+                          Overwritten => $overwritten[0],
+                          Contributor => $identical[0]);
+    }
+    if (@p == 2 && @identical == 2) {
+       my @bytime = nsort_by {
+           my ($ph,$pm) = get_commit $_->{CommitId};
+           $ph =~ m/^committer .* (\d+) [-+]\d+$/m or die "$_->{CommitId} ?";
+           $1;
+       } @p;
+       return $classify->(qw(Pseudomerge),
+                          Xtype => qw(Ambiguous),
+                          Overwritten => $bytime[0],
+                          Contributyor => $bytime[1]);
+    }
+    foreach my $p (@p) {
+       my ($type) = git_cat_file "$p^1";
+       $p->{IsOrigin} = $type eq 'missing';
+    }
+    if (!grep { !$_->{IsOrigin} } @p
+       && $m =~ m{^\[dgit import unpatched .*\]$}m) {
+       return $classify->(qw(DgitImport));
+    }
+
+    my ($stype, $series) = git_cat_file "$t:debian/patches/series";
+    my $haspatches = $stype ne 'missing' && $series =~ m/^\s*[^#\n\t ]/m;
+
+    # how to decide about l/r ordering of breakwater merges
+    # git --topo-order prefers to expand 2nd parent first
+    # easy rune to look for debian/ history so that should
+    # be 1st parent.
+    if (@p == 2 &&
+       !$haspatches &&
+       !$p[0]{IsOrigin} && # breakwater merge never starts with an origin
+       !($p[0]{Differs} & ~D_DEB) &&
+       !($p[1]{Differs} & ~D_UPS)) {
+       return $classify->(qw(BreakwaterUpstreamMerge),
+                          Upstream => $p[1]);
+    }
+
+    return $unknown->("complex merge");
+}
+
+       ((git_cat_file "$t:debian/patches/series"
+       
+    
+    my @
+                          
+       
+
+           return $r;
+           $r->{Type} = '
+           $r->{Type} = '
+           return 
+           # changes on debian/patches, discard it
+           
+           $cur = $p[0];
+           next;
+       }
+       if ($d & DPAT) {
+           
+
+    ($r->{Tree},) = 
+    
+                   
 
 sub launder () {
     # go through commits backwards
@@ -58,19 +173,6 @@ sub launder () {
     my (@deb_cl, @ups_cl);
     my $cur = git_rev_parse('HEAD');
     for (;;) {
-       my ($h,$m) = get_commit $cur;
-       my ($t) = $h =~ m/^tree (\w+)$/m;  defined $t or die $cur;
-       my (@p) = $h =~ m/^parent (\w+)$/m;
-       my (@d) = map { get_differs $t, $_ } @p;
-       if (@p == 1) {
-           my ($d) = $d[0];
-           if ($d == DPAT) {
-               # changes on debian/patches, discard it
-               $cur = $p[0];
-               next;
-           }
-           if ($d & DPAT) {
-           
 }   
 
 if ($ARGV[0] eq 'launder') {
@@ -80,3 +182,10 @@ if ($ARGV[0] eq 'launder') {
 use Data::Dumper;
 print Dumper(cfg('wombat.foo.bar'));
 
+
+
+
+
+ when starting must record original start (for ff)
+ and new rebase basis
+