summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Debian/Dgit.pm16
-rw-r--r--Makefile3
-rw-r--r--debian/changelog100
-rw-r--r--debian/tests/control32
-rwxr-xr-xdgit183
-rw-r--r--dgit.175
-rw-r--r--dgit.787
-rwxr-xr-xgit-debrebase52
-rw-r--r--git-debrebase.1.pod6
-rwxr-xr-xtests/enumerate-tests2
-rw-r--r--tests/lib15
-rw-r--r--tests/lib-core6
-rw-r--r--tests/lib-gdr2
-rw-r--r--tests/lib-import-chk8
-rwxr-xr-xtests/setup/gdr-convert-gbp3
-rwxr-xr-xtests/setup/gdr-convert-gbp-noarchive1
-rwxr-xr-xtests/setup/gnupg6
-rwxr-xr-xtests/tartree-edit2
-rwxr-xr-xtests/tests/checkout59
-rwxr-xr-xtests/tests/gdr-makepatches79
-rwxr-xr-xtests/tests/gdr-newupstream8
-rwxr-xr-xtests/tests/gdr-viagit1
-rwxr-xr-xtests/tests/import-native2
-rwxr-xr-xtests/tests/manpages-format78
-rwxr-xr-xtests/tests/overwrite-splitbrains2
-rwxr-xr-xtests/tests/push-newrepeat21
-rwxr-xr-xtests/tests/sourceonlypolicy38
-rwxr-xr-xtests/tests/trustingpolicy-replay5
-rwxr-xr-xtests/tstunt/gpg18
-rwxr-xr-xtests/tstunt/gpg-withagent68
30 files changed, 802 insertions, 106 deletions
diff --git a/Debian/Dgit.pm b/Debian/Dgit.pm
index 57b79e8..5106f85 100644
--- a/Debian/Dgit.pm
+++ b/Debian/Dgit.pm
@@ -52,6 +52,7 @@ BEGIN {
git_get_ref git_get_symref git_for_each_ref
git_for_each_tag_referring is_fast_fwd
git_check_unmodified
+ git_reflog_action_msg git_update_ref_cmd
$package_re $component_re $deliberately_re
$distro_re $versiontag_re $series_filename_re
$extra_orig_namepart_re
@@ -492,6 +493,21 @@ sub is_fast_fwd ($$) {
}
}
+sub git_reflog_action_msg ($) {
+ my ($msg) = @_;
+ my $rla = $ENV{GIT_REFLOG_ACTION};
+ $msg = "$rla: $msg" if length $rla;
+ return $msg;
+}
+
+sub git_update_ref_cmd {
+ # returns qw(git update-ref), qw(-m), @_
+ # except that message may be modified to honour GIT_REFLOG_ACTION
+ my $msg = shift @_;
+ $msg = git_reflog_action_msg $msg;
+ return qw(git update-ref -m), $msg, @_;
+}
+
sub changedir ($) {
my ($newdir) = @_;
printdebug "CD $newdir\n";
diff --git a/Makefile b/Makefile
index de28f4d..605b580 100644
--- a/Makefile
+++ b/Makefile
@@ -119,6 +119,9 @@ installdirs-infra:
$(INSTALL_DIR) $(DESTDIR)$(bindir) $(DESTDIR)$(infraexamplesdir) \
$(addprefix $(DESTDIR)$(perldir)/, $(dir $(INFRA_PERLMODULES)))
+list-manpages:
+ @echo $(MANPAGES)
+
check installcheck:
clean distclean mostlyclean maintainer-clean:
diff --git a/debian/changelog b/debian/changelog
index 9b64e20..837bab1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,103 @@
+dgit (5.8) unstable; urgency=medium
+
+ Bugfixes:
+ * dgit, git-debrebase: Properly make patches even if an awkward
+ .gitignore ignores the things in debian/patches. Closes:#903130.
+ * git-debrebase status: Fix commit reporting. Closes:903131.
+ * git-debrebase new-upstream: Add a -1 revision if the user
+ didn't supply one. Closes:#903127.
+ * git-debrebase: Improve grammar if one blocking snag.
+ * dgit(1): Unscramble push[-source] descriptions. Closes:#903116.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Sun, 08 Jul 2018 11:42:41 +0100
+
+dgit (5.7) unstable; urgency=medium
+
+ New feature:
+ * dgit checkout: new subcommand. Closes:#878443.
+ * dgit: Check that entirely-new uploads to Debian are not
+ source-only-uploads, as those are REJECTed. Closes:#801435.
+
+ Bugfixes:
+ * dgit(7): Mention git-debrebase and gbp pq alongside git-dpm,
+ in the comment about handling patch stacks.
+ * dgit update-vcs-git: Honour --package properly.
+ * test suite: Always pass LC_COLLATE=C to sort(1). Closes:#903006.
+ * test suite: Fix trustingpolicy-replay & dput-ng. Closes:#903007.
+ * test suite: Test dput-ng compatibility.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Thu, 05 Jul 2018 15:02:21 +0100
+
+dgit (5.6) unstable; urgency=medium
+
+ * Merge the experimental branch containing the fianl
+ version of the test suite gnupg workarounds. Empirically,
+ - The tests now pass (most of the time, at least) in
+ current Debian unstable, whereas 5.5's fail utterly.
+ - There is still occasional lossage. So when running tests
+ in a loop (eg to test ever commit), it is still good to set
+ DGIT_TEST_RETRY_COUNT=3 (say).
+
+ * test suite: Test that manpages format with only expected warnings.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Sun, 01 Jul 2018 00:41:20 +0100
+
+dgit (5.5+exp9) experimental; urgency=medium
+
+ * test suite: Explicitly start/stop the gnupg agent, around
+ each call to gnupg. Apropos of #902316 (and #868550).
+
+ * Separate changelog entries for the following test attempts
+ in experimental have been elided:
+ dgit (5.5+exp8) experimental; urgency=medium
+ dgit (5.5+exp7) experimental; urgency=medium
+ dgit (5.5+exp6) experimental; urgency=medium
+ dgit (5.5+exp5) experimental; urgency=medium
+ dgit (5.5+exp4) experimental; urgency=medium
+ dgit (5.5+exp3) experimental; urgency=medium
+ dgit (5.5+exp2) experimental; urgency=medium
+ dgit (5.4+exp1) experimental; urgency=medium
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Sat, 30 Jun 2018 19:03:00 +0100
+
+dgit (5.5) unstable; urgency=medium
+
+ * Add missing comma in debian/control. Closes:#902578.
+ * dgit(1): Fix a wrong reference to \fp, which should be \fP.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Thu, 28 Jun 2018 13:25:21 +0100
+
+dgit (5.4) unstable; urgency=medium
+
+ Improvements:
+ * dgit(1): Better description of --overwrite. Somewhat
+ apropos of discussion in #902534.
+
+ Bugfixes:
+ * test suite: gdr-viagit, gdr-newupstream: Do not spuriously
+ fail if gnupg not serendipitously installed. Closes:#902559.
+ * Fix bug ref to #865444 in previous changelog entry.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Wed, 27 Jun 2018 23:13:42 +0100
+
+dgit (5.3) unstable; urgency=medium
+
+ Bugfixes:
+ * dgit: Do not introduce duplicate origs in .changes files,
+ eg if the .changes already has that orig. Closes:#869146.
+ * Honour GIT_REFLOG_ACTION everywhere. Closes:#901935.
+ * git-debrebase new-upstream: Provide better reflog entries
+ by setting GIT_REFLOG_ACTION. Closes:#901925.
+
+ Improvements:
+ * Better message formatting when --overwrite may be needed,
+ and a note about first dgit push in dgit(1). Closes:891031.
+ * dgit(7): Add discussion of quilt fixup error messages,
+ and add cross-references to dgit(1) and the actual error.
+ Somewhat apropos of #865444.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Wed, 27 Jun 2018 14:00:31 +0100
+
dgit (5.2~bpo9+1) stretch-backports; urgency=medium
* Rebuild for stretch-backports.
diff --git a/debian/tests/control b/debian/tests/control
index 378cf4c..dfd73bb 100644
--- a/debian/tests/control
+++ b/debian/tests/control
@@ -1,24 +1,24 @@
Tests: build-modes-gbp
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, git-buildpackage
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, git-buildpackage
Tests: clone-reprepro downstream-gitless
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, reprepro
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, reprepro
Tests: dpkgsourceignores-docs
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc
Restrictions: x-dgit-intree-only
Tests: defdistro-dsd-clone-drs dsd-clone-drs
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc
Restrictions: x-dgit-intree-only x-dgit-git-only
Tests: gdr-diverge-nmu gdr-diverge-nmu-dgit gdr-edits gdr-import-dgit gdr-makepatches7 gdr-subcommands
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, git-debrebase, git-buildpackage, faketime
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, git-debrebase, git-buildpackage, faketime
Tests: gdr-newupstream gdr-viagit
Tests-Directory: tests/tests
@@ -26,33 +26,41 @@ Depends: chiark-utils-bin, git-debrebase, git-buildpackage, faketime
Tests: gitattributes
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bsdgames, man-db, git-man
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, bsdgames, man-db, git-man
Tests: hint-testsuite-triggers
Tests-Directory: tests/tests
Depends: gnupg, patch, diffutils
Restrictions: hint-testsuite-triggers
+Tests: manpages-format
+Tests-Directory: tests/tests
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, man-db, make, groff, git-debrebase
+
Tests: defdistro-mirror mirror mirror-debnewgit mirror-private
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, rsync
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, rsync
Tests: build-modes-sbuild quilt-gbp-build-modes-sbuild
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, sbuild
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, sbuild
Restrictions: x-dgit-schroot-build
Tests: sbuild-gitish
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, sbuild, man-db
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, sbuild, man-db
Restrictions: x-dgit-schroot-build
Tests: spelling
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc
Restrictions: x-dgit-git-only
-Tests: absurd-gitapply badcommit-rewrite build-modes build-modes-asplit build-modes-gbp-asplit clone-clogsigpipe clone-gitnosuite clone-nogit debpolicy-dbretry debpolicy-newreject debpolicy-quilt-gbp defdistro-rpush defdistro-setup distropatches-reject dpkgsourceignores-correct drs-clone-nogit drs-push-masterupdate drs-push-rejects dsd-clone-nogit dsd-divert fetch-localgitonly fetch-somegit-notlast gbp-orig gitconfig gitworktree import-dsc import-maintmangle import-native import-nonnative import-tarbomb inarchivecopy mismatches-contents mismatches-dscchanges multisuite newtag-clone-nogit oldnewtagalt oldtag-clone-nogit orig-include-exclude orig-include-exclude-chkquery overwrite-chkclog overwrite-junk overwrite-splitbrains overwrite-version protocol-compat push-buildproductsdir push-newpackage push-nextdgit push-source push-source-with-changes quilt quilt-gbp quilt-gbp-build-modes quilt-singlepatch quilt-splitbrains quilt-useremail rpush tag-updates test-list-uptodate trustingpolicy-replay unrepresentable version-opt
+Tests: trustingpolicy-replay
+Tests-Directory: tests/tests
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc, dput-ng
+
+Tests: absurd-gitapply badcommit-rewrite build-modes build-modes-asplit build-modes-gbp-asplit checkout clone-clogsigpipe clone-gitnosuite clone-nogit debpolicy-dbretry debpolicy-newreject debpolicy-quilt-gbp defdistro-rpush defdistro-setup distropatches-reject dpkgsourceignores-correct drs-clone-nogit drs-push-masterupdate drs-push-rejects dsd-clone-nogit dsd-divert fetch-localgitonly fetch-somegit-notlast gbp-orig gitconfig gitworktree import-dsc import-maintmangle import-native import-nonnative import-tarbomb inarchivecopy mismatches-contents mismatches-dscchanges multisuite newtag-clone-nogit oldnewtagalt oldtag-clone-nogit orig-include-exclude orig-include-exclude-chkquery overwrite-chkclog overwrite-junk overwrite-splitbrains overwrite-version protocol-compat push-buildproductsdir push-newpackage push-newrepeat push-nextdgit push-source push-source-with-changes quilt quilt-gbp quilt-gbp-build-modes quilt-singlepatch quilt-splitbrains quilt-useremail rpush sourceonlypolicy tag-updates test-list-uptodate unrepresentable version-opt
Tests-Directory: tests/tests
-Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin
+Depends: dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc
diff --git a/dgit b/dgit
index 5c9cdc3..0d36361 100755
--- a/dgit
+++ b/dgit
@@ -90,6 +90,7 @@ our $chase_dsc_distro=1;
our %forceopts = map { $_=>0 }
qw(unrepresentable unsupported-source-format
dsc-changes-mismatch changes-origs-exactly
+ uploading-binaries uploading-source-only
import-gitapply-absurd
import-gitapply-no-absurd
import-dsc-with-dgit-field);
@@ -614,6 +615,7 @@ our %defcfg = ('dgit.default.distro' => 'debian',
'dgit.default.sshpsql-dbname' => 'service=projectb',
'dgit.default.aptget-components' => 'main',
'dgit.default.dgit-tag-format' => 'new,old,maint',
+ 'dgit.default.source-only-uploads' => 'ok',
'dgit.dsc-url-proto-ok.http' => 'true',
'dgit.dsc-url-proto-ok.https' => 'true',
'dgit.dsc-url-proto-ok.git' => 'true',
@@ -628,6 +630,7 @@ our %defcfg = ('dgit.default.distro' => 'debian',
'dgit-distro.debian.git-check' => 'url',
'dgit-distro.debian.git-check-suffix' => '/info/refs',
'dgit-distro.debian.new-private-pushers' => 't',
+ 'dgit-distro.debian.source-only-uploads' => 'not-wholly-new',
'dgit-distro.debian/push.git-url' => '',
'dgit-distro.debian/push.git-host' => 'push.dgit.debian.org',
'dgit-distro.debian/push.git-user-force' => 'dgit',
@@ -1179,6 +1182,12 @@ sub file_in_archive_ftpmasterapi {
my $info = api_query($data, "file_in_archive/$pat", 1);
}
+sub package_not_wholly_new_ftpmasterapi {
+ my ($proto,$data,$pkg) = @_;
+ my $info = api_query($data,"madison?package=${pkg}&f=json");
+ return !!@$info;
+}
+
#---------- `aptget' archive query method ----------
our $aptget_base;
@@ -1342,34 +1351,55 @@ sub archive_query_aptget {
}
sub file_in_archive_aptget () { return undef; }
+sub package_not_wholly_new_aptget () { return undef; }
#---------- `dummyapicat' archive query method ----------
sub archive_query_dummycatapi { archive_query_ftpmasterapi @_; }
sub canonicalise_suite_dummycatapi { canonicalise_suite_ftpmasterapi @_; }
-sub file_in_archive_dummycatapi ($$$) {
- my ($proto,$data,$filename) = @_;
+sub dummycatapi_run_in_mirror ($@) {
+ # runs $fn with FIA open onto rune
+ my ($rune, $argl, $fn) = @_;
+
my $mirror = access_cfg('mirror');
$mirror =~ s#^file://#/# or die "$mirror ?";
- my @out;
- my @cmd = (qw(sh -ec), '
- cd "$1"
- find -name "$2" -print0 |
- xargs -0r sha256sum
- ', qw(x), $mirror, $filename);
+ my @cmd = (qw(sh -ec), 'cd "$1"; shift'."\n".$rune,
+ qw(x), $mirror, @$argl);
debugcmd "-|", @cmd;
open FIA, "-|", @cmd or die $!;
- while (<FIA>) {
- chomp or die;
- printdebug "| $_\n";
- m/^(\w+) (\S+)$/ or die "$_ ?";
- push @out, { sha256sum => $1, filename => $2 };
- }
- close FIA or die failedcmd @cmd;
+ my $r = $fn->();
+ close FIA or ($!==0 && $?==141) or die failedcmd @cmd;
+ return $r;
+}
+
+sub file_in_archive_dummycatapi ($$$) {
+ my ($proto,$data,$filename) = @_;
+ my @out;
+ dummycatapi_run_in_mirror '
+ find -name "$1" -print0 |
+ xargs -0r sha256sum
+ ', [$filename], sub {
+ while (<FIA>) {
+ chomp or die;
+ printdebug "| $_\n";
+ m/^(\w+) (\S+)$/ or die "$_ ?";
+ push @out, { sha256sum => $1, filename => $2 };
+ }
+ };
return \@out;
}
+sub package_not_wholly_new_dummycatapi {
+ my ($proto,$data,$pkg) = @_;
+ dummycatapi_run_in_mirror "
+ find -name ${pkg}_*.dsc
+ ", [], sub {
+ local $/ = undef;
+ !!<FIA>;
+ };
+}
+
#---------- `madison' archive query method ----------
sub archive_query_madison {
@@ -1420,6 +1450,7 @@ sub canonicalise_suite_madison {
}
sub file_in_archive_madison { return undef; }
+sub package_not_wholly_new_madison { return undef; }
#---------- `sshpsql' archive query method ----------
@@ -1497,6 +1528,7 @@ END
}
sub file_in_archive_sshpsql ($$$) { return undef; }
+sub package_not_wholly_new_sshpsql ($$$) { return undef; }
#---------- `dummycat' archive query method ----------
@@ -1541,6 +1573,7 @@ sub archive_query_dummycat ($$) {
}
sub file_in_archive_dummycat () { return undef; }
+sub package_not_wholly_new_dummycat () { return undef; }
#---------- tag format handling ----------
@@ -1975,12 +2008,12 @@ END
if ($found_same) {
# in archive, delete from .changes if it's there
$changed{$file} = "removed" if
- $changes->{$fname} =~ s/^.* \Q$file\E$(?:)\n//m;
- } elsif ($changes->{$fname} =~ m/^.* \Q$file\E$(?:)\n/m) {
+ $changes->{$fname} =~ s/\n.* \Q$file\E$(?:)$//m;
+ } elsif ($changes->{$fname} =~ m/^.* \Q$file\E$(?:)$/m) {
# not in archive, but it's here in the .changes
} else {
my $dsc_data = getfield $dsc, $fname;
- $dsc_data =~ m/^(.* \Q$file\E$)\n/m or die "$dsc_data $file ?";
+ $dsc_data =~ m/^(.* \Q$file\E$)$/m or die "$dsc_data $file ?";
my $extra = $1;
$extra =~ s/ \d+ /$&$placementinfo /
or die "$fname $extra >$dsc_data< ?"
@@ -2851,15 +2884,14 @@ sub mergeinfo_version ($) {
sub fetch_from_archive_record_1 ($) {
my ($hash) = @_;
- runcmd @git, qw(update-ref -m), "dgit fetch $csuite",
- 'DGIT_ARCHIVE', $hash;
+ runcmd git_update_ref_cmd "dgit fetch $csuite", 'DGIT_ARCHIVE', $hash;
cmdoutput @git, qw(log -n2), $hash;
# ... gives git a chance to complain if our commit is malformed
}
sub fetch_from_archive_record_2 ($) {
my ($hash) = @_;
- my @upd_cmd = (@git, qw(update-ref -m), 'dgit fetch', lrref(), $hash);
+ my @upd_cmd = (git_update_ref_cmd 'dgit fetch', lrref(), $hash);
if (act_local()) {
cmdoutput @upd_cmd;
} else {
@@ -3558,7 +3590,7 @@ sub fork_for_multisuite ($) {
my $csubsuite = multisuite_suite_child($tsuite, \@mergeinputs,
sub {
@end = ();
- fetch();
+ fetch_one();
finish 0;
});
# xxx collecte the ref here
@@ -3716,7 +3748,7 @@ sub clone ($) {
clone_finish($dstdir);
}
-sub fetch () {
+sub fetch_one () {
canonicalise_suite();
if (check_for_git()) {
git_fetch_us();
@@ -3739,10 +3771,14 @@ END
printdone "fetched into ".lrref();
}
-sub pull () {
+sub dofetch () {
my $multi_fetched = fork_for_multisuite(sub { });
- fetch() unless $multi_fetched; # parent
- return if $multi_fetched eq '0'; # child
+ fetch_one() unless $multi_fetched; # parent
+ finish 0 if $multi_fetched eq '0'; # child
+}
+
+sub pull () {
+ dofetch();
runcmd_ordryrun_local @git, qw(merge -m),"Merge from $csuite [dgit]",
lrref();
printdone "fetched to ".lrref()." and merged into HEAD";
@@ -3776,11 +3812,11 @@ sub quiltify_nofix_bail ($$) {
}
sub commit_quilty_patch () {
- my $output = cmdoutput @git, qw(status --porcelain);
+ my $output = cmdoutput @git, qw(status --ignored --porcelain);
my %adds;
foreach my $l (split /\n/, $output) {
next unless $l =~ m/\S/;
- if ($l =~ m{^(?:\?\?| [MADRC]) (.pc|debian/patches)}) {
+ if ($l =~ m{^(?:[?!][?!]| [MADRC]) (.pc|debian/patches)}) {
$adds{$1}++;
}
}
@@ -3850,7 +3886,7 @@ sub maybe_split_brain_save ($$$) {
# => message fragment "$saved" describing disposition of $dgitview
return "commit id $dgitview" unless defined $split_brain_save;
my @cmd = (shell_cmd 'cd "$1"; shift', $maindir,
- @git, qw(update-ref -m),
+ git_update_ref_cmd
"dgit --dgit-view-save $msg HEAD=$headref",
$split_brain_save, $dgitview);
runcmd @cmd;
@@ -4014,10 +4050,12 @@ sub splitbrain_pseudomerge ($$$$) {
infopair_cond_ff($i_dep14, [ $maintview, 'HEAD' ]);
1;
}) {
+ $@ =~ s/^\n//; chomp $@;
print STDERR <<END;
-$us: check failed (maybe --overwrite is needed, consult documentation)
+$@
+| Not fast forward; maybe --overwrite is needed, see dgit(1)
END
- die "$@";
+ finish -1;
}
my $r = pseudomerge_make_commit
@@ -4050,7 +4088,7 @@ sub plain_overwrite_pseudomerge ($$$) {
$clogp, $head, $archive_hash, $i_arch_v,
"dgit", $m;
- runcmd @git, qw(update-ref -m), $m, 'HEAD', $r, $head;
+ runcmd git_update_ref_cmd $m, 'HEAD', $r, $head;
progress "Make pseudo-merge of $i_arch_v->[0] into your HEAD.";
return $r;
@@ -4413,6 +4451,29 @@ END
files_compare_inputs($dsc, $changes)
unless forceing [qw(dsc-changes-mismatch)];
+ # Check whether this is a source only upload
+ my $hasdebs = $changes->{Files} =~ m{\.deb$}m;
+ my $sourceonlypolicy = access_cfg 'source-only-uploads';
+ if ($sourceonlypolicy eq 'ok') {
+ } elsif ($sourceonlypolicy eq 'always') {
+ forceable_fail [qw(uploading-binaries)],
+ "uploading binaries, although distroy policy is source only"
+ if $hasdebs;
+ } elsif ($sourceonlypolicy eq 'never') {
+ forceable_fail [qw(uploading-source-only)],
+ "source-only upload, although distroy policy requires .debs"
+ if !$hasdebs;
+ } elsif ($sourceonlypolicy eq 'not-wholly-new') {
+ forceable_fail [qw(uploading-source-only)],
+ "source-only upload, even though package is entirely NEW\n".
+ "(this is contrary to policy in ".(access_nomdistro()).")"
+ if !$hasdebs
+ && $new_package
+ && !(archive_query('package_not_wholly_new', $package) // 1);
+ } else {
+ badcfg "unknown source-only-uploads policy \`$sourceonlypolicy'";
+ }
+
# Perhaps adjust .dsc to contain right set of origs
changes_update_origs_from_dsc($dsc, $changes, $upstreamversion,
$changesfile)
@@ -4496,7 +4557,7 @@ END
runcmd_ordryrun @git,
qw(-c push.followTags=false push), access_giturl(), @pushrefs;
- runcmd_ordryrun @git, qw(update-ref -m), 'dgit push', lrref(), $dgithead;
+ runcmd_ordryrun git_update_ref_cmd 'dgit push', lrref(), $dgithead;
supplementary_message(<<'END');
Push failed, while obtaining signatures on the .changes and .dsc.
@@ -4596,11 +4657,15 @@ sub branchsuite () {
}
}
-sub fetchpullargs () {
+sub package_from_d_control () {
if (!defined $package) {
my $sourcep = parsecontrol('debian/control','debian/control');
$package = getfield $sourcep, 'Source';
}
+}
+
+sub fetchpullargs () {
+ package_from_d_control();
if (@ARGV==0) {
$isuite = branchsuite();
if (!$isuite) {
@@ -4619,9 +4684,7 @@ sub fetchpullargs () {
sub cmd_fetch {
parseopts();
fetchpullargs();
- my $multi_fetched = fork_for_multisuite(sub { });
- finish 0 if $multi_fetched;
- fetch();
+ dofetch();
}
sub cmd_pull {
@@ -4636,6 +4699,40 @@ END
pull();
}
+sub cmd_checkout {
+ parseopts();
+ package_from_d_control();
+ @ARGV==1 or badusage "dgit checkout needs a suite argument";
+ ($isuite) = @ARGV;
+ notpushing();
+
+ foreach my $canon (qw(0 1)) {
+ if (!$canon) {
+ $csuite= $isuite;
+ } else {
+ undef $csuite;
+ canonicalise_suite();
+ }
+ if (length git_get_ref lref()) {
+ # local branch already exists, yay
+ last;
+ }
+ if (!length git_get_ref lrref()) {
+ if (!$canon) {
+ # nope
+ next;
+ }
+ dofetch();
+ }
+ # now lrref exists
+ runcmd (@git, qw(update-ref), lref(), lrref(), '');
+ last;
+ }
+ local $ENV{GIT_REFLOG_ACTION} = git_reflog_action_msg
+ "dgit checkout $isuite";
+ runcmd (@git, qw(checkout), lbranch());
+}
+
sub cmd_update_vcs_git () {
my $specsuite;
if (@ARGV==0 || $ARGV[0] =~ m/^-/) {
@@ -4653,11 +4750,10 @@ sub cmd_update_vcs_git () {
}
}
- my $sourcep = parsecontrol 'debian/control', 'debian/control';
- $package = getfield $sourcep, 'Source';
+ package_from_d_control();
my $ctrl;
if ($specsuite eq '.') {
- $ctrl = $sourcep;
+ $ctrl = parsecontrol 'debian/control', 'debian/control';
} else {
$isuite = $specsuite;
get_archive_dsc();
@@ -5222,7 +5318,7 @@ END
print SERIES "\n" or die $! unless $newline eq "\n";
print SERIES "auto-gitignore\n" or die $!;
close SERIES or die $!;
- runcmd @git, qw(add -- debian/patches/series), $gipatch;
+ runcmd @git, qw(add -f -- debian/patches/series), $gipatch;
commit_admin <<END
Commit patch to update .gitignore
@@ -5399,7 +5495,8 @@ sub quiltify ($$$$) {
print STDERR "$us: ", $reportnot->($notp), "\n";
}
print STDERR "$us: $_\n" foreach @$failsuggestion;
- fail "quilt fixup naive history linearisation failed.\n".
+ fail
+ "quilt history linearisation failed. Search \`quilt fixup' in dgit(7).\n".
"Use dpkg-source --commit by hand; or, --quilt=smash for one ugly patch";
} elsif ($quilt_mode eq 'smash') {
} elsif ($quilt_mode eq 'auto') {
@@ -6437,7 +6534,7 @@ sub cmd_quilt_fixup {
sub import_dsc_result {
my ($dstref, $newhash, $what_log, $what_msg) = @_;
- my @cmd = (@git, qw(update-ref -m), $what_log, $dstref, $newhash);
+ my @cmd = (git_update_ref_cmd $what_log, $dstref, $newhash);
runcmd @cmd;
check_gitattrs($newhash, "source tree");
diff --git a/dgit.1 b/dgit.1
index 8ddcbe3..67aa2fa 100644
--- a/dgit.1
+++ b/dgit.1
@@ -14,7 +14,7 @@ dgit \- git integration with the Debian archive
.br
.B dgit
[\fIdgit\-opts\fP] \fBbuild\fP|\fBsbuild\fP|\fBbuild-source\fP
-[\fIbuild\-opts\fp]
+[\fIbuild\-opts\fP]
.br
.B dgit
[\fIdgit\-opts\fP] \fBpush\fP|\fBpush-source\fP [\fIdgit\-opts\fP]
@@ -109,6 +109,27 @@ branch
.BI remotes/dgit/dgit/ suite
into the current branch.
.TP
+\fBdgit checkout\fR \fIsuite\fR
+Checks out the local branch
+.BR dgit/ \fIsuite\fR.
+
+If the branch does not exist,
+dgit checkout creates it,
+and sets it up the same way as dgit clone would.
+In that case, if
+the archive remote tracking branch does not exist,
+dgit checkout will do a dgit fetch first.
+
+NB: dgit checkout will only do a fetch if it has to.
+If you already have the suite branch,
+and want to merge your branch with updates from the archive,
+use dgit pull.
+
+dgit checkout will normally need to aceess the archive server,
+to canonicalise the provided suite name.
+The exception is if you specify the canonical name,
+and the branch (or tracking branch) already exists.
+.TP
\fBdgit build\fR ...
Runs
.B dpkg-buildpackage
@@ -206,9 +227,6 @@ dgit push always uses the package, suite and version specified in the
debian/changelog and the .dsc, which must agree. If the command line
specifies a suite then that must match too.
-With \fB-C\fR, performs a dgit push, additionally ensuring that no
-binary packages are uploaded.
-
When used on a git-debrebase branch,
dgit calls git-debrebase
to prepare the branch
@@ -218,6 +236,9 @@ for source package upload and push.
Without \fB-C\fR, builds a source package and dgit pushes it. Saying
\fBdgit push-source\fR is like saying "update the source code in the
archive to match my git HEAD, and let the autobuilders do the rest."
+
+With \fB-C\fR, performs a dgit push, additionally ensuring that no
+binary packages are uploaded.
.TP
\fBdgit rpush\fR \fIbuild-host\fR\fB:\fR\fIbuild-dir\fR [\fIpush args...\fR]
Pushes the contents of the specified directory on a remote machine.
@@ -334,6 +355,11 @@ so dgit quilt-fixup can be useful in its own right.
To always use dgit's own patch generator
instead of git-debrebase make-patches,
pass --git-debrebase=true to dgit.
+
+See
+.B FORMAT 3.0 (QUILT)
+in
+.BR dgit(7) .
.TP
\fBdgit import-dsc\fR [\fIsub-options\fR] \fI../path/to/.dsc\fR [\fB+\fR|\fB..\fR]branch
Import a Debian-format source package,
@@ -509,25 +535,39 @@ push will still ensure that the .dsc you upload and the git tree
you push are identical, so this option won't make broken pushes.)
.TP
.BR --overwrite [=\fIprevious-version\fR]
-Declare that even though your git branch may not be a descendant
+Declare that your HEAD really does contain
+all the (wanted) changes
+from all versions listed in its changelog;
+or, all (wanted) changes from
+.IR previous-version .
+This promise is needed when
+your git branch is not a descendant
of the version in the archive
-according to the revision history,
-it really does contain
-all the (wanted) changes from that version.
+according to the git revision history.
This option is useful if you are the maintainer, and you have
incorporated NMU changes into your own git workflow in a way that
doesn't make your branch a fast forward from the NMU.
-.I previous-version
-ought to be the version currently in the archive. If
+This option is also usually necessary
+the first time a package is pushed with dgit push
+to a particular suite.
+See
+.BR dgit-maint- \fI*\fR (7) .
+
+If
.I previous-version
is not
specified, dgit will check that the version in the archive is
mentioned in your debian/changelog.
(This will avoid losing
-changes unless someone committed to git a finalised changelog
+changes, even with
+.BR --overwrite ,
+unless someone committed to git a finalised changelog
entry, and then made later changes to that version.)
+If
+.IR previous-version
+is specified, it ought to be the version currently in the archive.
dgit push --overwrite
will, if necessary, make a
@@ -1010,6 +1050,17 @@ The result is a fresh import,
discarding the git history
that the person who pushed that .dsc was working with.
.TP
+.B --force-uploading-binaries
+Carry on and
+upload binaries
+even though dgit thinks your distro does not permit that.
+.TP
+.B --force-uploading-source-only
+Carry on and do a source-only upload,
+without any binaries,
+even though dgit thinks your distro does not permit that,
+or does not permit that in this situation.
+.TP
.B --force-unrepresentable
Carry on even if
dgit thinks that your git tree contains changes
@@ -1186,6 +1237,8 @@ or when pushing and
.TP
.BI dgit-distro. distro .rewrite-map-enable
.TP
+.BR dgit-distro. \fIdistro\fR .source-only-uploads " " ok | always | never | not-wholly-new
+.TP
.BI dgit.default.old-dsc-distro
.TP
.BI dgit.dsc-url-proto-ok. protocol
diff --git a/dgit.7 b/dgit.7
index 7ad5aba..b623d8c 100644
--- a/dgit.7
+++ b/dgit.7
@@ -284,6 +284,13 @@ pushing. The only thing you need to know is that dgit build, sbuild,
etc., may make new commits on your HEAD. If you're not a quilt user
this commit won't contain any changes to files you care about.
+Simply commiting to source files
+(whether in debian/ or not, but not to patches)
+will result in a branch that dgit quilt-fixup can linearise.
+Other kinds of changes,
+including editing patches or merging,
+cannot be handled this way.
+
You can explicitly request that dgit do just this fixup, by running
dgit quilt-fixup.
@@ -291,7 +298,85 @@ If you are a quilt user you need to know that dgit's git trees are
`patches applied packaging branches' and do not contain the .pc
directory (which is used by quilt to record which patches are
applied). If you want to manipulate the patch stack you probably want
-to be looking at tools like git-dpm.
+to be looking at tools like
+git-debrebase, gbp pq, or git-dpm.
+
+.SS quilt fixup error messages
+When dgit's quilt fixup fails, it prints messages like this:
+
+.EX
+dgit: base trees orig=5531f03d8456b702eab6 o+d/p=135338e9cc253cc85f84
+dgit: quilt differences: src: == orig ## gitignores: == orig ##
+dgit: quilt differences: HEAD ## o+d/p HEAD ## o+d/p
+starting quiltify (multiple patches, linear mode)
+
+dgit: error: quilt fixup cannot be linear. Stopped at:
+dgit: 696c9bd5..84ae8f96: changed debian/patches/test-gitignore
+.EE
+
+.TP
+.B orig
+is an import of the .orig tarballs dgit found,
+with the debian/ directory from your HEAD substituted.
+This is a git tree object, not a commit:
+you can pass its hash to git-diff but not git-log.
+
+.TP
+.B o+d/p
+is another tree object,
+which is the same as orig
+but with the patches from debian/patches applied.
+
+.TP
+.B HEAD
+is of course your own git HEAD.
+
+.TP
+.B quilt differences
+shows whether each of the these trees differs from the others
+(i) in upstream files excluding .gitignore files;
+(ii) in upstream .gitignore files.
+.B ==
+indicates equality;
+.B ##
+indicates inequality.
+.LP
+dgit quilt-fixup --quilt=linear walks commits
+backwards from your HEAD
+trying to construct a linear set of additional patches,
+starting at the end.
+It hopes to eventually find an ancestor
+whose tree is identical to o+d/p in all upstream files.
+
+In the error message,
+696c9bd5..84ae8f96
+is the first commit child-parent edge
+which cannot be sensibly be
+either ignored, or turned into a patch in debian/patches.
+In this example, this is because
+it itself changes files in debian/patches,
+indicating that something unusual is going on
+and that continuing is not safe.
+But you might also see other kinds of troublesome commit or edge.
+
+Your appropriate response depends on the cause and the context.
+If you have been freely merging your git branch
+and do not need need a pretty linear patch queue,
+you can use
+.B --quilt=smash
+(or use the
+.B 1.0
+or
+.B single-debian-patch
+source formats; see
+.BR dpkg-source(1) .)
+If you want a pretty linear series,
+and this message is unexpected,
+it can mean that you have unwittingly committed changes
+that are not representable by dpkg-source (such as some mode changes).
+Or maybe you just forgot a necessary
+.B --quilt=
+option.
.SH SPLIT VIEW QUILT MODE
When working with git branches intended
for use with the `3.0 (quilt)' source format
diff --git a/git-debrebase b/git-debrebase
index fd05c6b..f16a89c 100755
--- a/git-debrebase
+++ b/git-debrebase
@@ -118,7 +118,7 @@ sub run_deferred_updates ($) {
confess 'dangerous internal error' unless all_snags_summarised();
- my @upd_cmd = (@git, qw(update-ref --stdin -m), "debrebase: $mrest");
+ my @upd_cmd = (git_update_ref_cmd "debrebase: $mrest", qw(--stdin));
debugcmd '>|', @upd_cmd;
open U, "|-", @upd_cmd or die $!;
foreach (@deferred_updates) {
@@ -270,7 +270,7 @@ sub snags_maybe_bail () {
$us, $snags_tripped;
} else {
fail sprintf
- "%s: snags: %d blockers (you could -f<tag>, or --force)",
+ "%s: snags: %d blocker(s) (you could -f<tag>, or --force)",
$us, $snags_tripped;
}
}
@@ -568,11 +568,12 @@ sub keycommits ($;$$$$) {
my $cl;
$fatal //= sub { fail $_[2]; };
my $x = sub {
- my ($cb, $tagsfx, $why) = @_;
+ my ($cb, $tagsfx, $mainwhy, $xwhy) = @_;
+ my $why = $mainwhy.$xwhy;
my $m = "branch needs laundering (run git-debrebase): $why";
fail $m unless defined $cb;
return unless $cb;
- $cb->("unclean-$tagsfx", $why, $cl);
+ $cb->("unclean-$tagsfx", $why, $cl, $mainwhy);
};
for (;;) {
$cl = classify $head;
@@ -593,27 +594,27 @@ sub keycommits ($;$$$$) {
last;
} elsif ($ty eq 'Upstream') {
$x->($unclean, 'ordering',
- "packaging change ($breakwater) follows upstream change (eg $head)")
+ "packaging change ($breakwater) follows upstream change"," (eg $head)")
if defined $breakwater;
$clogonly = undef;
$breakwater = undef;
} elsif ($ty eq 'Mixed') {
$x->($unclean, 'mixed',
- "found mixed upstream/packaging commit ($head)");
+ "found mixed upstream/packaging commit"," ($head)");
$clogonly = undef;
$breakwater = undef;
} elsif ($ty eq 'Pseudomerge' or
$ty eq 'AddPatches') {
$x->($furniture, (lc $ty),
- "found interchange bureaucracy commit ($ty, $head)");
+ "found interchange bureaucracy commit ($ty)"," ($head)");
} elsif ($ty eq 'DgitImportUnpatched') {
$x->($trouble, 'dgitimport',
"found dgit dsc import ($head)");
return (undef,undef);
} else {
$x->($fatal, 'unprocessable',
- "found unprocessable commit, cannot cope: $head; $cl->{Why}"
- );
+ "found unprocessable commit, cannot cope: $cl->{Why}",
+ " ($head)");
return (undef,undef);
}
$head = $cl->{Parents}[0]{CommitId};
@@ -1139,7 +1140,11 @@ sub cmd_new_upstream () {
badusage "need NEW-VERSION [UPS-COMMITTISH]" unless @ARGV >= 1;
# parse args - low commitment
- my $new_version = (new Dpkg::Version scalar(shift @ARGV), check => 1);
+ my $spec_version = shift @ARGV;
+ my $new_version = (new Dpkg::Version $spec_version, check => 1);
+ if ($new_version->is_native()) {
+ $new_version = (new Dpkg::Version "$spec_version-1", check => 1);
+ }
my $new_upstream_version = $new_version->version();
my $new_upstream = shift @ARGV;
@@ -1351,6 +1356,8 @@ END
'launder for new upstream';
my @cmd = (@git, qw(rebase --onto), $new_bw, $old_bw, @ARGV);
+ local $ENV{GIT_REFLOG_ACTION} = git_reflog_action_msg
+ "debrebase new-upstream $new_version: rebase";
runcmd @cmd;
# now it's for the user to sort out
}
@@ -1386,15 +1393,20 @@ sub cmd_status () {
# todo: gdr status should print upstream component(s) info
# todo: gdr should leave/maintain some refs with this kind of info ?
- my $oldest = [ 0 ];
+ my $oldest = { Badness => 0 };
my $newest;
my $note = sub {
- my ($badness, $ourmsg, $snagname, $kcmsg, $cl) = @_;
- if ($oldest->[0] < $badness) {
+ my ($badness, $ourmsg, $snagname, $dummy, $cl, $kcmsg) = @_;
+ if ($oldest->{Badness} < $badness) {
$oldest = $newest = undef;
}
- $oldest = \@_; # we're walking backwards
- $newest //= \@_;
+ $oldest = {
+ Badness => $badness,
+ CommitId => $cl->{CommitId},
+ OurMsg => $ourmsg,
+ KcMsg => $kcmsg,
+ };
+ $newest //= $oldest;
};
my ($anchor, $bw) = keycommits +(git_rev_parse 'HEAD'),
sub { $note->(1, 'branch contains furniture (not laundered)', @_); },
@@ -1411,16 +1423,16 @@ sub cmd_status () {
};
print "current branch contents, in git-debrebase terms:\n";
- if (!$oldest->[0]) {
+ if (!$oldest->{Badness}) {
print " branch is laundered\n";
} else {
- print " $oldest->[1]\n";
+ print " $oldest->{OurMsg}\n";
my $printed = '';
foreach my $info ($oldest, $newest) {
- my $cid = $info->[4]{CommitId};
+ my $cid = $info->{CommitId};
next if $cid eq $printed;
$printed = $cid;
- print " $info->[3]\n";
+ print " $info->{KcMsg}\n";
$prcommitinfo->($cid);
}
}
@@ -1502,7 +1514,7 @@ sub make_patches_staged ($) {
{ local ($!,$?); copy('../gbp-pq-err', \*STDERR); }
failedcmd @gbp_cmd;
}
- runcmd @git, qw(add debian/patches);
+ runcmd @git, qw(add -f debian/patches);
};
}
diff --git a/git-debrebase.1.pod b/git-debrebase.1.pod
index 1c3e681..4d1a673 100644
--- a/git-debrebase.1.pod
+++ b/git-debrebase.1.pod
@@ -135,6 +135,12 @@ If you git-rebase --abort,
the whole new upstream operation is aborted,
except for the laundering.
+<new-version>
+may be whole new Debian version, including revision,
+or just the upstream part,
+in which case -1 will be appended
+to make the new Debian version.
+
The <upstream-details> are, optionally, in order:
=over
diff --git a/tests/enumerate-tests b/tests/enumerate-tests
index 0599b69..0f37c96 100755
--- a/tests/enumerate-tests
+++ b/tests/enumerate-tests
@@ -42,7 +42,7 @@ finish- () {
test-begin-gencontrol () {
restrictions=''
- dependencies='dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin'
+ dependencies='dgit, dgit-infrastructure, devscripts, debhelper (>=8), fakeroot, build-essential, chiark-utils-bin, bc'
}
restriction-gencontrol () {
diff --git a/tests/lib b/tests/lib
index bd06d20..4ef275c 100644
--- a/tests/lib
+++ b/tests/lib
@@ -41,6 +41,7 @@ export DGIT_TEST_TROOT=$troot
tmp=$ADTTMP
if [ x"$tmp" = x ]; then
+ export DGIT_TEST_BYHAND=1
mkdir -p tests/tmp
tmpbase=$troot/tmp
tmp=tests/tmp/$testname
@@ -152,7 +153,7 @@ t-reporefs () {
exec >"$outputfile"
if test -d $whichrepo; then
cd $whichrepo
- git show-ref |sort
+ git show-ref |t-sort
fi)
}
@@ -1134,7 +1135,11 @@ t-alt-test () {
t-git-config dgit.default.old-dsc-distro test-dummy
-case "$0" in
-*/gnupg) ;;
-*) t-setup-import gnupg ;;
-esac
+for import in ${autoimport-gnupg}; do
+ case "$0" in
+ */$import) ;;
+ *)
+ t-setup-import $import
+ ;;
+ esac
+done
diff --git a/tests/lib-core b/tests/lib-core
index c3a04cb..724c8ac 100644
--- a/tests/lib-core
+++ b/tests/lib-core
@@ -13,8 +13,10 @@ t-set-intree () {
: ${DGIT_SSH_DISPATCH_TEST:=$DGIT_TEST_INTREE/infra/dgit-ssh-dispatch}
: ${DGIT_INFRA_PFX:=$DGIT_TEST_INTREE${DGIT_TEST_INTREE:+/infra/}}
: ${DGIT_GITDEBREBASE_TEST:=$DGIT_TEST_INTREE/git-debrebase}
+ : ${DGIT_MANPAGES_SOURCE_DIR:=$DGIT_TEST_INTREE}
export DGIT_TEST DGIT_BADCOMMIT_FIXUP
export DGIT_REPOS_SERVER_TEST DGIT_SSH_DISPATCH_TEST
+ export DGIT_MANPAGES_SOURCE_DIR
export PERLLIB="$DGIT_TEST_INTREE${PERLLIB:+:}${PERLLIB}"
}
@@ -38,3 +40,7 @@ t-filter-out-git-hyphen-dir () {
path="${path%:}"
PATH="$path"
}
+
+t-sort () {
+ LC_COLLATE=C sort "$@"
+}
diff --git a/tests/lib-gdr b/tests/lib-gdr
index 7b4f085..22ea6d1 100644
--- a/tests/lib-gdr
+++ b/tests/lib-gdr
@@ -141,7 +141,7 @@ t-gdr-good () {
test $cnparents = $enparents
local cndparents=`
- for f in $parents; do echo $f; done | sort -u | wc -w
+ for f in $parents; do echo $f; done | t-sort -u | wc -w
`
test $cndparents = $cnparents
diff --git a/tests/lib-import-chk b/tests/lib-import-chk
index 88984c1..d6633f9 100644
--- a/tests/lib-import-chk
+++ b/tests/lib-import-chk
@@ -1,11 +1,11 @@
t-import-chk-authorship () {
perl -ne 'print $1,"\n" if m/^ -- (\S.*\>) /' debian/changelog \
- | sort -u \
+ | t-sort -u \
> $tmp/authorship.changelog
${import_chk_changelog_massage:-:} $tmp/authorship.changelog
git log --pretty=format:'%an <%ae>%n%cn <%ce>' \
- | sort -u \
+ | t-sort -u \
> $tmp/authorship.commits
diff $tmp/authorship.{changelog,commits}
}
@@ -63,7 +63,7 @@ t-import-chk2() {
t-ref-same refs/heads/first-2nd-import
for orig in ../${p}_${v%-*}.orig*.tar.*; do
- tar -atf $orig | LC_ALL=C sort >../files.o
+ tar -atf $orig | t-sort >../files.o
pfx=$(perl <../files.o -ne '
while (<>) {
m#^([^/]+/)# or exit 0;
@@ -87,7 +87,7 @@ t-import-chk2() {
t-ref-same-val "$orig $start" "$imp"
done
git ls-tree -r --name-only "$t_ref_val:" \
- | sort >../files.g
+ | t-sort >../files.g
diff ../files.{o,g}
done
cd ..
diff --git a/tests/setup/gdr-convert-gbp b/tests/setup/gdr-convert-gbp
index 0b525c8..e523fd3 100755
--- a/tests/setup/gdr-convert-gbp
+++ b/tests/setup/gdr-convert-gbp
@@ -1,8 +1,11 @@
#!/bin/bash
set -e
+autoimport=
. tests/lib
. $troot/lib-gdr
+$ifarchive t-setup-import gnupg
+
t-dependencies GDR
t-tstunt-parsechangelog
diff --git a/tests/setup/gdr-convert-gbp-noarchive b/tests/setup/gdr-convert-gbp-noarchive
index dfeea3b..1d6758b 100755
--- a/tests/setup/gdr-convert-gbp-noarchive
+++ b/tests/setup/gdr-convert-gbp-noarchive
@@ -1,4 +1,5 @@
#!/bin/bash
+autoimport=
set -e
. tests/lib
. $troot/lib-gdr
diff --git a/tests/setup/gnupg b/tests/setup/gnupg
index c88d40b..7a164ef 100755
--- a/tests/setup/gnupg
+++ b/tests/setup/gnupg
@@ -7,10 +7,11 @@ cp $troot/gnupg/* $tmp/gnupg
chmod go-rw $tmp/gnupg/*
export DGIT_TEST_GNUPG_GLOBAL_LOCK=$tmp/gnupg/dgit-test-global-lock
+export DGIT_TEST_GNUPG_LOG=$tmp/gnupg-workarounds.log
setup='
export GNUPGHOME=$tmp/gnupg
- export DGIT_TEST_GNUPG_GLOBAL_LOCK
+ export DGIT_TEST_GNUPG_GLOBAL_LOCK DGIT_TEST_GNUPG_LOG
cat >$tmp/gnupg/gpg-agent.conf <<END
log-file $tmp/gnupg/AGENT.log
@@ -27,6 +28,7 @@ eval "$setup"
gpg --list-secret
-t-setup-done 'DGIT_TEST_GNUPG_GLOBAL_LOCK' 'gnupg' "$setup"
+t-setup-done 'DGIT_TEST_GNUPG_GLOBAL_LOCK DGIT_TEST_GNUPG_LOG' \
+ 'gnupg' "$setup"
t-ok
diff --git a/tests/tartree-edit b/tests/tartree-edit
index 40bd6e9..78f0e4f 100755
--- a/tests/tartree-edit
+++ b/tests/tartree-edit
@@ -17,7 +17,7 @@ gitfetchdiff_list () {
git for-each-ref --format '%(refname) %(objectname)' \
refs/remotes/"$1" \
| sed 's/^refs\/remotes\/[^\/]*\///' \
- | sort >"$play/$2"
+ | t-sort >"$play/$2"
}
gitfetchdiff () {
diff --git a/tests/tests/checkout b/tests/tests/checkout
new file mode 100755
index 0000000..756c49b
--- /dev/null
+++ b/tests/tests/checkout
@@ -0,0 +1,59 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-tstunt-parsechangelog
+
+t-setup-import examplegit
+
+now-on () {
+ local branch=$(git symbolic-ref HEAD)
+ test "$branch" = "refs/heads/$1"
+}
+
+p=example
+
+mkdir $p.2
+cd $p.2
+
+git init
+t-dgit setup-new-tree
+t-dgit checkout -p $p unstable
+
+now-on dgit/sid
+t-refs-same-start
+t-ref-head
+t-ref-same refs/tags/test-dummy/$v
+
+t-dgit checkout -p $p stable
+now-on dgit/stable
+
+t-dgit checkout -d no-such-distro sid
+t-ref-head
+now-on dgit/sid
+
+t-dgit checkout stable
+now-on dgit/stable
+
+git branch -D dgit/sid
+t-dgit checkout -d no-such-distro sid
+t-ref-head
+now-on dgit/sid
+
+git reflog --pretty=tformat:%gs >../reflog.got
+cat >../reflog.expect <<END
+dgit checkout sid
+dgit checkout stable
+dgit checkout sid
+dgit checkout stable
+dgit checkout unstable
+END
+diff -u ../reflog.{expect,got}
+
+git for-each-ref --format='%(refname)' refs/heads | t-sort >../refs.got
+cat >../refs.expect <<END
+refs/heads/dgit/sid
+refs/heads/dgit/stable
+END
+diff -u ../refs.{expect,got}
+
+t-ok
diff --git a/tests/tests/gdr-makepatches7 b/tests/tests/gdr-makepatches7
index 9c39710..02ea7ab 100755
--- a/tests/tests/gdr-makepatches7
+++ b/tests/tests/gdr-makepatches7
@@ -8,6 +8,15 @@ t-setup-import gdr-convert-gbp
cd $p
+git checkout upstream/2.0
+echo '*patch*' >>.gitignore
+git commit -m nasty .gitignore
+git tag v2.1
+GZIP=-1 git archive -o ../${p}_2.1.orig.tar.gz --prefix ${p}/ v2.1
+
+git checkout master
+t-git-debrebase new-upstream 2.1-1
+
t-some-changes for-rebase-fixup m
t-git-debrebase
diff --git a/tests/tests/gdr-newupstream b/tests/tests/gdr-newupstream
index 536f49c..39ed24b 100755
--- a/tests/tests/gdr-newupstream
+++ b/tests/tests/gdr-newupstream
@@ -1,5 +1,6 @@
#!/bin/bash
set -e
+autoimport=
. tests/lib
t-dependencies NO-DGIT GDR
@@ -35,8 +36,10 @@ t-git-debrebase new-upstream $v
git tag v2.1 upstream
-t-git-debrebase new-upstream $v
+t-git-debrebase new-upstream ${v%-*}
+
t-gdr-good laundered
+git reflog | egrep 'debrebase new-upstream.*checkout'
t-git-debrebase stitch
t-gdr-good stitched
@@ -54,8 +57,11 @@ anchor=$(perl <../anal.anch -ne '
exit;
')
+GIT_REFLOG_ACTION='STUNT-RLA' \
t-git-debrebase --anchor=$anchor -fanchor-treated new-upstream $v upstream
t-gdr-good laundered
+git reflog | egrep 'STUNT-RLA: debrebase new-upstream'
+git reflog | egrep 'STUNT-RLA: debrebase: launder for new upstream'
t-git-debrebase stitch
t-gdr-good stitched
diff --git a/tests/tests/gdr-viagit b/tests/tests/gdr-viagit
index 644d2d4..a83e622 100755
--- a/tests/tests/gdr-viagit
+++ b/tests/tests/gdr-viagit
@@ -1,5 +1,6 @@
#!/bin/bash
set -e
+autoimport=
. tests/lib
t-dependencies NO-DGIT GDR
diff --git a/tests/tests/import-native b/tests/tests/import-native
index 1e09343..0766841 100755
--- a/tests/tests/import-native
+++ b/tests/tests/import-native
@@ -8,7 +8,7 @@ t-tstunt-parsechangelog
mkdir $tmp/aside
versions=""
-for f in $(find $tmp/mirror -name \*.dsc | sort); do
+for f in $(find $tmp/mirror -name \*.dsc | t-sort); do
perl -i -pe '
$_="" if m/^-----BEGIN PGP SIGNED/..!m/\S/;
$_="" if m/^-----BEGIN PGP SIGNATURE/..0;
diff --git a/tests/tests/manpages-format b/tests/tests/manpages-format
new file mode 100755
index 0000000..7ba2f9d
--- /dev/null
+++ b/tests/tests/manpages-format
@@ -0,0 +1,78 @@
+#!/bin/bash
+set -e
+autoimport=
+. tests/lib
+
+t-dependencies man-db make groff git-debrebase
+
+cd $root
+
+printenv |grep MAKE ||: |t-sort
+manpages=$(MAKEFLAGS= MAKELEVEL= make list-manpages)
+
+export MANWIDTH=80
+
+run_man () {
+ if [ "x${DGIT_MANPAGES_SOURCE_DIR}" = x ]; then
+ cmd='man "$@" $section $page'
+ else
+ make $roff >&2
+ cmd='man "$@" -l $roff'
+ fi
+ eval "$cmd 2>&1 >/dev/null |tee $errs"
+}
+
+for roff in $manpages; do
+ for fmt in txt ps; do
+ >$tmp/$roff.$fmt-expected
+ done
+done
+
+expected () {
+ cat >$tmp/$2.$1-expected
+}
+
+not_egrep_vxPf () {
+ # egrep -vxPf does not work, so we reimplement it
+ perl -ne '
+ BEGIN () {
+ open PATS, shift @ARGV or die $!;
+ $re = join "|", map { chomp; qr{^(?:$_)$} }
+ qr{^(?=a)b}, <PATS>;
+ print STDERR "RE $re\n";
+ }
+ next if m{$re};
+ print STDERR "unexpected: $_";
+ $bad = 1;
+ END { die "unexpected errors\n" if $bad; }
+ ' "$@"
+}
+
+expected txt dgit.1 <<'END'
+.* # table wider than line width
+END
+
+prep () {
+ fmt=$1
+ errs=$tmp/$roff.$fmt-errs
+}
+
+check () {
+ perl -0777 -i~ -pe 's/\n[ \t]+/ # /' $errs
+ not_egrep_vxPf $tmp/$roff.$fmt-expected $errs
+}
+
+for roff in $manpages; do
+ section=${roff##*.}
+ page=${roff%.*}
+
+ prep txt
+ run_man
+ check
+
+ prep ps
+ run_man -Tps
+ check
+done
+
+t-ok
diff --git a/tests/tests/overwrite-splitbrains b/tests/tests/overwrite-splitbrains
index 0ef03f6..06d1a98 100755
--- a/tests/tests/overwrite-splitbrains
+++ b/tests/tests/overwrite-splitbrains
@@ -14,7 +14,7 @@ t-dgit fetch
t-refs-same-start
t-ref-head
-t-expect-fail 'check failed (maybe --overwrite is needed' \
+t-expect-fail 'maybe --overwrite is needed' \
t-dgit --quilt=gbp --dgit-view-save=split.p push
t-refs-same-start
diff --git a/tests/tests/push-newrepeat b/tests/tests/push-newrepeat
new file mode 100755
index 0000000..87fcb35
--- /dev/null
+++ b/tests/tests/push-newrepeat
@@ -0,0 +1,21 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+cd $p
+git checkout quilt-tip
+cp $troot/pkg-srcs/${p}_1.0.orig.tar.gz ..
+
+t-dgit --quilt=smash build-source
+
+t-expect-fail E:'Push failed, while updating the remote git repository' \
+t-dgit -cdgit-distro.test-dummy.git-url=file:///dev/enoent/fail \
+ push --new
+
+t-dgit push --new
+
+t-ok
diff --git a/tests/tests/sourceonlypolicy b/tests/tests/sourceonlypolicy
new file mode 100755
index 0000000..b0569c3
--- /dev/null
+++ b/tests/tests/sourceonlypolicy
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+
+dgit-with-policy () {
+ local policy=$1; shift
+ t-dgit -cdgit-distro.test-dummy.source-only-uploads=$policy "$@"
+}
+
+t-expect-fail E:'source-only.*entirely NEW' \
+dgit-with-policy not-wholly-new push-source --new
+
+t-expect-fail E:'source-only.*requires \.debs' \
+dgit-with-policy never push-source --new
+
+dgit-with-policy always push-source --new
+
+t-archive-process-incoming sid
+
+t-commit 'Now with binaries'
+
+t-dgit -wgf build
+
+t-expect-fail E:'uploading binaries.*source only' \
+dgit-with-policy always push --new
+
+t-commit 'Source-only not NEW'
+
+dgit-with-policy not-wholly-new push-source --new
+
+t-ok
diff --git a/tests/tests/trustingpolicy-replay b/tests/tests/trustingpolicy-replay
index ad731f5..2a1012b 100755
--- a/tests/tests/trustingpolicy-replay
+++ b/tests/tests/trustingpolicy-replay
@@ -4,6 +4,8 @@ set -e
t-tstunt-parsechangelog
+t-dependencies dput-ng
+
t-git-config dgit.default.dep14tag no
t-dsd
@@ -17,11 +19,12 @@ git tag start
t-dgit build
t-dgit push --new
+t-rm-dput-dropping
+
t-commit 'Prep v1.1 which will be rewound'
t-dgit build
t-dgit push
-t-rm-dput-dropping
git checkout $tagpfx/1.0
t-dgit build
t-dgit push --deliberately-fresh-repo
diff --git a/tests/tstunt/gpg b/tests/tstunt/gpg
index 679a6b8..4214b4a 100755
--- a/tests/tstunt/gpg
+++ b/tests/tstunt/gpg
@@ -3,4 +3,20 @@ set -e
exec \
with-lock-ex -w "$DGIT_TEST_GNUPG_GLOBAL_LOCK" \
- $tmp "$DGIT_TEST_TROOT"/tstunt/gpg-locked "$@"
+ sh -c '
+ "$@" 9>&2 2>>"$DGIT_TEST_GNUPG_LOG"
+ rc=$?
+ if [ $rc = 0 ]; then exit 0; fi
+ if [ "x$DGIT_TEST_BYHAND" != x ]; then
+ echo >&2 "BYHAND, not dumping $DGIT_TEST_GNUPG_LOG"
+ else
+ echo >&2 "########################################"
+ echo >&2 "$DGIT_TEST_GNUPG_LOG"
+ sed '\''s/^/\[gnupg-workarounds] /'\'' >&2 \
+ "$DGIT_TEST_GNUPG_LOG"
+ echo >&2 "end of $DGIT_TEST_GNUPG_LOG"
+ echo >&2 "########################################"
+ fi
+ exit $rc
+ ' x \
+ "$DGIT_TEST_TROOT"/tstunt/gpg-withagent "$@"
diff --git a/tests/tstunt/gpg-withagent b/tests/tstunt/gpg-withagent
new file mode 100755
index 0000000..b7b8bfd
--- /dev/null
+++ b/tests/tstunt/gpg-withagent
@@ -0,0 +1,68 @@
+#!/bin/sh
+set -ex
+
+d () {
+ date --iso-8601=ns >&2
+ ps -ef | grep gpg-agent >&2 ||:
+}
+
+d
+
+retry_until_ok () {
+ sleeptime=0
+ d
+ while ! "$@"; do
+ d
+ case $sleeptime in
+ ??.*)
+ echo >&2 "$0: GPG AGENT STARTP $@ TIMED OUT"
+ exit 127
+ ;;
+ esac
+ sleep $sleeptime
+ sleeptime=$(echo "($sleeptime + 0.001) * 2" | bc -l)
+ done
+}
+
+kill_agent_not_running () {
+ LC_MESSAGES=C gpg-connect-agent --no-autostart </dev/null \
+ KILLAGENT /bye 2>&1 \
+ | tee -a /dev/stderr \
+ | grep 'no gpg-agent running' >&2
+}
+
+echo >&2 'GPG-WITHAGENT... PRE-STOPPING'
+
+retry_until_ok kill_agent_not_running
+
+agent_is_running () {
+ gpg-connect-agent --no-autostart </dev/null \
+ '/echo dgit-gpg-agent-ok' /bye 2>&1 \
+ | grep dgit-gpg-agent-ok >&2
+}
+
+
+$DGIT_STUNT_AGENT --daemon </dev/null >&2
+retry_until_ok agent_is_running
+
+echo >&2 'GPG-WITHAGENT... RUNNING'
+
+d
+
+set +e
+$DGIT_TEST_REAL_GPG \
+ --agent-program=$DGIT_STUNT_AGENT "$@" 2>&9
+rc=$?
+set -e
+
+d
+
+echo >&2 'GPG-WITHAGENT... STOPPING'
+
+retry_until_ok kill_agent_not_running
+
+echo >&2 'GPG-WITHAGENT... DONE'
+
+d
+
+exit $rc