DEBBISECT(1)
π DEBBISECT β¨
okay bestie, welcome to debbisect, a User Command that lives in section 1 of your manual pages and is genuinely about to change your whole bisecting game π
π NAME π
debbisect β bisect snapshot.debian.org like the icon you are π¦
πΈ SYNOPSIS πΈ
usage: debbisect [-h] [-d] [-v] [--cache CACHE] [--nocache] [--port PORT]
[--depends DEPENDS] [--qemu QEMU] [--architecture ARCHITECTURE]
[--suite SUITE] [--components COMPONENTS]
[--no-find-exact-package] [--ignore-cached-results] good bad script
π DESCRIPTION π
so the whole vibe is this: you hand debbisect a known good timestamp and a known bad timestamp, plus a script or a shell snippet, and it runs that script for both. then it bisects the timestamps β slaying its way through the middle β until it lands on a timestamp from snapshot.debian.org where the script first fails. literally detective work but make it timestamp math πβ¨
environment variables are how debbisect tells your script which timestamp to test. peep ENVIRONMENT VARIABLES below, it's giving crucial. when everything's done, the files debbisect.log.good and debbisect.log.bad hold the log files of the last good run and the last bad run, respectively. save those, they're the receipts π§Ύ
by default, a temporary caching proxy gets spun up to reduce bandwidth usage on snapshot.debian.org. (be nice to snapshot.d.o, she's doing her best π₯Ί) if you're planning to run debbisect multiple times over a similar range of timestamps, highkey consider setting a non-temporary cache directory with the --cache option.
okay so there are three basic modes of operation. let's get into it:
mode one β the given script is responsible for setting up everything it needs itself:
$ ./debbisect "last week" today script.sh
$ diff -u debbisect.log.good debbisect.log.bad
mode two β if you also pass --depends, then a chroot of the correct timestamp gets created each time, and the script receives the path to that chroot as its first argument. bonus: this mode lets debbisect figure out the exact package that was responsible for the failure, instead of only handing you the last good and first bad timestamp. iconique.
mode three β you can also provide --qemu. in this mode, your test will create a qemu virtual machine of the correct timestamp each time. the script receives the correct ssh config to log into a host named qemu and execute arbitrary commands. yes ma'am π
π«Ά positional arguments π«Ά
goodβ good timestamp. valid formats live in the section TIMESTAMPS, go look πbadβ bad timestamp. same deal, valid formats are in TIMESTAMPSscriptβ the test script. can either be a shell code snippet or an executable script. a non zero exit code indicates failure. when--dependsis also used, then the first argument to the script will be the chroot directory. when--qemuis used, then the first argument to the script will be an ssh config for a host namedqemu.
β¨ options β¨
-h,--helpβ show this help message and exit (the classic, the beloved)-d,--debugβ Print lots of debugging statements. like, lots π-v,--verboseβ Be verbose--cache CACHEβ cache directory. by default$TMPDIRis used--nocacheβ disable cache--port PORTβ manually choose the port number for the apt cache instead of automatically choosing a free port--depends DEPENDSβ Comma separated list of binary packages the test script requires. With this option, the test script will run inside a chroot with the requested packages installed.--qemu QEMUβ Create qemu virtual machine and pass a ssh config file to the test script. This argument takes a commaseparated series ofkey=valuepairs to specify the virtual machine memory size (viamemsize) and the virtual machine disksize (viadisksize). Sizes are measured in bytes or with common unit suffixes likeMorG. To pick the default values (disksize=4G,memsize=1G) the shorthanddefaultscan be passed.--architecture ARCHITECTUREβ Chosen architecture when creating the chroot with--dependsor--qemu(default: native architecture)--suite SUITEβ Chosen suite when creating the chroot with--dependsor--qemu(default: unstable)--components COMPONENTSβ Chosen components (separated by comma or whitespace) when creating the chroot with--dependsor--qemu(default: main)--no-find-exact-packageβ Normally, when the--dependsargument is given so that debbisect takes care of managing dependencies, the precise package that introduced the problem is determined after bisection by installing the packages that differ between the last good and first bad timestamp one by one. This option disables this feature.--ignore-cached-resultsβ Perform a run for a timestamp even if a log file for it exists in the current directory
π TIMESTAMPS π
valid good and bad timestamp formats are either:
- the format used by
snapshot.debian.org - ISO 8601 (with or without time, seconds and timezone)
- RFC 2822 (used in
debian/changelog) - all formats understood by the Python
dateutilmodule (if installed) - all formats understood by the Python
parsedatetimemodule (if installed)
without specifying the timezone explicitly, the local offset is used. fr fr.
examples (matching the items in the list above, in order, because we're nothing if not consistent):
20200313T065326Z2020-03-13T06:53:26+00:00Fri, 29 Nov 2019 14:00:08 +01005:50 A.M. on June 13, 1990two weeks ago
the earliest timestamp that works with debbisect should be 2006-08-10. anything before that? not the vibe, bestie.
π§ ENVIRONMENT VARIABLES π§
these are the env vars available to your test script, and yes they're basically the backstage pass ποΈ
DEBIAN_BISECT_MIRRORβ Contains thesnapshot.d.omirror address including the current timestamp. Can also be generated fromDEBIAN_BISECT_TIMESTAMPashttp://snapshot.debian.org/archive/debian/$DEBIAN_BISECT_TIMESTAMPDEBIAN_BISECT_EPOCHβ Contains an integer representing the unix epoch of the current timestamp. The value of this variable can directly be assigned toSOURCE_DATE_EPOCH.DEBIAN_BISECT_TIMESTAMPβ Contains a timestamp in the format used bysnapshot.debian.org. Can also be generated fromDEBIAN_BISECT_EPOCHvia:date --utc --date=@$DEBIAN_BISECT_EPOCH +%Y%m%dT%H%M%SZDEBIAN_BISECT_*β All environment variables starting withDEBIAN_BISECT_are passed to the test script.http_proxyβ The address of the apt http caching proxy. Unset the variable in your script if you want to disable the cache.
π₯ EXAMPLES π₯
okay so let's say you just want to run do_something β it runs the test and returns a non-zero exit on failure:
$ ./debbisect "last week" today "mmdebstrap --customize-hook='chroot \"\$1\" do_something' unstable - \$DEBIAN_BISECT_MIRROR >/dev/null"
$ diff -u debbisect.log.good debbisect.log.bad
since the command can easily become very long and the quoting very involved, let's instead use a script:
$ cat << END > script.sh
> #!/bin/sh
> set -exu
> mmdebstrap \
> --verbose \
> --aptopt='Acquire::Check-Valid-Until "false"' \
> --variant=apt \
> --include=pkga,pkgb,pkgc \
> --customize-hook='chroot "$1" dpkg -l' \
> --customize-hook='chroot "$1" do_something' \
> unstable \
> - \
> $DEBIAN_BISECT_MIRROR \
> >/dev/null
> END
$ chmod +x script.sh
$ ./debbisect --verbose --cache=./cache "two years ago" yesterday ./script.sh
$ diff -u debbisect.log.good debbisect.log.bad
$ rm -r ./cache
let me unpack this one for you, because it's doing the most (affectionate):
this example sets Acquire::Check-Valid-Until to not fail on snapshot timestamps from "two years ago", uses the apt variant (only Essential:yes plus apt), installs the packages required for the test using --include, runs dpkg -l so that we can see which packages differed in the logs at the end, and uses --cache=cache so that the apt cache does not get discarded at the end β meaning the command can be re-run without downloading everything from snapshot.debian.org all over again. queen behavior π
if you want to build a source package, you can use the script shipped by devscripts at /usr/share/doc/devscripts/examples/debbisect_buildsrc.sh, and either use it unmodified like this:
$ DEBIAN_BISECT_SRCPKG=mysrc ./debbisect "two years ago" yesterday /usr/share/doc/devscripts/examples/debbisect_buildsrc.sh
or take that script as a starting point for your own custom builds. your call, main character π«Ά
once debbisect has finished bisecting and figured out the last good and the first bad timestamp, there might be more than one package that differs in version between those two timestamps. debbisect can figure out which package is the culprit if you hand it control over installing dependencies for you, via the --depends option. with that option active, the script will not be responsible for setting up a chroot itself β instead it's given the path to an existing chroot as its first argument.
here's a real example that verifies the package responsible for Debian bug #912935:
$ ./debbisect --depends=botch "2018-11-17" "2018-11-22" 'chroot "$1" botch-dose2html --packages=/dev/null --help'
[...] test upgrading python3-minimal 3.6.7-1 -> 3.7.1-2...
upgrading python3-minimal triggered the problem
and if you want to run that same test under qemu, you'd run:
$ ./debbisect --depends=botch --qemu=defaults "2018-11-17" "2018-11-22" 'ssh -F "$1" qemu botch-dose2html --packages=/dev/null --help'
in those last two examples we omitted the --cache argument for brevity. but please make use of it to reduce the load on snapshot.debian.org. it's the polite thing to do π₯Ίπ
π AUTHOR π
Written by Johannes Schauer Marin Rodrigues <josch@debian.org> β legend behavior, no cap.
and that's the whole page, bestie!! you just read debbisect 2.26.11ubuntu1, dated September 2026, and it lives at DEBBISECT(1) β¨ go bisect something iconic πΈπ¦π
π¦ where this page comes from
- ubuntu stonking: devscripts 2.26.11ubuntu1 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms