chore: clean .gitignore cache
This commit is contained in:
@@ -1 +0,0 @@
|
||||
Triggered re-run by automation on 2025-12-09T14:32:02Z
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0
|
||||
|
||||
Lists branches and tags, saves a tag reference tarball to data/backups.
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
|
||||
usage; exit 0
|
||||
fi
|
||||
|
||||
logdir="data/backups"
|
||||
mkdir -p "$logdir"
|
||||
ts=$(date +"%Y%m%d-%H%M%S")
|
||||
tags_tar="$logdir/tags-$ts.tar.gz"
|
||||
|
||||
echo "Branches:"
|
||||
git branch -a || true
|
||||
|
||||
echo "Tags:"
|
||||
git tag -l || true
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
git show-ref --tags > "$tmpdir/tags-show-ref.txt" || true
|
||||
tar -C "$tmpdir" -czf "$tags_tar" . || { echo "Warning: failed to create tag tarball" >&2; rm -rf "$tmpdir"; exit 1; }
|
||||
rm -rf "$tmpdir"
|
||||
echo "Created tags tarball: $tags_tar"
|
||||
|
||||
echo "Attempting to push tags to origin under refs/backups/tags/*"
|
||||
for t in $(git tag --list); do
|
||||
if ! git push origin "refs/tags/$t:refs/backups/tags/$t" >/dev/null 2>&1; then
|
||||
echo "Warning: pushing tag $t to refs/backups/tags/$t failed" >&2
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Done."
|
||||
exit 0
|
||||
@@ -1,231 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Bash script to safely preview and optionally run a git history rewrite
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# Default values
|
||||
DRY_RUN=1
|
||||
FORCE=0
|
||||
NON_INTERACTIVE=0
|
||||
PATHS="backend/codeql-db,codeql-db,codeql-db-js,codeql-db-go"
|
||||
STRIP_SIZE=50
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 [--dry-run] [--force] [--paths 'p1,p2'] [--strip-size N]
|
||||
|
||||
Options:
|
||||
--dry-run (default) Show what would be removed; no changes are made.
|
||||
--force Run rewrite (destructive). Requires manual confirmation.
|
||||
--paths Comma-separated list of paths to remove from history.
|
||||
--strip-size Strip blobs larger than N MB in the history.
|
||||
--help Show this help and exit.
|
||||
|
||||
Example:
|
||||
$0 --dry-run --paths 'backend/codeql-db,codeql-db' --strip-size 50
|
||||
$0 --force --paths 'backend/codeql-db' --strip-size 100
|
||||
EOF
|
||||
}
|
||||
|
||||
check_requirements() {
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
echo "git is required but not found. Aborting." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v git-filter-repo >/dev/null 2>&1; then
|
||||
echo "git-filter-repo not found. Please install it:"
|
||||
echo " - Debian/Ubuntu: sudo apt install git-filter-repo"
|
||||
echo " - Mac (Homebrew): brew install git-filter-repo"
|
||||
echo " - Python pip: pip install git-filter-repo"
|
||||
echo "Or see https://github.com/newren/git-filter-repo for details."
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
timestamp() {
|
||||
# POSIX-friendly timestamp
|
||||
date +"%Y%m%d-%H%M%S"
|
||||
}
|
||||
|
||||
logdir="data/backups"
|
||||
mkdir -p "$logdir"
|
||||
logfile="$logdir/history_cleanup-$(timestamp).log"
|
||||
|
||||
echo "Starting history cleanup tool at $(date)" | tee "$logfile"
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=1; shift;;
|
||||
--force)
|
||||
DRY_RUN=0; FORCE=1; shift;;
|
||||
--non-interactive)
|
||||
NON_INTERACTIVE=1; shift;;
|
||||
--paths)
|
||||
PATHS="$2"; shift 2;;
|
||||
--strip-size)
|
||||
STRIP_SIZE="$2"; shift 2;;
|
||||
--help)
|
||||
usage; exit 0;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2; usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
check_requirements
|
||||
|
||||
# Reject shallow clones
|
||||
if git rev-parse --is-shallow-repository >/dev/null 2>&1 && [ "$(git rev-parse --is-shallow-repository 2>/dev/null)" = "true" ]; then
|
||||
echo "Shallow clone detected; fetch full history before rewriting history. Run: git fetch --unshallow or actions/checkout: fetch-depth: 0 in CI." | tee -a "$logfile"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "(detached)")
|
||||
if [ "$current_branch" = "main" ] || [ "$current_branch" = "master" ]; then
|
||||
if [ "$FORCE" -ne 1 ]; then
|
||||
echo "Refusing to run on main/master branch. Switch to a feature branch and retry. To force running on main/master set FORCE=1" | tee -a "$logfile"
|
||||
exit 3
|
||||
fi
|
||||
echo "WARNING: Running on main/master as FORCE=1 is set." | tee -a "$logfile"
|
||||
fi
|
||||
|
||||
backup_branch="backup/history-$(timestamp)"
|
||||
echo "Creating backup branch: $backup_branch" | tee -a "$logfile"
|
||||
git branch -f "$backup_branch" || true
|
||||
if ! git push origin "$backup_branch" >/dev/null 2>&1; then
|
||||
echo "Error: Failed to push backup branch $backup_branch to origin. Aborting." | tee -a "$logfile"
|
||||
exit 5
|
||||
fi
|
||||
|
||||
IFS=','; set -f
|
||||
paths_list=""
|
||||
for p in $PATHS; do
|
||||
# Expand shell expansion
|
||||
paths_list="$paths_list $p"
|
||||
done
|
||||
set +f; unset IFS
|
||||
|
||||
echo "Paths targeted: $paths_list" | tee -a "$logfile"
|
||||
echo "Strip blobs bigger than: ${STRIP_SIZE}M" | tee -a "$logfile"
|
||||
|
||||
# Ensure STRIP_SIZE is numeric
|
||||
if ! printf '%s\n' "$STRIP_SIZE" | grep -Eq '^[0-9]+$'; then
|
||||
echo "Error: --strip-size must be a numeric value (MB). Got: $STRIP_SIZE" | tee -a "$logfile"
|
||||
exit 6
|
||||
fi
|
||||
|
||||
preview_removals() {
|
||||
echo "=== Preview: commits & blobs touching specified paths ===" | tee -a "$logfile"
|
||||
# List commits that touch the paths
|
||||
for p in $paths_list; do
|
||||
echo "--- Path: $p" | tee -a "$logfile"
|
||||
git rev-list --all -- "$p" | head -n 20 | tee -a "$logfile"
|
||||
done
|
||||
echo "=== End of commit preview ===" | tee -a "$logfile"
|
||||
|
||||
echo "=== Preview: objects in paths ===" | tee -a "$logfile"
|
||||
# List objects for the given paths
|
||||
for p in $paths_list; do
|
||||
echo "Path: $p" | tee -a "$logfile"
|
||||
git rev-list --objects --all -- "$p" | while read -r line; do
|
||||
oid=$(printf '%s' "$line" | awk '{print $1}')
|
||||
label=$(printf '%s' "$line" | awk '{print $2}')
|
||||
type=$(git cat-file -t "$oid" 2>/dev/null || true)
|
||||
if [ "$type" = "blob" ]; then
|
||||
echo "$oid $label"
|
||||
else
|
||||
echo "[${type^^}] $oid $label"
|
||||
fi
|
||||
done | head -n 50 | tee -a "$logfile"
|
||||
done
|
||||
|
||||
echo "=== Example large objects (candidate for --strip-size) ===" | tee -a "$logfile"
|
||||
# List object sizes and show top N
|
||||
git rev-list --objects --all | awk '{print $1}' | while read -r oid; do
|
||||
size=$(git cat-file -s "$oid" 2>/dev/null || true)
|
||||
if [ -n "$size" ] && [ "$size" -ge $((STRIP_SIZE * 1024 * 1024)) ]; then
|
||||
echo "$oid size=$size"
|
||||
fi
|
||||
done | head -n 30 | tee -a "$logfile"
|
||||
}
|
||||
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo "Running dry-run mode. No destructive operations will be performed." | tee -a "$logfile"
|
||||
preview_removals
|
||||
echo "Dry-run complete. See $logfile for details." | tee -a "$logfile"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$FORCE" -ne 1 ]; then
|
||||
echo "To run a destructive rewrite, pass --force. Aborting." | tee -a "$logfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "FORCE mode enabled - performing rewrite. This is destructive and will rewrite history." | tee -a "$logfile"
|
||||
|
||||
if [ "$NON_INTERACTIVE" -eq 0 ]; then
|
||||
echo "Confirm operation: Type 'I UNDERSTAND' to proceed:" | tee -a "$logfile"
|
||||
read -r confirmation
|
||||
if [ "$confirmation" != "I UNDERSTAND" ]; then
|
||||
echo "Confirmation not provided. Aborting." | tee -a "$logfile"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ "$FORCE" -ne 1 ]; then
|
||||
echo "Error: Non-interactive mode requires FORCE=1 to proceed. Aborting." | tee -a "$logfile"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
## No additional branch check here; earlier check prevents running on main/master unless FORCE=1
|
||||
|
||||
# Build git-filter-repo arguments
|
||||
paths_args=""
|
||||
IFS=' '
|
||||
for p in $paths_list; do
|
||||
paths_args="$paths_args --paths $p"
|
||||
done
|
||||
set +f
|
||||
|
||||
echo "Running git filter-repo with: $paths_args --invert-paths --strip-blobs-bigger-than ${STRIP_SIZE}M" | tee -a "$logfile"
|
||||
|
||||
echo "Performing a local dry-run against a local clone before actual rewrite is strongly recommended." | tee -a "$logfile"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
set -- $paths_args
|
||||
git filter-repo --invert-paths "$@" --strip-blobs-bigger-than "${STRIP_SIZE}"M | tee -a "$logfile"
|
||||
|
||||
echo "Rewrite complete. Running post-rewrite checks..." | tee -a "$logfile"
|
||||
git count-objects -vH | tee -a "$logfile"
|
||||
git fsck --full | tee -a "$logfile"
|
||||
git gc --aggressive --prune=now | tee -a "$logfile"
|
||||
|
||||
# Backup tags list as a tarball and try to push tags to a backup namespace
|
||||
tags_tar="$logdir/tags-$(timestamp).tar.gz"
|
||||
tmp_tags_dir=$(mktemp -d)
|
||||
git for-each-ref --format='%(refname:short) %(objectname)' refs/tags > "$tmp_tags_dir/tags.txt"
|
||||
tar -C "$tmp_tags_dir" -czf "$tags_tar" . || echo "Warning: failed to create tag tarball" | tee -a "$logfile"
|
||||
rm -rf "$tmp_tags_dir"
|
||||
echo "Created tags tarball: $tags_tar" | tee -a "$logfile"
|
||||
|
||||
echo "Attempting to push tags to origin under refs/backups/tags/*" | tee -a "$logfile"
|
||||
for t in $(git tag --list); do
|
||||
if ! git push origin "refs/tags/$t:refs/backups/tags/$t" >/dev/null 2>&1; then
|
||||
echo "Warning: pushing tag $t to refs/backups/tags/$t failed" | tee -a "$logfile"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "REWRITE DONE. Next steps (manual):" | tee -a "$logfile"
|
||||
cat <<EOF | tee -a "$logfile"
|
||||
- Verify repo locally and run CI checks: ./.venv/bin/pre-commit run --all-files
|
||||
- Run backend tests: cd backend && go test ./...
|
||||
- Run frontend build: cd frontend && npm run build
|
||||
- Coordinate with maintainers prior to force-push. To finalize:
|
||||
git push --all --force
|
||||
git push --tags --force
|
||||
- If anything goes wrong, restore from your backup branch: git checkout -b restore/$(date +"%Y%m%d-%H%M%S") $backup_branch
|
||||
EOF
|
||||
|
||||
echo "Log saved to $logfile"
|
||||
|
||||
exit 0
|
||||
@@ -1,122 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Preview the list of commits and objects that would be removed by clean_history.sh
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
PATHS="backend/codeql-db,codeql-db,codeql-db-js,codeql-db-go"
|
||||
STRIP_SIZE=50
|
||||
FORMAT="text"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 [--paths 'p1,p2'] [--strip-size N]
|
||||
|
||||
Prints commits and objects that would be removed by a history rewrite.
|
||||
EOF
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--paths)
|
||||
PATHS="$2"; shift 2;;
|
||||
--strip-size)
|
||||
STRIP_SIZE="$2"; shift 2;;
|
||||
--format)
|
||||
FORMAT="$2"; shift 2;;
|
||||
--help)
|
||||
usage; exit 0;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2; usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
IFS=','; set -f
|
||||
paths_list=""
|
||||
for p in $PATHS; do
|
||||
paths_list="$paths_list $p"
|
||||
done
|
||||
set +f; unset IFS
|
||||
|
||||
echo "Paths: $paths_list"
|
||||
echo "Strip blobs larger than: ${STRIP_SIZE}M"
|
||||
|
||||
# Reject shallow clones
|
||||
if git rev-parse --is-shallow-repository >/dev/null 2>&1 && [ "$(git rev-parse --is-shallow-repository 2>/dev/null)" = "true" ]; then
|
||||
echo "Error: Shallow clone detected. Please run 'git fetch --unshallow' or use actions/checkout fetch-depth: 0 to fetch full history." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Ensure STRIP_SIZE is numeric
|
||||
if ! printf '%s\n' "$STRIP_SIZE" | grep -Eq '^[0-9]+$'; then
|
||||
echo "Error: --strip-size must be a numeric value (MB). Got: $STRIP_SIZE" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
printf '{"paths":['
|
||||
first_path=true
|
||||
for p in $paths_list; do
|
||||
if [ "$first_path" = true ]; then
|
||||
printf '"%s"' "$p"
|
||||
first_path=false
|
||||
else
|
||||
printf ',"%s"' "$p"
|
||||
fi
|
||||
done
|
||||
printf '],"strip_size":%s,"commits":{' "$STRIP_SIZE"
|
||||
fi
|
||||
echo "--- Commits touching specified paths ---"
|
||||
for p in $paths_list; do
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
printf '"%s":[' "$p"
|
||||
git rev-list --all -- "$p" | head -n 50 | awk '{printf "%s\n", $0}' | sed -n '1,50p' | awk '{printf "%s,", $0}' | sed 's/,$//'
|
||||
printf '],'
|
||||
else
|
||||
echo "Path: $p"
|
||||
git rev-list --all -- "$p" | nl -ba | sed -n '1,50p'
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
printf '},"objects":['
|
||||
for p in $paths_list; do
|
||||
git rev-list --objects --all -- "$p" | head -n 100 | awk '{printf "\"%s\",", $1}' | sed 's/,$//'
|
||||
done
|
||||
printf '],'
|
||||
else
|
||||
echo "--- Objects in paths (blob objects shown; tags highlighted) ---"
|
||||
for p in $paths_list; do
|
||||
echo "Path: $p"
|
||||
git rev-list --objects --all -- "$p" | while read -r line; do
|
||||
oid=$(printf '%s' "$line" | awk '{print $1}')
|
||||
label=$(printf '%s' "$line" | awk '{print $2}')
|
||||
type=$(git cat-file -t "$oid" 2>/dev/null || true)
|
||||
if [ "$type" = "blob" ]; then
|
||||
echo "$oid $label"
|
||||
else
|
||||
echo "[${type^^}] $oid $label"
|
||||
fi
|
||||
done | nl -ba | sed -n '1,100p'
|
||||
done
|
||||
fi
|
||||
|
||||
echo "--- Example large objects larger than ${STRIP_SIZE}M ---"
|
||||
git rev-list --objects --all | awk '{print $1}' | while read -r oid; do
|
||||
size=$(git cat-file -s "$oid" 2>/dev/null || true)
|
||||
if [ -n "$size" ] && [ "$size" -ge $((STRIP_SIZE * 1024 * 1024)) ]; then
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
printf '{"oid":"%s","size":%s},' "$oid" "$size"
|
||||
else
|
||||
echo "$oid size=$size"
|
||||
fi
|
||||
fi
|
||||
done | nl -ba | sed -n '1,50p'
|
||||
|
||||
if [ "$FORMAT" = "json" ]; then
|
||||
printf '],"large_objects":[]}'
|
||||
echo
|
||||
else
|
||||
echo "Preview complete. Use clean_history.sh --dry-run to get a log file."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup() {
|
||||
TMPREPO=$(mktemp -d)
|
||||
cd "$TMPREPO"
|
||||
git init -q
|
||||
# Set local git identity for test commits
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Test Runner"
|
||||
# create a directory that matches the paths to be pruned
|
||||
mkdir -p backend/codeql-db
|
||||
# add a large fake blob file
|
||||
dd if=/dev/zero of=backend/codeql-db/largefile.bin bs=1M count=2 >/dev/null 2>&1 || true
|
||||
git add -A && git commit -m 'add large blob' -q
|
||||
git checkout -b feature/test
|
||||
# Create a local bare repo to act as origin and allow git push
|
||||
TMPORIGIN=$(mktemp -d)
|
||||
git init --bare "$TMPORIGIN" >/dev/null
|
||||
git remote add origin "$TMPORIGIN"
|
||||
git push -u origin feature/test >/dev/null 2>&1 || true
|
||||
# Add a stub git-filter-repo to PATH to satisfy requirements without installing
|
||||
STUBBIN=$(mktemp -d)
|
||||
cat > "$STUBBIN/git-filter-repo" <<'SH'
|
||||
#!/usr/bin/env bash
|
||||
echo "stub git-filter-repo called: $@"
|
||||
exit 0
|
||||
SH
|
||||
chmod +x "$STUBBIN/git-filter-repo"
|
||||
PATH="$STUBBIN:$PATH"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$TMPREPO"
|
||||
}
|
||||
|
||||
REPO_ROOT=$(cd "$BATS_TEST_DIRNAME/../../../" && pwd)
|
||||
SCRIPT="$REPO_ROOT/scripts/history-rewrite/clean_history.sh"
|
||||
|
||||
@test "clean_history dry-run prints expected log and exits 0" {
|
||||
run bash "$SCRIPT" --dry-run --paths 'backend/codeql-db' --strip-size 1
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Dry-run complete"* ]]
|
||||
}
|
||||
|
||||
@test "preview_removals shows commits for the path" {
|
||||
run bash "$REPO_ROOT/scripts/history-rewrite/preview_removals.sh" --paths 'backend/codeql-db' --strip-size 1
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Path: backend/codeql-db"* ]]
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup() {
|
||||
TMPREPO=$(mktemp -d)
|
||||
cd "$TMPREPO"
|
||||
git init -q
|
||||
# local git identity
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Test Runner"
|
||||
# create a directory that matches the paths to be pruned
|
||||
mkdir -p backend/codeql-db
|
||||
echo "dummy" > backend/codeql-db/keep.txt
|
||||
git add -A && git commit -m 'add test files' -q
|
||||
git checkout -b feature/test
|
||||
# Create a local bare repo to act as origin and allow git push
|
||||
TMPORIGIN=$(mktemp -d)
|
||||
git init --bare "$TMPORIGIN" >/dev/null
|
||||
git remote add origin "$TMPORIGIN"
|
||||
git push -u origin feature/test >/dev/null 2>&1 || true
|
||||
# Add a stub git-filter-repo to PATH to satisfy requirements without installing
|
||||
STUBBIN=$(mktemp -d)
|
||||
cat > "$STUBBIN/git-filter-repo" <<'SH'
|
||||
#!/usr/bin/env bash
|
||||
echo "stub git-filter-repo called: $@"
|
||||
exit 0
|
||||
SH
|
||||
chmod +x "$STUBBIN/git-filter-repo"
|
||||
PATH="$STUBBIN:$PATH"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$TMPREPO"
|
||||
}
|
||||
|
||||
REPO_ROOT=$(cd "$BATS_TEST_DIRNAME/../../../" && pwd)
|
||||
SCRIPT="$REPO_ROOT/scripts/history-rewrite/clean_history.sh"
|
||||
|
||||
@test "clean_history non-interactive + force runs without prompting and invokes git-filter-repo" {
|
||||
run bash "$SCRIPT" --force --non-interactive --paths 'backend/codeql-db' --strip-size 1
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"stub git-filter-repo called"* ]]
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup() {
|
||||
TMPREPO=$(mktemp -d)
|
||||
cd "$TMPREPO"
|
||||
git init -q
|
||||
# Set local git identity so commits succeed in CI
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Test Runner"
|
||||
# Create a commit in an unrelated path
|
||||
mkdir -p other/dir
|
||||
echo hello > other/dir/file.txt
|
||||
git add other/dir/file.txt && git commit -m 'add unrelated file' -q
|
||||
# Create an annotated tag
|
||||
git tag -a v0.3.0 -m "annotated tag v0.3.0"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$TMPREPO"
|
||||
}
|
||||
|
||||
REPO_ROOT=$(cd "$BATS_TEST_DIRNAME/../../../" && pwd)
|
||||
SCRIPT="$REPO_ROOT/scripts/ci/dry_run_history_rewrite.sh"
|
||||
|
||||
@test "dry_run script ignores tag-only objects and passes" {
|
||||
run bash "$SCRIPT" --paths 'backend/codeql-db' --strip-size 50
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"DRY-RUN OK"* ]]
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup() {
|
||||
# Create an isolated working repo
|
||||
TMPREPO=$(mktemp -d)
|
||||
cd "$TMPREPO"
|
||||
git init -q
|
||||
# Set local git identity for test commits
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Test Runner"
|
||||
echo 'initial' > README.md
|
||||
git add README.md && git commit -m 'init' -q
|
||||
# Make a minimal .venv pre-commit stub
|
||||
mkdir -p .venv/bin
|
||||
cat > .venv/bin/pre-commit <<'SH'
|
||||
#!/usr/bin/env sh
|
||||
exit 0
|
||||
SH
|
||||
chmod +x .venv/bin/pre-commit
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$TMPREPO"
|
||||
}
|
||||
|
||||
## Prefer deriving the script location from the test directory rather than hard-coding
|
||||
## repository root paths such as /projects/Charon. This is more portable across
|
||||
## environments and CI runners (e.g., forks where the repo path is different).
|
||||
SCRIPT_DIR=$(cd "$BATS_TEST_DIRNAME/.." && pwd -P)
|
||||
SCRIPT="$SCRIPT_DIR/validate_after_rewrite.sh"
|
||||
|
||||
@test "validate_after_rewrite fails when backup branch is missing" {
|
||||
run bash "$SCRIPT"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"backup branch not provided"* ]]
|
||||
}
|
||||
|
||||
@test "validate_after_rewrite passes with backup branch argument" {
|
||||
run bash "$SCRIPT" --backup-branch backup/main
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
TMPREMOTE=$(mktemp -d)
|
||||
git init --bare "$TMPREMOTE/remote.git"
|
||||
TMPCLONE=$(mktemp -d)
|
||||
cd "$TMPCLONE"
|
||||
git clone "$TMPREMOTE/remote.git" .
|
||||
# create a commit
|
||||
mkdir -p backend/codeql-db
|
||||
echo 'dummy' > backend/codeql-db/foo.txt
|
||||
git add -A
|
||||
git commit -m "Add dummy file" -q
|
||||
git checkout -b feature/test
|
||||
# set up stub git-filter-repo in PATH
|
||||
## Resolve the repo root based on the script file location (Bash-safe)
|
||||
# Use ${BASH_SOURCE[0]} instead of $0 to correctly resolve the script path even
|
||||
# when invoked from different PWDs or via sourced contexts.
|
||||
REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../" && pwd -P)
|
||||
TMPBIN=$(mktemp -d)
|
||||
cat > "$TMPBIN/git-filter-repo" <<'SH'
|
||||
#!/usr/bin/env sh
|
||||
# Minimal stub to simulate git-filter-repo
|
||||
while [ $# -gt 0 ]; do
|
||||
shift
|
||||
done
|
||||
exit 0
|
||||
SH
|
||||
chmod +x "$TMPBIN/git-filter-repo"
|
||||
export PATH="$TMPBIN:$PATH"
|
||||
# run clean_history.sh with dry-run
|
||||
# NOTE: Avoid hard-coded repo paths like /projects/Charon/
|
||||
# Use the dynamically-derived REPO_ROOT (above) or a relative path from this script
|
||||
# so this helper script runs correctly on other machines/CI environments.
|
||||
# Examples:
|
||||
# "$REPO_ROOT/scripts/history-rewrite/clean_history.sh" --dry-run ...
|
||||
# "$(dirname "$0")/clean_history.sh" --dry-run ...
|
||||
"$REPO_ROOT/scripts/history-rewrite/clean_history.sh" --dry-run --paths 'backend/codeql-db' --strip-size 1
|
||||
# run clean_history.sh with force should attempt to push branch then succeed (requires that remote exists)
|
||||
"$REPO_ROOT/scripts/history-rewrite/clean_history.sh" --force --paths 'backend/codeql-db' --strip-size 1 <<'IN'
|
||||
I UNDERSTAND
|
||||
IN
|
||||
|
||||
# test non-interactive with force
|
||||
"$REPO_ROOT/scripts/history-rewrite/clean_history.sh" --force --non-interactive --paths 'backend/codeql-db' --strip-size 1
|
||||
|
||||
# cleanup
|
||||
rm -rf "$TMPREMOTE" "$TMPCLONE" "$TMPBIN"
|
||||
echo 'done'
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
TMP=$(mktemp -d)
|
||||
REPO_ROOT=$(cd "$(dirname "$0")/../../" && pwd)
|
||||
cd "$TMP"
|
||||
git init -q
|
||||
echo hi > README.md
|
||||
git add README.md
|
||||
git commit -q -m init
|
||||
mkdir -p .venv/bin
|
||||
cat > .venv/bin/pre-commit <<'PRE'
|
||||
#!/usr/bin/env sh
|
||||
exit 0
|
||||
PRE
|
||||
chmod +x .venv/bin/pre-commit
|
||||
echo "temp repo: $TMP"
|
||||
# Use the configured REPO_ROOT rather than hardcoding /projects/Charon.
|
||||
# Note: avoid a leading slash before "$REPO_ROOT" which would make the path invalid
|
||||
# on different hosts; use "$REPO_ROOT/scripts/..." directly.
|
||||
"$REPO_ROOT/scripts/history-rewrite/validate_after_rewrite.sh" || echo "first run rc $?"
|
||||
"$REPO_ROOT/scripts/history-rewrite/validate_after_rewrite.sh" --backup-branch backup/main || echo "second run rc $?"
|
||||
echo exit status $?
|
||||
@@ -1,97 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Verify repository health after a destructive history-rewrite
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 [--backup-branch BRANCH]
|
||||
|
||||
Performs: sanity checks after a destructive history-rewrite.
|
||||
Options:
|
||||
--backup-branch BRANCH Name of the backup branch created prior to rewrite.
|
||||
-h, --help Show this help and exit.
|
||||
EOF
|
||||
}
|
||||
|
||||
backup_branch=""
|
||||
|
||||
while [ "${#}" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--backup-branch)
|
||||
shift
|
||||
if [ -z "${1:-}" ]; then
|
||||
echo "Error: --backup-branch requires an argument" >&2
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
backup_branch="$1"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage; exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $1" >&2; usage; exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Fallback to env variable
|
||||
if [ -z "${backup_branch}" ]; then
|
||||
if [ -n "${BACKUP_BRANCH:-}" ]; then
|
||||
backup_branch="$BACKUP_BRANCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If still not set, try to infer from data/backups logs
|
||||
if [ -z "${backup_branch}" ] && [ -d data/backups ]; then
|
||||
# Look for common patterns referencing a backup branch name
|
||||
candidate=$(grep -E "backup[-_]branch" data/backups/* 2>/dev/null | sed -E 's/.*[:=]//; s/^[[:space:]]+//; s/[[:space:]\047"\"]+$//' | head -n1 || true)
|
||||
if [ -n "${candidate}" ]; then
|
||||
backup_branch="$candidate"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${backup_branch}" ]; then
|
||||
echo "Error: backup branch not provided. Use --backup-branch or set BACKUP_BRANCH environment variable, or ensure data/backups/ contains a log referencing the branch." >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# No positional args required; any unknown options are handled during parsing
|
||||
|
||||
echo "Running git maintenance: git count-objects -vH"
|
||||
git count-objects -vH || true
|
||||
|
||||
echo "Running git fsck --full"
|
||||
git fsck --full || true
|
||||
|
||||
pre_commit_executable=""
|
||||
if [ -x "./.venv/bin/pre-commit" ]; then
|
||||
pre_commit_executable="./.venv/bin/pre-commit"
|
||||
elif command -v pre-commit >/dev/null 2>&1; then
|
||||
pre_commit_executable=$(command -v pre-commit)
|
||||
fi
|
||||
|
||||
if [ -z "${pre_commit_executable}" ]; then
|
||||
echo "Error: pre-commit not found. Install pre-commit in a virtualenv at ./.venv/bin/pre-commit or ensure it's in PATH." >&2
|
||||
exit 4
|
||||
fi
|
||||
|
||||
echo "Running pre-commit checks (${pre_commit_executable})"
|
||||
${pre_commit_executable} run --all-files || { echo "pre-commit checks reported issues" >&2; exit 5; }
|
||||
|
||||
if [ -d backend ]; then
|
||||
echo "Running backend go tests"
|
||||
(cd backend && go test ./... -v) || echo "backend tests failed"
|
||||
fi
|
||||
|
||||
if [ -d frontend ]; then
|
||||
echo "Running frontend build"
|
||||
(cd frontend && npm run build) || echo "frontend build failed"
|
||||
fi
|
||||
|
||||
echo "Validation complete. Inspect output for errors. If something is wrong, restore:
|
||||
git checkout -b restore/$(date +"%Y%m%d-%H%M%S") ${backup_branch:-}"
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user