From efc3496563ecfdc6fba48b92a296b7a056ad4b5a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 29 Jan 2017 18:46:13 +0000 Subject: [PATCH] git-debrebase: WIP classification core done? --- git-debrebase | 143 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 126 insertions(+), 17 deletions(-) diff --git a/git-debrebase b/git-debrebase index 8911c057..bb2d91a2 100755 --- a/git-debrebase +++ b/git-debrebase @@ -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 + -- 2.30.2