summaryrefslogtreecommitdiff
path: root/dgit
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2018-10-20 10:21:58 -0700
committerSean Whitton <spwhitton@spwhitton.name>2018-10-20 10:21:58 -0700
commit4ea49240ddaa77bb4e290f9018727805ef87efc6 (patch)
treeecc5ef8ce55fa7cce83ebc9554edeb29920ea2cf /dgit
parentc1594eccda40a6a40bb2eb330a13578f330b3cc9 (diff)
parent16d99b2680f6c4e41c7740f542ca064455b4f5a4 (diff)
Merge tag 'debian/8.0' into stretch-bpo
dgit release 8.0 for unstable (sid) [dgit] [dgit distro=debian] # gpg: Signature made Sat 13 Oct 2018 04:01:49 PM MST # gpg: using RSA key 559AE46C2D6B6D3265E7CBA1E3E3392348B50D39 # gpg: Can't check signature: No public key
Diffstat (limited to 'dgit')
-rwxr-xr-xdgit204
1 files changed, 151 insertions, 53 deletions
diff --git a/dgit b/dgit
index 4cc5684..e104838 100755
--- a/dgit
+++ b/dgit
@@ -101,7 +101,11 @@ our %forceopts = map { $_=>0 }
our %format_ok = map { $_=>1 } ("1.0","3.0 (native)","3.0 (quilt)");
our $suite_re = '[-+.0-9a-z]+';
-our $cleanmode_re = 'dpkg-source(?:-d)?|git|git-ff|check|none';
+our $cleanmode_re = qr{(?: dpkg-source (?: -d )? (?: ,no-check | ,all-check )?
+ | git | git-ff
+ | check (?: ,ignores )?
+ | none
+ )}x;
our $git_authline_re = '^([^<>]+) \<(\S+)\> (\d+ [-+]\d+)$';
our $splitbraincache = 'dgit-intern/quilt-cache';
@@ -379,6 +383,10 @@ sub branch_is_gdr ($) {
printdebug "branch_is_gdr $walk ?-octopus NO\n";
return 0;
}
+ if (!@parents) {
+ printdebug "branch_is_gdr $walk origin\n";
+ return 0;
+ }
if ($get_patches->($walk) ne $tip_patches) {
# Our parent added, removed, or edited patches, and wasn't
# a gdr make-patches commit. gdr make-patches probably
@@ -786,6 +794,9 @@ sub git_get_config ($) {
@$l==1 or badcfg
f_ "multiple values for %s (in %s git config)", $c, $src
if @$l > 1;
+ $l->[0] =~ m/\n/ and badcfg f_
+ "value for config option %s (in %s git config) contains newline(s)!",
+ $c, $src;
return $l->[0];
}
return undef;
@@ -2220,18 +2231,18 @@ sub generate_commits_from_dsc () {
printdebug "considering saving $f: ";
- if (link $f, $upper_f) {
+ if (rename_link_xf 1, $f, $upper_f) {
printdebug "linked.\n";
- } elsif ((printdebug "($!) "),
+ } elsif ((printdebug "($@) "),
$! != EEXIST) {
- fail f_ "saving %s: %s", "$buildproductsdir/$f", $!;
+ fail f_ "saving %s: %s", "$buildproductsdir/$f", $@;
} elsif (!$refetched) {
printdebug "no need.\n";
- } elsif (link $f, "$upper_f,fetch") {
+ } elsif (rename_link_xf 1, $f, "$upper_f,fetch") {
printdebug "linked (using ...,fetch).\n";
- } elsif ((printdebug "($!) "),
+ } elsif ((printdebug "($@) "),
$! != EEXIST) {
- fail f_ "saving %s: %s", "$buildproductsdir/$f,fetch", $!;
+ fail f_ "saving %s: %s", "$buildproductsdir/$f,fetch", $@;
} else {
printdebug "cannot.\n";
}
@@ -3813,12 +3824,25 @@ sub pull () {
}
sub check_not_dirty () {
- foreach my $f (qw(local-options local-patch-header)) {
- if (stat_exists "debian/source/$f") {
- fail f_ "git tree contains debian/source/%s", $f;
+ my @forbid = qw(local-options local-patch-header);
+ @forbid = map { "debian/source/$_" } @forbid;
+ foreach my $f (@forbid) {
+ if (stat_exists $f) {
+ fail f_ "git tree contains %s", $f;
}
}
+ my @cmd = (@git, qw(status -uall --ignored --porcelain));
+ push @cmd, qw(debian/source/format debian/source/options);
+ push @cmd, @forbid;
+
+ my $bad = cmdoutput @cmd;
+ if (length $bad) {
+ fail +(__
+ "you have uncommitted changes to critical files, cannot continue:\n").
+ $bad;
+ }
+
return if $includedirty;
git_check_unmodified();
@@ -4012,7 +4036,7 @@ END
sub pseudomerge_make_commit ($$$$ $$) {
my ($clogp, $dgitview, $archive_hash, $i_arch_v,
$msg_cmd, $msg_msg) = @_;
- progress f_ "Declaring that HEAD inciudes all changes in %s...",
+ progress f_ "Declaring that HEAD includes all changes in %s...",
$i_arch_v->[0];
my $tree = cmdoutput qw(git rev-parse), "${dgitview}:";
@@ -4068,7 +4092,7 @@ sub splitbrain_pseudomerge ($$$$) {
my $i_arch_v = pseudomerge_version_check($clogp, $archive_hash);
if (!defined $overwrite_version) {
- progress __ "Checking that HEAD inciudes all changes in archive...";
+ progress __ "Checking that HEAD includes all changes in archive...";
}
return $dgitview if is_fast_fwd $archive_hash, $dgitview;
@@ -4519,11 +4543,11 @@ ENDT
if ($sourceonlypolicy eq 'ok') {
} elsif ($sourceonlypolicy eq 'always') {
forceable_fail [qw(uploading-binaries)],
- __ "uploading binaries, although distroy policy is source only"
+ __ "uploading binaries, although distro policy is source only"
if $hasdebs;
} elsif ($sourceonlypolicy eq 'never') {
forceable_fail [qw(uploading-source-only)],
- __ "source-only upload, although distroy policy requires .debs"
+ __ "source-only upload, although distro policy requires .debs"
if !$hasdebs;
} elsif ($sourceonlypolicy eq 'not-wholly-new') {
forceable_fail [qw(uploading-source-only)],
@@ -5499,7 +5523,8 @@ sub quiltify ($$$$) {
printdebug "considering C=$c->{Commit} P=$p->{Commit}\n";
my @cmd= (@git, qw(diff-tree -r --name-only),
- $p->{Commit},$c->{Commit}, qw(-- debian/patches .pc));
+ $p->{Commit},$c->{Commit},
+ qw(-- debian/patches .pc debian/source/format));
my $patchstackchange = cmdoutput @cmd;
if (length $patchstackchange) {
$patchstackchange =~ s/\n/,/g;
@@ -5800,7 +5825,9 @@ sub quilt_fixup_singlepatch ($$$) {
changedir "..";
runcmd @dpkgsource, qw(-x), (srcfn $version, ".dsc");
rename srcfn("$upstreamversion", "/debian/patches"),
- "work/debian/patches";
+ "work/debian/patches"
+ or $!==ENOENT
+ or confess "install d/patches: $!";
changedir "work";
commit_quilty_patch();
@@ -6176,34 +6203,71 @@ sub maybe_unapply_patches_again () {
#----- other building -----
-our $clean_using_builder;
-# ^ tree is to be cleaned by dpkg-source's builtin idea that it should
-# clean the tree before building (perhaps invoked indirectly by
-# whatever we are using to run the build), rather than separately
-# and explicitly by us.
+sub clean_tree_check_git ($$) {
+ my ($honour_ignores, $message) = @_;
+ my @cmd = (@git, qw(clean -dn));
+ push @cmd, qw(-x) unless $honour_ignores;
+ my $leftovers = cmdoutput @cmd;
+ if (length $leftovers) {
+ print STDERR $leftovers, "\n" or confess $!;
+ fail $message;
+ }
+}
+
+sub clean_tree_check_git_wd ($) {
+ my ($message) = @_;
+ return if $cleanmode =~ m{no-check};
+ return if $patches_applied_dirtily; # yuk
+ clean_tree_check_git +($cleanmode !~ m{all-check}),
+ (f_ <<END, $message);
+%s
+If this is just missing .gitignore entries, use a different clean
+mode, eg --clean=dpkg-source,no-check (-wdu/-wddu) to ignore them
+or --clean=git (-wg/-wgf) to use \`git clean' instead.
+END
+}
+
+sub clean_tree_check () {
+ # Not yet fully implemented.
+ # This function needs to not care about modified but tracked files.
+ # That was done by check_not_dirty, and by now we may have run
+ # the rules clean target which might modify tracked files (!)
+ if ($cleanmode =~ m{^check}) {
+ clean_tree_check_git +($cleanmode =~ m{ignores}), __
+ "tree contains uncommitted files and --clean=check specified";
+ } elsif ($cleanmode =~ m{^dpkg-source}) {
+ clean_tree_check_git_wd __
+ "tree contains uncommitted files (NB dgit didn't run rules clean)";
+ } elsif ($cleanmode =~ m{^git}) {
+ # If we were actually cleaning these files would be summarily
+ # deleted. Since we're not, and not using the working tree
+ # anyway, we can just ignore them - nothing will use them.
+ } elsif ($cleanmode eq 'none') {
+ } else {
+ confess "$cleanmode ?";
+ }
+}
sub clean_tree () {
- return if $clean_using_builder;
- if ($cleanmode eq 'dpkg-source') {
- maybe_apply_patches_dirtily();
- runcmd_ordryrun_local @dpkgbuildpackage, qw(-T clean);
- } elsif ($cleanmode eq 'dpkg-source-d') {
+ # We always clean the tree ourselves, rather than leave it to the
+ # builder (dpkg-source, or soemthing which calls dpkg-source).
+ if ($cleanmode =~ m{^dpkg-source}) {
+ my @cmd = @dpkgbuildpackage;
+ push @cmd, qw(-d) if $cleanmode =~ m{^dpkg-source-d};
+ push @cmd, qw(-T clean);
maybe_apply_patches_dirtily();
- runcmd_ordryrun_local @dpkgbuildpackage, qw(-d -T clean);
+ runcmd_ordryrun_local @cmd;
+ clean_tree_check_git_wd __
+ "tree contains uncommitted files (after running rules clean)";
} elsif ($cleanmode eq 'git') {
runcmd_ordryrun_local @git, qw(clean -xdf);
} elsif ($cleanmode eq 'git-ff') {
runcmd_ordryrun_local @git, qw(clean -xdff);
- } elsif ($cleanmode eq 'check') {
- my $leftovers = cmdoutput @git, qw(clean -xdn);
- if (length $leftovers) {
- print STDERR $leftovers, "\n" or confess $!;
- fail __
- "tree contains uncommitted files and --clean=check specified";
- }
+ } elsif ($cleanmode =~ m{^check}) {
+ clean_tree_check();
} elsif ($cleanmode eq 'none') {
} else {
- die "$cleanmode ?";
+ confess "$cleanmode ?";
}
}
@@ -6239,9 +6303,18 @@ sub build_prep_early () {
sub build_prep ($) {
my ($wantsrc) = @_;
build_prep_early();
- # clean the tree if we're trying to include dirty changes in the
- # source package, or we are running the builder in $maindir
- clean_tree() if $includedirty || ($wantsrc & WANTSRC_BUILDER);
+ if (!building_source_in_playtree() || ($wantsrc & WANTSRC_BUILDER)) {
+ # Clean the tree because we're going to use the contents of
+ # $maindir. (We trying to include dirty changes in the source
+ # package, or we are running the builder in $maindir.)
+ clean_tree();
+ } else {
+ # We don't actually need to do anything in $maindir, but we
+ # should do some kind of cleanliness check because (i) the
+ # user may have forgotten a `git add', and (ii) if the user
+ # said -wc we should still do the check.
+ clean_tree_check();
+ }
build_maybe_quilt_fixup();
if ($rmchanges) {
my $pat = changespat $version;
@@ -6512,9 +6585,7 @@ sub cmd_gbp_build {
build_source();
midbuild_checkchanges_vanilla $wantsrc;
} else {
- if (!$clean_using_builder) {
- push @cmd, '--git-cleaner=true';
- }
+ push @cmd, '--git-cleaner=true';
}
maybe_unapply_patches_again();
if ($wantsrc & WANTSRC_BUILDER) {
@@ -6562,6 +6633,24 @@ sub build_source {
}
} else {
$leafdir = basename $maindir;
+
+ if ($buildproductsdir ne '..') {
+ # Well, we are going to run dpkg-source -b which consumes
+ # origs from .. and generates output there. To make this
+ # work when the bpd is not .. , we would have to (i) link
+ # origs from bpd to .. , (ii) check for files that
+ # dpkg-source -b would/might overwrite, and afterwards
+ # (iii) move all the outputs back to the bpd (iv) except
+ # for the origs which should be deleted from .. if they
+ # weren't there beforehand. And if there is an error and
+ # we don't run to completion we would necessarily leave a
+ # mess. This is too much. The real way to fix this
+ # is for dpkg-source to have bpd support.
+ confess unless $includedirty;
+ fail __
+ "--include-dirty not supported with --build-products-dir, sorry";
+ }
+
changedir '..';
}
runcmd_ordryrun_local @cmd, $leafdir;
@@ -6578,8 +6667,8 @@ sub build_source {
my $mv = sub {
my ($why, $l) = @_;
printdebug " renaming ($why) $l\n";
- rename "$l", bpd_abs()."/$l"
- or fail f_ "put in place new built file (%s): %s", $l, $!;
+ rename_link_xf 0, "$l", bpd_abs()."/$l"
+ or fail f_ "put in place new built file (%s): %s", $l, $@;
};
foreach my $l (split /\n/, getfield $dsc, 'Files') {
$l =~ m/\S+$/ or next;
@@ -6808,7 +6897,7 @@ sub cmd_import_dsc {
fail f_ <<END, $dsc_hash
.dsc contains Dgit field referring to object %s
Your git tree does not have that object. Try `git fetch' from a
-plausible server (browse.dgit.d.o? alioth?), and try the import-dsc again.
+plausible server (browse.dgit.d.o? salsa?), and try the import-dsc again.
END
}
if ($oldhash && !is_fast_fwd $oldhash, $dsc_hash) {
@@ -6895,7 +6984,7 @@ END
import_dsc_result $dstbranch, $newhash,
"dgit import-dsc: $info",
- f_ "results are in in git ref %s", $dstbranch;
+ f_ "results are in git ref %s", $dstbranch;
}
sub pre_archive_api_query () {
@@ -7198,15 +7287,18 @@ sub parseopts () {
} elsif (s/^-wgf$//s) {
push @ropts, $&;
$cleanmode = 'git-ff';
- } elsif (s/^-wd$//s) {
+ } elsif (s/^-wd(d?)([na]?)$//s) {
push @ropts, $&;
$cleanmode = 'dpkg-source';
- } elsif (s/^-wdd$//s) {
- push @ropts, $&;
- $cleanmode = 'dpkg-source-d';
+ $cleanmode .= '-d' if $1;
+ $cleanmode .= ',no-check' if $2 eq 'n';
+ $cleanmode .= ',all-check' if $2 eq 'a';
} elsif (s/^-wc$//s) {
push @ropts, $&;
$cleanmode = 'check';
+ } elsif (s/^-wci$//s) {
+ push @ropts, $&;
+ $cleanmode = 'check,ignores';
} elsif (s/^-c([^=]*)\=(.*)$//s) {
push @git, '-c', $&;
$gitcfgs{cmdline}{$1} = [ $2 ];
@@ -7245,7 +7337,7 @@ sub check_env_sanity () {
chomp $@;
fail f_ <<END, $@;
On entry to dgit, %s
-This is a bug produced by something in in your execution environment.
+This is a bug produced by something in your execution environment.
Giving up.
END
}
@@ -7314,11 +7406,14 @@ sub parseopts_late_defaults () {
if (!defined $cleanmode) {
local $access_forpush;
- $cleanmode = access_cfg('clean-mode', 'RETURN-UNDEF');
+ $cleanmode = access_cfg('clean-mode-newer', 'RETURN-UNDEF');
+ $cleanmode = undef if $cleanmode && $cleanmode !~ m/^$cleanmode_re$/;
+
+ $cleanmode //= access_cfg('clean-mode', 'RETURN-UNDEF');
$cleanmode //= 'dpkg-source';
badcfg f_ "unknown clean-mode \`%s'", $cleanmode unless
- $cleanmode =~ m/^($cleanmode_re)$(?!\n)/s;
+ $cleanmode =~ m/$cleanmode_re/;
}
$buildproductsdir //= access_cfg('build-products-dir', 'RETURN-UNDEF');
@@ -7351,7 +7446,10 @@ $cmd =~ y/-/_/;
my $pre_fn = ${*::}{"pre_$cmd"};
$pre_fn->() if $pre_fn;
-record_maindir if $invoked_in_git_tree;
+if ($invoked_in_git_tree) {
+ changedir_git_toplevel();
+ record_maindir();
+}
git_slurp_config();
my $fn = ${*::}{"cmd_$cmd"};