From e84adb76c87f419ed5bad8f7d08a4132de2bc406 Mon Sep 17 00:00:00 2001
From: David Kalnischkies <kalnischkies@gmail.com>
Date: Tue, 30 Mar 2010 17:47:19 +0200
Subject: try version match in FindSrc first exact than fuzzy (LP: #551178)

---
 cmdline/apt-get.cc | 32 +++++++++++++++++++++-----------
 debian/changelog   |  1 +
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 7875ae20f..5af2dca04 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -1291,12 +1291,26 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
    {
       if(VerTag.empty() == false || DefRel.empty() == false) 
       {
+	 bool fuzzy = false;
 	 // we have a default release, try to locate the pkg. we do it like
 	 // this because GetCandidateVer() will not "downgrade", that means
 	 // "apt-get source -t stable apt" won't work on a unstable system
-	 for (pkgCache::VerIterator Ver = Pkg.VersionList();
-	      Ver.end() == false; Ver++) 
+	 for (pkgCache::VerIterator Ver = Pkg.VersionList();; Ver++)
 	 {
+	    // try first only exact matches, later fuzzy matches
+	    if (Ver.end() == true)
+	    {
+	       if (fuzzy == true)
+		  break;
+	       fuzzy = true;
+	       Ver = Pkg.VersionList();
+	    }
+	    // We match against a concrete version (or a part of this version)
+	    if (VerTag.empty() == false &&
+		(fuzzy == true || Cache.VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match
+		(fuzzy == false || strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)) // fuzzy match
+	       continue;
+
 	    for (pkgCache::VerFileIterator VF = Ver.FileList();
 		 VF.end() == false; VF++) 
 	    {
@@ -1309,10 +1323,6 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
 		   pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver)
 		  continue;
 
-	       // We match against a concrete version (or a part of this version)
-	       if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)
-		  continue;
-
 	       // or we match against a release
 	       if(VerTag.empty() == false ||
 		  (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) ||
@@ -1323,10 +1333,9 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
 		  // no SourcePkg name, so it is the "binary" name
 		  if (Src.empty() == true)
 		     Src = TmpSrc;
-		  // no Version, so we try the Version of the SourcePkg -
-		  // and after that the version of the binary package
-		  if (VerTag.empty() == true)
-		     VerTag = Parse.SourceVer();
+		  // the Version we have is possibly fuzzy or includes binUploads,
+		  // so we use the Version of the SourcePkg (empty if same as package)
+		  VerTag = Parse.SourceVer();
 		  if (VerTag.empty() == true)
 		     VerTag = Ver.VerStr();
 		  break;
@@ -1390,7 +1399,8 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
 	 const string Ver = Parse->Version();
 
 	 // Ignore all versions which doesn't fit
-	 if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0)
+	 if (VerTag.empty() == false &&
+	     Cache.VS().CmpVersion(VerTag, Ver) != 0) // exact match
 	    continue;
 
 	 // Newer version or an exact match? Save the hit
diff --git a/debian/changelog b/debian/changelog
index bd1fda316..61a4dc618 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -43,6 +43,7 @@ apt (0.7.26) UNRELEASED; urgency=low
   * cmdline/apt-get.cc:
     - add a --only-upgrade flag to install command (Closes: #572259)
     - fix memory leaks in error conditions in DoSource()
+    - try version match in FindSrc first exact than fuzzy (LP: #551178)
   * apt-pkg/contrib/cmndline.cc:
     - save Commandline in Commandline::AsString for logging
   * apt-pkg/deb/debversion.cc:
-- 
cgit v1.2.3