Skip to content
zit Artifact [2b9b50ee27]
Login

Artifact [2b9b50ee27]

Artifact 2b9b50ee2734d2c07b249879766510392969e30ff06eaa93e15965af388946e0:


#!/bin/sh
# Export the fossil repository to its git mirror and push it.
#
# The mirror exists so GitHub Actions can run the release battery; it is a
# derived view, never a source of truth. Fossil is the repository. Nothing is
# ever committed on the git side — a push is always a replay of fossil history,
# which is why the push is `--mirror`.
#
# The mirror repo is PRIVATE and stays private. Publishing zit is a separate,
# deliberate decision; do not change repository visibility from this script or
# from any automation that calls it.
#
# `fossil git export` keeps its own per-checkout state (mirror directory and
# autopush URL, set up once with `fossil git export <dir> --autopush <url>`).
# Incremental export skips tag-only changes unless forced, so every run uses
# `--force`; this is cheap when there are no check-ins and ensures a release
# tag reaches GitHub without requiring an unrelated source commit. The state is
# machine-local and therefore invisible to anyone cloning this repository,
# which is the reason this script exists: it makes the export reproducible and
# documents the one supported way to run it.
#
# Usage:  scripts/mirror-export.sh
# Exit:   0 on a completed export+push, non-zero otherwise.

set -eu

MIRROR_URL="https://github.com/danmestas/zit"

# Run from the repository root regardless of where the caller invoked this.
cd "$(dirname "$0")/.."

if ! command -v fossil >/dev/null 2>&1; then
    echo "mirror-export: fossil is not on PATH" >&2
    exit 1
fi

# `fossil git export` with no arguments resumes the configured mirror. If it has
# never been configured in this checkout, say so with the fix rather than
# failing obscurely three lines deeper.
if ! fossil git status >/dev/null 2>&1; then
    echo "mirror-export: no git mirror configured in this checkout." >&2
    echo "  fossil git export /path/to/zit-mirror --autopush ${MIRROR_URL}" >&2
    exit 1
fi

echo "mirror-export: exporting fossil history to the git mirror"
fossil git export --force

# Autopush is best-effort inside fossil: a transient network failure leaves the
# local mirror ahead of the remote while `fossil git status` still reports
# "up-to-date", because that status describes the export, not the push. So the
# push is re-driven explicitly and its exit status is the script's.
MIRROR_DIR=$(fossil git status | awk '/^Git mirror:/ { print $3 }')
if [ -z "${MIRROR_DIR}" ] || [ ! -d "${MIRROR_DIR}" ]; then
    echo "mirror-export: could not resolve the mirror directory from 'fossil git status'" >&2
    exit 1
fi

# A closed fossil branch carries no active work, so its ref has no reader on
# the mirror side either — GitHub Actions runs on main. Drop closed refs from
# the local mirror here; the `--mirror` push below propagates the deletions,
# and because this runs on every export, a branch closed in fossil disappears
# from GitHub on the next run without anyone touching the mirror by hand.
fossil branch list --closed | sed 's/^[ *]*//' | while IFS= read -r closed_name; do
    [ -n "${closed_name}" ] || continue
    git -C "${MIRROR_DIR}" update-ref -d "refs/heads/${closed_name}" 2>/dev/null || true
done

echo "mirror-export: pushing ${MIRROR_DIR} -> ${MIRROR_URL}"
cd "${MIRROR_DIR}"

# The mirror carries no LFS objects; the lock-verify probe only adds a failure
# mode on a repo that has never used LFS.
git config "lfs.${MIRROR_URL}.git/info/lfs.locksverify" false 2>/dev/null || true

git push --mirror "${MIRROR_URL}"

echo "mirror-export: done"