On Wed, Aug 26, 2026 at 01:03:34AM +0900, Simon Richter wrote:
> Package: devscripts
> Version: 2.26.11~bpo13+1
> X-Debbugs-Cc: [email protected]
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA512
> 
> Hi,
> 
> this looks somewhat similar to #1145549, but no uscan submodule handling is
> involved here, so it's a bit different.
> 
> In prjxray, the main program and the generated files move independently, no
> submodules are involved.
> 
> The watch file uses two components for that:
> 
> Version: 5
> Version-Schema: group
> 
> Mode: git
> Source: https://github.com/f4pga/prjxray.git
> #Matching-Pattern: refs/tags/v(.+)
> Matching-Pattern: heads/master
> Git-Pretty: describe
> Git-Modules: all
> Compression: xz
> Version-Mangle: s/\.([0-9]+)\.(g[0-9a-fA-F]{8})$/+git$1.$2/
> Filename-Mangle: s/^(@PACKAGE@-)v/$1/
> 
> Mode: git
> Component: database
> Source: https://github.com/f4pga/prjxray-db.git
> Matching-Pattern: HEAD
> Git-Pretty: db%cd.g%h
> Compression: xz
> 
> If the main repository is available as a remote in the current working
> directory, but the database repository isn't, this falls over with:
> 
> $ git clone https://salsa.debian.org/electronics-team/prjxray.git
> $ cd prjxray
> $ git remote add tools https://github.com/f4pga/prjxray.git
> $ git fetch tools
> $ uscan
> fatal: Not a valid object name tools/HEAD
> uscan: error: git describe --tags tools/HEAD subprocess returned exit status 
> 128
> 
> Fixing the immediate problem
> 
> $ git remote set-head tools master
> 
> then leads to a new issue
> 
> $ uscan
> Newest version of database on remote site is db20260725.gf8826f35, local 
> version is db20211214.g0a0added
>  => Newer package available from:
>         => https://github.com/f4pga/prjxray-db.git HEAD
> Successfully repacked ../prjxray-0.1+git3356.gc9f02d85.tar.xz as 
> ../prjxray_0.1+git3356.gc9f02d85.orig.tar.xz, deleting 18 files from it.
> Successfully symlinked ../prjxray-db20260725.gf8826f35.tar.xz to 
> ../prjxray_db20260725.gf8826f35.orig-database.tar.xz.
> uscan warn: rename ../prjxray_0.1+git3356.gc9f02d85.orig.tar.xz to 
> ../prjxray_0.1+git3356.gc9f02d85+~db20260725.gf8826f35.orig.tar.xz
> uscan warn: rename ../prjxray_db20260725.gf8826f35.orig-database.tar.xz to 
> ../prjxray_0.1+git3356.gc9f02d85+~db20260725.gf8826f35.orig-database.tar.xz

Hi, Simon.

I have been looking at this and seems that the origin is that
$self->downloader->git_upstream, containing remote name, is not
reset across components. Once added code to reset it, noticed
that wrong dir was being used leading to another failure. Also
noticed that in this case, info is first processed for all
components and used later, leading to an error associated to
using the wrong dir (and leaving the other dir not removed).
Also noticed that when no remotes are defined,
prjxray-temporary.??.git and prjxray-temporary.??.database.git
dirs are not removed and left behind.

I have been doing some hacks to deal with all this, see attached
patch. I have no experience at all with anything related to object
oriented perl and little experience with uscan internals. That is
why I am not tagging this bug report as patch, these changes
require a careful review from someone really knowing uscan
internals (I think it would also be interesting to make sure that
a component is completely processed before going to the next one).
With these changes things seem to work,

Newest version of prjxray on remote site is 0.1+git3356.gc9f02d85, specified 
download version is 0.1+git3356.gc9f02d85
Newest version of database on remote site is db20211214.g0a0adde, specified 
download version is db20211214.g0a0added
Successfully repacked ../prjxray-0.1+git3356.gc9f02d85.tar.xz as 
../prjxray_0.1+git3356.gc9f02d85.orig.tar.xz, deleting 18 files from it.
Successfully symlinked ../prjxray-db20211214.g0a0adde.tar.xz to 
../prjxray_db20211214.g0a0adde.orig-database.tar.xz.
uscan warn: rename ../prjxray_0.1+git3356.gc9f02d85.orig.tar.xz to 
../prjxray_0.1+git3356.gc9f02d85+~db20211214.g0a0adde.orig.tar.xz
uscan warn: rename ../prjxray_db20211214.g0a0adde.orig-database.tar.xz to 
../prjxray_0.1+git3356.gc9f02d85+~db20211214.g0a0adde.orig-database.tar.xz

