Control: tag -1 patch

On 15.08.2015 02:13, Russ Allbery wrote:
> I believe the explanation is that selecting the distribution doesn't work
> the way that you think it does.  It just changes the prioritization used
> for selecting packages to install, which is then ignored by the source
> command.  (I could have the details wrong; this is vague memory from
> previous discussions.)

Actually the explanation is that it's a bug (or two) in apt.
The code responsible for this behavior is [1]:

      while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) 
      {
         const string Ver = Parse->Version();

         // See if we need to look for a specific release tag
         if (RelTag != "" && UserRequestedVerTag == "")
         {
            const string Rel = GetReleaseForSourceRecord(SrcList, Parse);

            if (Rel == RelTag) /// <-- Here it compares the '-t' argument with 
the release, e.g. stable/unstable. 
            {
               Last = Parse;
               Offset = Parse->Offset();
               Version = Ver; /// <-- Here it can have the correct version. :-)
            }
         }

         // Ignore all versions which doesn't fit
         if (VerTag.empty() == false &&
             Cache->VS().CmpVersion(VerTag, Ver) != 0) // exact match
            continue;

         // Newer version or an exact match? Save the hit
         if (Last == 0 || Cache->VS().CmpVersion(Version,Ver) < 0) {
            Last = Parse;
            Offset = Parse->Offset();
            Version = Ver; /// <-- But here it overwrites the found version 
with any newer one. :-(
         }

         // was the version check above an exact match?
         // If so, we don't need to look further
         if (VerTag.empty() == false && (VerTag == Ver))
            break;
      }

To fix this problem, one can add a 'break;' at the point, where apt got
the correct version.
Then 'apt-get -t unstable source <source-pkg>' works as expected,
but  'apt-get -t sid source <source-pkg>' still doesn't work, because
apt doesn't compare with the distribution codename, e.g. jessie/sid.
That's not hard to fix either.

> It would be great if this could be fixed at some point, since it's really
> surprising UI behavior.

Attached patch fixes both problems, so hopefully the next apt release gets
this right.

Best regards,
Andreas


1: 
https://anonscm.debian.org/cgit/apt/apt.git/tree/cmdline/apt-get.cc?id=990af3c952676eaa51ccd614ab2d4234693da397#n383
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -161,7 +161,7 @@ static std::string MetaIndexFileNameOnDisk(metaIndex *metaindex)
 // ---------------------------------------------------------------------
 /* */
 static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList,
-                                      pkgSrcRecords::Parser *Parse)
+                                      pkgSrcRecords::Parser *Parse, std::string &Dist)
 {
    // try to find release
    const pkgIndexFile& CurrentIndexFile = Parse->Index();
@@ -184,6 +184,7 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList,
             {
                indexRecords records;
                records.Load(path);
+               Dist = records.GetDist();
                return records.GetSuite();
             }
          }
@@ -387,13 +388,15 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
          // See if we need to look for a specific release tag
          if (RelTag != "" && UserRequestedVerTag == "")
          {
-            const string Rel = GetReleaseForSourceRecord(SrcList, Parse);
+            string Dist;
+            const string Rel = GetReleaseForSourceRecord(SrcList, Parse, Dist);
 
-            if (Rel == RelTag)
+            if (Rel == RelTag || Dist == RelTag)
             {
                Last = Parse;
                Offset = Parse->Offset();
                Version = Ver;
+               break;
             }
          }
 

Reply via email to