Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/storage-git-gix/parked-gix/.nornir/bench/have-mix.sh

#!/bin/bash
# Derive the REAL hit/miss mix and the REAL round sizes of a negotiation's `have`
# list, by running actual `git fetch`es against the 19 mirrored
# workspace_nordisk repositories and asking the SERVER whether it holds each oid
# the CLIENT offered.
#
# The client is made genuinely behind: reset, drop the remote-tracking ref, expire
# the reflog and `gc --prune=now`, so the newer objects are really gone. Without
# that the client still holds everything, git says "up to date", and the trace
# contains no `have` at all — which is exactly what the first version of this
# script measured.
#
# Two shapes:
#   behind-<D>    : client D commits behind the server, no local work.
#   divergent-<K> : client 10 behind AND holding K local commits of its own.
#
# The haves are taken off the wire (GIT_TRACE_PACKET), not modelled.
#
# LAW 2, added 2026-08-04. Every bail-out below is `|| continue`, which is right
# for one repository that cannot be shaped and catastrophic as a whole-script
# outcome: with the corpus absent the glob stays literal, every iteration
# `continue`s, and the script prints `rows: 0` and exits **0**. Empty output is
# shaped exactly like a legitimate result. Three things now make that impossible:
#
#   * the corpus directory and the glob are checked before the loop;
#   * `git cat-file`'s answer is checked to have one line per `have` — it is
#     `paste`d against them positionally, so a short read does not fail, it
#     SHIFTS every later hit onto the wrong oid, and a completely failed read
#     reports a 100% miss rate as a measurement;
#   * `rows: 0` is a non-zero exit.
set -u -o pipefail
MIRRORS=${HAVE_MIX_MIRRORS:-/home/rickard/scratch/gunnar-bench-fixtures/real-corpus}
WORK=/home/rickard/scratch/have-mix
OUT=/home/rickard/scratch/have-mix.tsv
die() { echo "FATAL: $*" >&2; exit 1; }
[ -d "$MIRRORS" ] || die "no corpus at $MIRRORS. Build it with the real-corpus \
fixture (nornir-bench) or point HAVE_MIX_MIRRORS at one. A missing corpus makes \
every loop below \`continue\` and the script exits 0 having measured nothing."
shopt -s nullglob
MIRROR_DIRS=("$MIRRORS"/*.git)
[ "${#MIRROR_DIRS[@]}" -gt 0 ] || die "$MIRRORS holds no *.git mirror"
rm -rf "$WORK"; mkdir -p "$WORK"
printf 'repo\tshape\tround\thaves\thits\tmisses\n' > "$OUT"
export GIT_LFS_SKIP_SMUDGE=1

for m in "${MIRROR_DIRS[@]}"; do
  repo=$(basename "$m" .git)
  br=$(git -C "$m" symbolic-ref --short HEAD 2>/dev/null) || continue
  n=$(git -C "$m" rev-list --count "$br" 2>/dev/null || echo 0)
  [ "$n" -lt 25 ] && continue

  for shape in behind-1 behind-10 behind-100 behind-400 divergent-1 divergent-10 divergent-40 divergent-200; do
    depth=${shape#*-}
    case "$shape" in
      behind-*)    back=$depth; local_k=0 ;;
      divergent-*) back=10;     local_k=$depth ;;
    esac
    [ "$back" -ge "$n" ] && continue

    c="$WORK/$repo-$shape"
    rm -rf "$c"
    git clone --quiet --no-tags --single-branch --branch "$br" "file://$m" "$c" >/dev/null 2>&1 || continue
    git -C "$c" reset --quiet --hard "HEAD~$back" 2>/dev/null || { rm -rf "$c"; continue; }
    git -C "$c" update-ref -d "refs/remotes/origin/$br" 2>/dev/null
    git -C "$c" update-ref -d refs/remotes/origin/HEAD 2>/dev/null
    rm -f "$c/.git/FETCH_HEAD"
    git -C "$c" reflog expire --expire=now --all >/dev/null 2>&1
    git -C "$c" gc --prune=now --quiet >/dev/null 2>&1
    i=0
    while [ "$i" -lt "$local_k" ]; do
      git -C "$c" -c user.name=b -c user.email=b@b commit --quiet --allow-empty -m "local $i" 2>/dev/null
      i=$((i+1))
    done

    trace="$c/trace.txt"
    GIT_TRACE_PACKET="$trace" git -C "$c" -c protocol.version=2 fetch --quiet origin "$br" >/dev/null 2>&1
    [ -s "$trace" ] || { rm -rf "$c"; continue; }

    # One round per `command=fetch` the CLIENT sends.
    awk '/fetch> command=fetch/{r++} /fetch> have /{if (r>0) print r"\t"$NF}' "$trace" > "$c/haves.txt"
    [ -s "$c/haves.txt" ] || { rm -rf "$c"; continue; }

    # Ask the SERVER. `cat-file --batch-check` prints "<oid> missing" for an oid
    # the repository does not hold, and "<oid> <type> <size>" for one it does.
    cut -f2 "$c/haves.txt" | git -C "$m" cat-file --batch-check 2>/dev/null \
      | awk '{print ($NF=="missing") ? 0 : 1}' > "$c/present.txt"

    # `paste` joins by POSITION, and pads a short file with empties. A
    # `cat-file` that died halfway therefore does not fail — it shifts every
    # remaining answer onto the wrong oid, and one that produced nothing at all
    # makes `$3` never equal 1, i.e. a 100% miss rate reported as a result. This
    # is the whole reason the script's stderr is discarded above and its exit
    # status is invisible, so the line count is what has to be checked.
    hn=$(wc -l < "$c/haves.txt"); pn=$(wc -l < "$c/present.txt")
    [ "$hn" -eq "$pn" ] || die "$repo/$shape: $hn have(s) offered but \`cat-file \
--batch-check\` answered $pn line(s). \`paste\` joins by position, so this would \
have been charted as a hit/miss mix rather than as the broken read it is."

    paste "$c/haves.txt" "$c/present.txt" \
      | awk -v repo="$repo" -v shape="$shape" '
          {r=$1+0; tot[r]++; if ($3==1) hit[r]++}
          END {for (k in tot) printf "%s\t%s\t%d\t%d\t%d\t%d\n", repo, shape, k, tot[k], hit[k]+0, tot[k]-(hit[k]+0)}' \
      | sort -k3,3n >> "$OUT"
    rm -rf "$c"
  done
done
rows=$(( $(wc -l < "$OUT") - 1 ))
echo "rows: $rows"
# Non-vacuity. Every bail-out above is a `continue`, so "all 19 repositories were
# unusable" and "the mix is as measured" printed the same thing and exited the
# same way until this line.
[ "$rows" -gt 0 ] || die "have-mix produced NO rows over ${#MIRROR_DIRS[@]} \
mirror(s). Every repository fell through a \`continue\`; nothing was measured."