X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=dgit;h=94f915efe5ab16836fbe1f9f36f4b2f4f46983f9;hb=47d5cc045b10fc6993e9cfa7c9b6dfd61873702b;hp=c3b66f15f75ce1acb588edb867e7cf234e4adc68;hpb=4cdfc872d003b1e78aa25ffacee66f8f1b0d82c1;p=dgit.git diff --git a/dgit b/dgit index c3b66f15..94f915ef 100755 --- a/dgit +++ b/dgit @@ -117,6 +117,7 @@ our (@gpg) = qw(gpg); our (@sbuild) = qw(sbuild); our (@ssh) = 'ssh'; our (@dgit) = qw(dgit); +our (@git_debrebase) = qw(git-debrebase); our (@aptget) = qw(apt-get); our (@aptcache) = qw(apt-cache); our (@dpkgbuildpackage) = (qw(dpkg-buildpackage), @dpkg_source_ignores); @@ -136,6 +137,7 @@ our %opts_opt_map = ('dget' => \@dget, # accept for compatibility 'ssh' => \@ssh, 'dgit' => \@dgit, 'git' => \@git, + 'git-debrebase' => \@git_debrebase, 'apt-get' => \@aptget, 'apt-cache' => \@aptcache, 'dpkg-source' => \@dpkgsource, @@ -290,6 +292,32 @@ sub dgit_privdir () { our $dgit_privdir_made //= ensure_a_playground 'dgit'; } +sub branch_gdr_info ($$) { + my ($symref, $head) = @_; + my ($status, $msg, $current, $ffq_prev, $gdrlast) = + gdr_ffq_prev_branchinfo($symref); + return () unless $status eq 'branch'; + $ffq_prev = git_get_ref $ffq_prev; + $gdrlast = git_get_ref $gdrlast; + $gdrlast &&= is_fast_fwd $gdrlast, $head; + return ($ffq_prev, $gdrlast); +} + +sub branch_is_gdr ($$) { + my ($symref, $head) = @_; + my ($ffq_prev, $gdrlast) = branch_gdr_info($symref, $head); + return 0 unless $ffq_prev || $gdrlast; + return 1; +} + +sub branch_is_gdr_unstitched_ff ($$$) { + my ($symref, $head, $ancestor) = @_; + my ($ffq_prev, $gdrlast) = branch_gdr_info($symref, $head); + return 0 unless $ffq_prev; + return 0 unless is_fast_fwd $ancestor, $ffq_prev; + return 1; +} + #---------- remote protocol support, common ---------- # remote push initiator/responder protocol: @@ -3365,38 +3393,57 @@ sub open_main_gitattrs () { return $gai; } +our $gitattrs_ourmacro_re = qr{^\[attr\]dgit-defuse-attrs\s}; + sub is_gitattrs_setup () { + # return values: + # trueish + # 1: gitattributes set up and should be left alone + # falseish + # 0: there is a dgit-defuse-attrs but it needs fixing + # undef: there is none my $gai = open_main_gitattrs(); return 0 unless $gai; while (<$gai>) { - return 1 if m{^\[attr\]dgit-defuse-attrs\s}; + next unless m{$gitattrs_ourmacro_re}; + return 1 if m{\s-working-tree-encoding\s}; + printdebug "is_gitattrs_setup: found old macro\n"; + return 0; } $gai->error and die $!; - return 0; + printdebug "is_gitattrs_setup: found nothing\n"; + return undef; } sub setup_gitattrs (;$) { my ($always) = @_; return unless $always || access_cfg_bool(1, 'setup-gitattributes'); - if (is_gitattrs_setup()) { + my $already = is_gitattrs_setup(); + if ($already) { progress < $af.new" or die $!; - print GAO <) { + if (m{$gitattrs_ourmacro_re}) { + die unless defined $already; + $_ = $new; + } chomp; print GAO $_, "\n" or die $!; } @@ -3431,7 +3478,7 @@ sub check_gitattrs ($$) { # oh dear, found one print STDERR <", $pmf or die "$pmf $!"; print MC <{Commit} differs from tree implied by ". - " debian/patches (tree object $oldtiptree)"; - } + quiltify_nofix_bail " $c->{Commit}", " (tree object $oldtiptree)"; if ($quilt_mode eq 'smash') { printdebug " search quitting smash\n"; last; @@ -5415,6 +5477,32 @@ END my $clogp = parsechangelog(); my $headref = git_rev_parse('HEAD'); + my $symref = git_get_symref(); + + if ($quilt_mode eq 'linear' + && !$fopts->{'single-debian-patch'} + && branch_is_gdr($symref, $headref)) { + # This is much faster. It also makes patches that gdr + # likes better for future updates without laundering. + # + # However, it can fail in some casses where we would + # succeed: if there are existing patches, which correspond + # to a prefix of the branch, but are not in gbp/gdr + # format, gdr will fail (exiting status 7), but we might + # be able to figure out where to start linearising. That + # will be slower so hopefully there's not much to do. + my @cmd = (@git_debrebase, + qw(--noop-ok -funclean-mixed -funclean-ordering + make-patches --quiet-would-amend)); + # We tolerate soe snags that gdr wouldn't, by default. + if (act_local()) { + $!=0; $?=-1; + failedcmd @cmd if system @cmd and $?!=7; + } else { + dryrun_report @cmd; + } + $headref = git_rev_parse('HEAD'); + } prep_ud(); changedir $playground;