chiark / gitweb /
dgit: Reject all git config options containing newlines
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 2f2b50918afe35c7a6a1ab33e632fcdd660fa37f..a37e89796fd9c784d9588f1f7e054212eabe70d0 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -790,6 +790,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;
@@ -2224,18 +2227,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";
        }
@@ -3817,12 +3820,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();
@@ -5503,7 +5519,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;
@@ -5804,7 +5821,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();
@@ -6566,6 +6585,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;
@@ -6582,8 +6619,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;
@@ -7355,7 +7392,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"};