diff --git a/Docs/setup.md b/Docs/setup.md index 5bbdf72..4dc05d9 100644 --- a/Docs/setup.md +++ b/Docs/setup.md @@ -47,10 +47,13 @@ Anything marked **human step** needs credentials, licence acceptance, or a decis ```bash git clone gig-line cd gig-line -git lfs install # requires git-lfs; otherwise every LFS-tracked add fails +git lfs install # writes filter.lfs.* into git config; required before any content commit git lfs pull +Tools/check-lfs.sh # fails when the lfs filter or the pointer storage is missing ``` +Without `git lfs install`, adding an LFS-matched file does not error — it commits the file as a plain blob. `Tools/check-lfs.sh` is the guard for that. + Sizes: the engine lives outside the repository (pinned install path recorded in `toolchain.md`). The repository holds the Unreal project, Blender sources, geo sources, and tooling. ## Known blockers diff --git a/README.md b/README.md index ee5acbf..6807947 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Pre-production. Workstation setup and repository scaffolding are in progress; no ```bash git lfs install # required: content, images, audio, and geo files are LFS-tracked git lfs pull +Tools/check-lfs.sh # verifies the lfs filter is active and files are stored as pointers ``` The engine is installed outside the repository and pinned in [Docs/toolchain.md](Docs/toolchain.md). The full procedure is in [Docs/setup.md](Docs/setup.md). diff --git a/Tools/README.md b/Tools/README.md index a64d994..1fb9bea 100644 --- a/Tools/README.md +++ b/Tools/README.md @@ -12,6 +12,7 @@ Repeatable import/export and processing helpers. Anything that was done twice by ## Planned helpers +- `check-lfs.sh` — repository guard (exists): fails if `git-lfs` or the `lfs` filter is missing, or if an LFS-tracked file was committed as a plain blob - Blender export preset runner (named presets, metric scale assertion) - Blender→Unreal scale test (export a known-size cube, verify 100× conversion) - OSM extract fetch and manifest writer (records date, bounds, checksum) diff --git a/Tools/check-lfs.sh b/Tools/check-lfs.sh new file mode 100755 index 0000000..d462388 --- /dev/null +++ b/Tools/check-lfs.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Verify Git LFS health for this repository. +# +# Why: .gitattributes routes content through the "lfs" filter, but that filter only +# exists after `git lfs install` writes filter.lfs.* into git config. Without it, +# git does NOT fail on a filtered path — it stores the file as an ordinary blob with +# no warning, and the mistake is only noticed later when the file is huge and +# unversioned in LFS. Run this before committing any binary content. +# +# Usage: Tools/check-lfs.sh (exit 0 = healthy, 1 = problem found) + +set -euo pipefail +cd "$(dirname "$0")/.." + +fail=0 + +lfs_patterns=$(grep -c 'filter=lfs' .gitattributes || true) +if [ "${lfs_patterns:-0}" -eq 0 ]; then + echo "ERROR: .gitattributes has no filter=lfs rules." >&2 + exit 1 +fi + +if ! command -v git-lfs >/dev/null 2>&1; then + echo "ERROR: git-lfs is not installed. LFS-tracked files would be stored as ordinary blobs." >&2 + echo " Install git-lfs, run 'git lfs install', then re-check. See Docs/environment.md." >&2 + fail=1 +fi + +if ! git config --get filter.lfs.process >/dev/null 2>&1; then + echo "ERROR: git config has no filter.lfs.process; the lfs filter is not active." >&2 + echo " Run 'git lfs install' in this repository." >&2 + fail=1 +fi + +pointer_prefix="version https://git-lfs" +checked=0 +while IFS= read -r path; do + [ -n "$path" ] || continue + filter=$(git check-attr filter -- "$path" | awk -F': ' '{print $NF}') + [ "$filter" = "lfs" ] || continue + checked=$((checked + 1)) + blob_head=$(git cat-file -p ":$path" 2>/dev/null | head -c 64 | tr -d '\0' || true) + case "$blob_head" in + "$pointer_prefix"*) ;; + *) + echo "ERROR: '$path' is LFS-tracked by .gitattributes but is stored as a plain blob." >&2 + echo " Fix with: git lfs migrate import --include='$path' (rewrites history)." >&2 + fail=1 + ;; + esac +done < <(git ls-files) + +if [ "$fail" -eq 0 ]; then + echo "LFS check OK: $checked LFS-tracked file(s) stored as pointers." +fi +exit "$fail"