Version in database renaming seems still wrong, but original
version seems OK.

Hope this helps in some way.

Regards,

--- 
Agustin
>From 1d77dd950bc2726f6fb697b09df2180e656e60ff Mon Sep 17 00:00:00 2001
From: Agustin Martin Domingo <[email protected]>
Date: Mon, 26 Oct 2026 12:42:44 +0100
Subject: [PATCH] uscan:{Downloader,WatchSource,Modes/Git}.pm: Try to better
 deal with components.

NOT READY FOR COMMIT BEFORE REVIEW.

 * Reset $self->downloader->git_upstream between components.
 * Keep track of component vs cloned gitrepo (if any) data and use
   as appropriate.
 * downloader->clean: Fix directory to remove and make conditional.

Closes: #1145549
---
 lib/Devscripts/Uscan/Downloader.pm  | 38 ++++++++++++++++++++++-------
 lib/Devscripts/Uscan/Modes/Git.pm   |  8 ++++++
 lib/Devscripts/Uscan/WatchSource.pm | 15 ++++++++++--
 3 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/lib/Devscripts/Uscan/Downloader.pm b/lib/Devscripts/Uscan/Downloader.pm
index 4dfa5dab..590a0fb8 100644
--- a/lib/Devscripts/Uscan/Downloader.pm
+++ b/lib/Devscripts/Uscan/Downloader.pm
@@ -38,6 +38,12 @@ has agent =>
 has timeout => (is => 'rw');
 has destdir => (is => 'rw');
 
