I've rebased this patch against current Git. To recap, this option enables (re)building a source package without cross- checking against the orig tarball, in scenarios where the latter is superfluous and expensive. Some benchmarks from a package I work with basically tell the story. This is with my patch applied:
$ ls -l *.orig.tar.xz -rw-r--r-- 1 skunk users 843547668 May 16 19:08 ungoogled-chromium_125.0.6422.60.orig.tar.xz $ time -p dpkg-source --no-preparation --abort-on-upstream-changes --build ungoogled-chromium-src dpkg-source.pl: info: using source format '3.0 (quilt)' dpkg-source.pl: info: building ungoogled-chromium using existing ./ungoogled-chromium_125.0.6422.60.orig.tar.xz dpkg-source.pl: info: using patch list from debian/patches/series dpkg-source.pl: info: building ungoogled-chromium in ungoogled-chromium_125.0.6422.60-1xtradeb1.2204.1.debian.tar.xz dpkg-source.pl: info: building ungoogled-chromium in ungoogled-chromium_125.0.6422.60-1xtradeb1.2204.1.dsc real 628.93 user 198.92 sys 88.00 $ time -p dpkg-source --no-generate-diff --no-preparation --abort-on-upstream-changes --build ungoogled-chromium-src dpkg-source.pl: info: using source format '3.0 (quilt)' dpkg-source.pl: info: building ungoogled-chromium using existing ./ungoogled-chromium_125.0.6422.60.orig.tar.xz dpkg-source.pl: info: building ungoogled-chromium in ungoogled-chromium_125.0.6422.60-1xtradeb1.2204.1.debian.tar.xz dpkg-source.pl: info: building ungoogled-chromium in ungoogled-chromium_125.0.6422.60-1xtradeb1.2204.1.dsc real 11.62 user 10.86 sys 0.74 --Daniel --- man/dpkg-source.pod | 11 ++++++++++- scripts/Dpkg/Source/Package/V2.pm | 32 +++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/man/dpkg-source.pod b/man/dpkg-source.pod index 736f42fd2..4102fd986 100644 --- a/man/dpkg-source.pod +++ b/man/dpkg-source.pod @@ -647,7 +647,8 @@ patches have been applied during the extraction. B<Building> -All original tarballs found in the current directory are extracted in a +If B<--no-generate-diff> is not given, then +all original tarballs found in the current directory are extracted in a temporary directory by following the same logic as for the unpack, the debian directory is copied over in the temporary directory, and all patches except the automatic patch (B<debian-changes->I<version> @@ -791,6 +792,14 @@ Those options are only allowed in B<debian/source/local-options> so that all generated source packages have the same behavior by default. +=item B<--no-generate-diff> + +Do not generate a diff against the upstream sources. This skips the process +of extracting the original tarballs, and thus allows for a faster build. +Not only is the source package directory not checked for any extraneous +modifications, anything outside the debian subdirectory is ignored +altogether. Use with caution. + =item B<--abort-on-upstream-changes> The process fails if an automatic patch has been generated diff --git a/scripts/Dpkg/Source/Package/V2.pm b/scripts/Dpkg/Source/Package/V2.pm index 1f0946128..0eb9ba529 100644 --- a/scripts/Dpkg/Source/Package/V2.pm +++ b/scripts/Dpkg/Source/Package/V2.pm @@ -71,6 +71,7 @@ sub init_options { $self->{options}{unapply_patches} //= 'auto'; $self->{options}{skip_debianization} //= 0; $self->{options}{create_empty_orig} //= 0; + $self->{options}{generate_diff} //= 1; $self->{options}{auto_commit} //= 0; $self->{options}{ignore_bad_version} //= 0; } @@ -104,6 +105,10 @@ my @module_cmdline = ( name => '--create-empty-orig', help => N_('create an empty original tarball if missing'), when => 'build', + }, { + name => '--no-generate-diff', + help => N_('do not generate diff against upstream sources'), + when => 'build', }, { name => '--abort-on-upstream-changes', help => N_('abort if generated diff has upstream files changes'), @@ -156,6 +161,9 @@ sub parse_cmdline_option { } elsif ($opt eq '--create-empty-orig') { $self->{options}{create_empty_orig} = 1; return 1; + } elsif ($opt eq '--no-generate-diff') { + $self->{options}{generate_diff} = 0; + return 1; } elsif ($opt eq '--abort-on-upstream-changes') { $self->{options}{auto_commit} = 0; return 1; @@ -460,6 +468,8 @@ sub _generate_patch { } } + return if !$opts{do_diff}; + # Unpack a second copy for comparison my $tmp = tempdir("$dirname.orig.XXXXXX", DIR => $updir); push_exit_handler(sub { erasedir($tmp) }); @@ -530,6 +540,21 @@ sub do_build { usageerr(g_("-b takes only one parameter with format '%s'"), $self->{fields}{'Format'}); } + if (!$self->{options}{generate_diff} && + ($self->{options}{include_removal} || + $self->{options}{include_timestamp} || + $self->{options}{include_binaries} || + $self->{options}{create_empty_orig} || + $self->{options}{auto_commit})) { + my @incompat = ( + "--include-removal", + "--include-timestamp", + "--include-binaries", + "--create-empty-orig", + "--auto-commit" + ); + usageerr(g_("--no-generate-diff is incompatible with the following options: %s"), join(", ", @incompat)); + } $self->prepare_build($dir); my $include_binaries = $self->{options}{include_binaries}; @@ -569,8 +594,9 @@ sub do_build { header_from => $autopatch, handle_binary => $handle_binary, skip_auto => $self->{options}{auto_commit}, + do_diff => $self->{options}{generate_diff}, usage => 'build'); - unless (-z $tmpdiff or $self->{options}{auto_commit}) { + unless (!$tmpdiff or -z $tmpdiff or $self->{options}{auto_commit}) { info(g_('Hint: make sure the version in debian/changelog matches ' . 'the unpacked source tree')); info(g_('you can integrate the local changes with %s'), @@ -578,7 +604,7 @@ sub do_build { error(g_('aborting due to unexpected upstream changes, see %s'), $tmpdiff); } - push_exit_handler(sub { unlink($tmpdiff) }); + push_exit_handler(sub { !$tmpdiff or unlink($tmpdiff) }); $binaryfiles->update_debian_source_include_binaries() if $include_binaries; # Install the diff as the new autopatch @@ -590,7 +616,7 @@ sub do_build { $autopatch) if -e $autopatch; rmdir(File::Spec->catdir($dir, 'debian', 'patches')); # No check on purpose } - unlink($tmpdiff) or syserr(g_('cannot remove %s'), $tmpdiff); + !$tmpdiff or unlink($tmpdiff) or syserr(g_('cannot remove %s'), $tmpdiff); pop_exit_handler(); # Create the debian.tar