Package: libdpkg-perl
Version: 1.19.7
Severity: normal
Tags: patch

Dear Maintainer,

the following problematic behaviour can be observed with 3.0 Quilt
packages:

   * What led up to the situation?

A package updated was not done correctly, and the contents of
debian/patches and the original upstream sources got out of sync such
that (at least) the first patch in d/patches/series no longer applies.

   * What exactly did you do (or not do) that was effective (or
     ineffective)?

Tried to build such a package.

   * What was the outcome of this action?

The unpatched upstream sources got built and packaged, silently skipping
any and all patch application.

   * What outcome did you expect instead?

dpkg-buildpackage/dpkg-source should have errored out, stating that the
patches in debian/patches are not appliable.


Attached patch improves the heuristic by attempting to forward and
reverse apply the first patch. The whole thing is still broken if just
the first patch was already applied, since all the rest will still be
silently skipped.

Dropping the heuristic and unconditionally attempting to apply all
patches (via quilt, which would skip patches already applied with quilt)
would also solve this issue, but might cause breakage for some arcane
workflows.

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=848611
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680155

are semi-related bug reports.


-- Package-specific info:

-- System Information:
Debian Release: bullseye/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages libdpkg-perl depends on:
ii  dpkg  1.19.7
ii  perl  5.30.0-9

Versions of packages libdpkg-perl recommends:
ii  bzip2                   1.0.8-2
ii  libfile-fcntllock-perl  0.22-3+b6
ii  liblocale-gettext-perl  1.07-4
ii  xz-utils                5.2.4-1+b1

Versions of packages libdpkg-perl suggests:
ii  binutils              2.33.50.20200115-2
pn  bzr                   <none>
ii  clang-8 [c-compiler]  1:8.0.1-5+b1
ii  debian-keyring        2019.12.23
ii  gcc [c-compiler]      4:9.2.1-3.1
ii  gcc-9 [c-compiler]    9.2.1-24
ii  git                   1:2.25.0-1
ii  gnupg                 2.2.19-1
ii  gpgv                  2.2.19-1
ii  patch                 2.7.6-6
ii  sensible-utils        0.0.12+nmu1

-- no debconf information
diff --git a/scripts/Dpkg/Source/Package/V3/Quilt.pm 
b/scripts/Dpkg/Source/Package/V3/Quilt.pm
index 45237d26a..1ebc97822 100644
--- a/scripts/Dpkg/Source/Package/V3/Quilt.pm
+++ b/scripts/Dpkg/Source/Package/V3/Quilt.pm
@@ -237,7 +237,13 @@ sub check_patches_applied {
 
     my $first_patch = File::Spec->catfile($dir, 'debian', 'patches', $next);
     my $patch_obj = Dpkg::Source::Patch->new(filename => $first_patch);
-    return unless $patch_obj->check_apply($dir, fatal_dupes => 1);
+    my $forward = $patch_obj->check_apply($dir, fatal_dupes => 1);
+    my $reverse = $patch_obj->check_apply($dir, fatal_dupes => 1, reverse => 
1);
+
+    # patch already applied: $reverse == 1, $forward == 0
+    # patch does apply, and is not yet applied: $reverse == 1, $forward == 1
+    # patch does not apply, and is not yet applied: $reverse = 0, $forward = 0
+    return if $reverse && !$forward;
 
     $self->apply_patches($dir, usage => 'preparation', verbose => 1);
 }
diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm
index 25d56335d..17ad29d00 100644
--- a/scripts/Dpkg/Source/Patch.pm
+++ b/scripts/Dpkg/Source/Patch.pm
@@ -624,8 +624,10 @@ sub check_apply {
     my ($self, $destdir, %opts) = @_;
     # Set default values to options
     $opts{create_dirs} //= 1;
-    $opts{options} ||= [ '--dry-run', '-s', '-t', '-F', '0', '-N', '-p1', '-u',
+    $opts{options} ||= [ '--dry-run', '-s', '-t', '-F', '0', '-p1', '-u',
             '-V', 'never', '-b', '-z', '.dpkg-orig'];
+    my $direction = $opts{reverse} ? '-R' : '-N';
+    push @{$opts{options}}, $direction;
     $opts{add_options} //= [];
     push @{$opts{options}}, @{$opts{add_options}};
     # Check the diff and create missing directories

Reply via email to