Package: devscripts
Version: 2.24.8
Severity: wishlist
Tags: patch

Hi. A few weeks ago I asked here how a bisect should be done
when bad < good and the aim is to know when something was fixed:

https://lists.debian.org/debian-mentors/2024/11/msg00056.html

The simple solution is to use another script with the exit status reversed.

However, when doing that, we have to change the way we call things.
Good becomes bad and bad becomes good, and if we cut and paste the
final output from debbisect, we have to clarify that the meanings
are swapped.

A better solution is to implement this "natively" in debbisect,
which is what the attached patch tries to do.

It mostly works for me, but it probably needs more testing.

I've also opened a Merge Request in salsa in case it helps.

Thanks.
commit 6226793a2553eba2db3c3b36485f8cc5a879da1d
Author: Santiago Vila <sanv...@debian.org>
Date:   Mon Dec 23 21:05:00 2024 +0100

    scripts/debbisect: Add --reverse option
    
    When using --reverse, the aim of the search is to find the timestamp when
    the bug was fixed, so it needs to happen that bad < good

diff --git a/scripts/debbisect b/scripts/debbisect
index df5e5022..da444fa9 100755
--- a/scripts/debbisect
+++ b/scripts/debbisect
@@ -374,13 +374,13 @@ def bisect(good, bad, staticargs):
     # unreadable
     # pylint: disable=too-many-statements
     diff = bad - good
-    print(f"snapshot timestamp difference: {diff / timedelta(days=1)} days")
+    print(f"snapshot timestamp difference: {abs(diff / timedelta(days=1))} 
days")
 
     stepnum = 1
     starttime = datetime.now(timezone.utc)
 
     steps = round(
-        (math.log(diff.total_seconds()) - math.log(DINSTALLRATE)) / 
math.log(2) + 2
+        (math.log(abs(diff.total_seconds())) - math.log(DINSTALLRATE)) / 
math.log(2) + 2
     )
     print(f"approximately {steps} steps left to test")
     # verify that the good timestamp is really good and the bad timestamp is 
really bad
@@ -406,7 +406,7 @@ def bisect(good, bad, staticargs):
             return None
     stepnum += 1
     steps = round(
-        (math.log(diff.total_seconds()) - math.log(DINSTALLRATE)) / 
math.log(2) + 1
+        (math.log(abs(diff.total_seconds())) - math.log(DINSTALLRATE)) / 
math.log(2) + 1
     )
     timeleft = steps * (datetime.now(timezone.utc) - starttime) / (stepnum - 1)
     print(f"computation time left: {timeleft}")
@@ -444,16 +444,13 @@ def bisect(good, bad, staticargs):
         # other guessing magic.
         newts = sanitize_timestamp(good + diff / 2)
         if newts in [good, bad]:
-            # If the middle timestamp mapped onto good or bad, then the
-            # timestamps are very close to each other. Test if there is maybe
-            # not another one between them by sanitizing the timestamp one
-            # second before the bad one
-            newts = sanitize_timestamp(bad - timedelta(seconds=1))
-            if newts == good:
-                break
-        print(f"snapshot timestamp difference: {diff / timedelta(days=1)} 
days")
+            # If the middle timestamp mapped onto good or bad, we assume
+            # that there is not any intermediate timestamp in 
snapshot.debian.org
+            # and the bisect is done
+            break
+        print(f"snapshot timestamp difference: {abs(diff / timedelta(days=1))} 
days")
         steps = round(
-            (math.log(diff.total_seconds()) - math.log(DINSTALLRATE)) / 
math.log(2) + 0
+            (math.log(abs(diff.total_seconds())) - math.log(DINSTALLRATE)) / 
math.log(2) + 0
         )
         timeleft = steps * (datetime.now(timezone.utc) - starttime) / (stepnum 
- 1)
         print(f"computation time left: {timeleft}")
@@ -933,6 +930,11 @@ Written by Johannes Schauer Marin Rodrigues 
<jo...@debian.org>
         "the first argument to the script will an ssh config for a host "
         "named qemu.",
     )
+    parser.add_argument(
+        "--reverse",
+        help="Find when the bug was fixed (requires that bad < good)",
+        action="store_true",
+    )
     return parser.parse_args()
 
 
@@ -1023,8 +1025,12 @@ def main():
             f" snapshot.d.o timestamp {format_timestamp(bad)}"
         )
 
-    if good > bad:
-        print("good is later than bad")
+    if good > bad and not args.reverse:
+        print("good is later than bad (enable --reverse to reverse logic)")
+        sys.exit(1)
+
+    if bad > good and args.reverse:
+        print("bad is later than good (drop --reverse to reverse logic)")
         sys.exit(1)
 
     # check if mmdebstrap is installed and at least 1.3.0
@@ -1050,6 +1056,7 @@ def main():
             "ignore_cached_results",
             "cache",
             "nocache",
+            "reverse",
         ],
     )
     for a in staticargs._fields:
@@ -1081,8 +1088,12 @@ def main():
     if res is not None:
         good, bad = res
         print("bisection finished successfully")
-        print(f"  last good timestamp: {format_timestamp(good)}")
-        print(f"  first bad timestamp: {format_timestamp(bad)}")
+        if args.reverse:
+            print(f"  last bad timestamp: {format_timestamp(bad)}")
+            print(f"  first good timestamp: {format_timestamp(good)}")
+        else:
+            print(f"  last good timestamp: {format_timestamp(good)}")
+            print(f"  first bad timestamp: {format_timestamp(bad)}")
 
         find_exact_package(
             good, bad, staticargs, args.depends, args.no_find_exact_package

Reply via email to