+# Reference to a hash with component vs cloned gitrepo (if any).
+has cloned_gitrepo => (is => 'rw', default => sub { {} });
+
+# Name used as index for no component entry in $self->cloned_gitrepo.
+has no_component => (is => 'ro', default => sub { "main-component" });
+
 # 0: no repo, 1: shallow clone, 2: full clone
 has gitrepo_state => (
     is      => 'rw',
@@ -138,7 +144,9 @@ sub download ($$$$$$$$) {
         my $suffix  = $3;
         my ($gitrepo, $gitref) = split /[[:space:]]+/, $url, 2;
         my $clean = sub {
-            uscan_exec_no_fail('rm', '-fr', $gitrepo_dir);
+            uscan_exec_no_fail('rm', '-fr', "$destdir/$gitrepo_dir")
+              if $gitrepo_dir
+              and $optref->pgpmode ne "gittag";
         };
         my $clean_and_die = sub {
             $clean->();
@@ -180,6 +188,7 @@ sub download ($$$$$$$$) {
             my @attr_files;
 
             if (!$self->git_upstream) {
+                my $lcl_component = $optref->component || $self->no_component;
                 # clone main repository
                 if ($self->gitrepo_state == 0) {
                     my @opts = ();
@@ -194,6 +203,7 @@ sub download ($$$$$$$$) {
                     } else {
                         $self->gitrepo_state(2);
                     }
+                    # Clone git repo.
                     uscan_exec('git', 'clone', @opts, $base,
                         "$destdir/$gitrepo_dir");
                 }
@@ -207,13 +217,16 @@ sub download ($$$$$$$$) {
                     foreach my $m (@{ $optref->git->{modules} }) {
                         push(@opts, "$m");
                     }
-                    chdir "$destdir/$gitrepo_dir";
+                    chdir "$destdir/$gitrepo_dir"
+                      if $gitrepo_dir;
                     uscan_exec('git', 'submodule', @opts);
                 }
 
-                chdir "$destdir/$gitrepo_dir"
-                  or $clean_and_die->(
-                    "Unable to chdir($destdir/$gitrepo_dir): $!");
+                if ($gitrepo_dir) {
+                    chdir "$destdir/$gitrepo_dir"
+                      or $clean_and_die->(
+                        "Unable to chdir($destdir/$gitrepo_dir): $!");
+                }
             }
 
             if ($self->git_export_all) {
@@ -263,10 +276,17 @@ sub download ($$$$$$$$) {
             }
 
             # archive main repository
-            uscan_exec_no_fail(@git, 'archive', '--format=tar',
-                "--prefix=$pkg-$ver/",
-                "--output=$abs_dst/$pkg-$ver.tar", $gitref) == 0
-              or $clean_and_die->("$gitrepo_dir", "git archive failed");
+            if (
+                uscan_exec_no_fail(@git, 'archive', '--format=tar',
+                    "--prefix=$pkg-$ver/", "--output=$abs_dst/$pkg-$ver.tar",
+                    $gitref) != 0
+            ) {
+                if ($gitrepo_dir) {
+                    $clean_and_die->("$gitrepo_dir", "git archive failed");
+                } else {
+                    uscan_die("git archive failed");
+                }
+            }
 
             # archive submodules, append to main tarball, clean up
             if ($optref->git->{modules}) {
diff --git a/lib/Devscripts/Uscan/Modes/Git.pm b/lib/Devscripts/Uscan/Modes/Git.pm
index 451ebd79..9458c7a8 100644
--- a/lib/Devscripts/Uscan/Modes/Git.pm
+++ b/lib/Devscripts/Uscan/Modes/Git.pm
@@ -28,6 +28,8 @@ sub git_search {
           . $out
           . "========\n";
 
+        $self->downloader->git_upstream('');    # Reset for each component.
+
         # Check whether any remote repository URLs match debian/watch Source
         if ($out and $out =~ /^(\S+)\s+\Q$self->{parse_result}->{base}\E/m) {
             my $remote = $1;
@@ -54,6 +56,8 @@ sub git_search {
 
     # Clone git repository (HEAD or heads/<branch> only)
     if ($self->versionless and not $self->downloader->git_upstream) {
+        my $lcl_component
+          = $self->component || $self->downloader->no_component;
         push(@args, '--quiet') if not $verbose;
         push(@args, '--bare')  if not $self->git->{modules};
 
@@ -73,6 +77,10 @@ sub git_search {
             push(@args, '-b', "$newfile");
         }
 
+        # Keep track of component->cloned_gitrepo info
+        my $tmp_hash = $self->downloader->cloned_gitrepo;
+        $tmp_hash->{$lcl_component} = $self->gitrepo_dir;
+        $self->downloader->cloned_gitrepo($tmp_hash);
         # Clone main repository
         uscan_exec(
             'git', 'clone', @args,
diff --git a/lib/Devscripts/Uscan/WatchSource.pm b/lib/Devscripts/Uscan/WatchSource.pm
index 20e2b1b6..290c635c 100644
--- a/lib/Devscripts/Uscan/WatchSource.pm
+++ b/lib/Devscripts/Uscan/WatchSource.pm
@@ -1147,6 +1147,17 @@ sub download_file_and_sig {
     uscan_debug "line: download_file_and_sig()";
     my $skip_git_vrfy;
 
+    my $lcl_component = $self->component || $self->downloader->no_component;
+    my $lcl_gitrepo_dir;
+    if (%{ $self->downloader->cloned_gitrepo }) {
+        $lcl_gitrepo_dir
+          = defined $self->downloader->cloned_gitrepo->{$lcl_component}
+          ? $self->downloader->cloned_gitrepo->{$lcl_component}
+          : undef;
+    } else {
+        $lcl_gitrepo_dir = $self->gitrepo_dir;
+    }
+
     # If we're not downloading or performing signature verification, we can
     # stop here
     if (!$self->shared->{download} || $self->shared->{signature} == -1) {
@@ -1187,7 +1198,7 @@ sub download_file_and_sig {
                 $self->pkg_dir,
                 $self->pkg,
                 $self->mode,
-                $self->gitrepo_dir,
+                $lcl_gitrepo_dir,
             );
             if ($download_available) {
                 dehs_verbose
@@ -1211,7 +1222,7 @@ sub download_file_and_sig {
                 $self->pkg_dir,
                 $self->pkg,
                 $self->mode,
-                $self->gitrepo_dir,
+                $lcl_gitrepo_dir,
             );
             if ($download_available) {
                 dehs_verbose
-- 
2.55.0

Reply via email to