Add script to clean and publish repository history
Create and document a script that removes Replit-specific files and author information from the Git history before pushing to Gitea. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 9417ede9-0069-4ffd-a7b5-6379f4c70b4d Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/kI0sxlu Replit-Helium-Checkpoint-Created: true
This commit is contained in:
Executable
+143
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# publish-to-gitea.sh
|
||||
#
|
||||
# Publishes a SANITIZED copy of this repository to a remote git server (Gitea
|
||||
# by default). Runs entirely in a throw-away temp directory — your real
|
||||
# working tree, Replit workspace, and local git history are never touched.
|
||||
#
|
||||
# What gets stripped from the published mirror:
|
||||
# • Files: .replit, .replitignore, replit.nix, .local/, .agents/,
|
||||
# attached_assets/, every .replit-artifact/ directory,
|
||||
# every artifact.toml inside .replit-artifact/, .gitsafe-backup
|
||||
# • Commit messages: every line starting with "Replit-" is removed.
|
||||
# • Author/committer identity: rewritten to AUTHOR_NAME / AUTHOR_EMAIL
|
||||
# (default: Riyadh <dev@tx.local>; override via env vars).
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/publish-to-gitea.sh # dry run preview
|
||||
# ./scripts/publish-to-gitea.sh --push # actually force-push
|
||||
# AUTHOR_NAME="John" AUTHOR_EMAIL=a@b.c ./scripts/publish-to-gitea.sh --push
|
||||
# GITEA_REMOTE_URL=https://... ./scripts/publish-to-gitea.sh --push
|
||||
# GITEA_BRANCH=main ./scripts/publish-to-gitea.sh --push
|
||||
# -----------------------------------------------------------------------------
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
AUTHOR_NAME="${AUTHOR_NAME:-Riyadh}"
|
||||
AUTHOR_EMAIL="${AUTHOR_EMAIL:-dev@tx.local}"
|
||||
GITEA_REMOTE_URL="${GITEA_REMOTE_URL:-$(git config --get remote.origin.url || echo "")}"
|
||||
GITEA_BRANCH="${GITEA_BRANCH:-main}"
|
||||
|
||||
PUSH=0
|
||||
[[ "${1:-}" == "--push" ]] && PUSH=1
|
||||
|
||||
if [[ -z "$GITEA_REMOTE_URL" ]]; then
|
||||
echo "ERROR: no remote URL. Set GITEA_REMOTE_URL or add a git remote named 'origin'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "================================================================"
|
||||
echo " Publish-to-Gitea — sanitized history mirror"
|
||||
echo "----------------------------------------------------------------"
|
||||
echo " Source repo: $REPO_ROOT"
|
||||
echo " Target remote: $GITEA_REMOTE_URL"
|
||||
echo " Target branch: $GITEA_BRANCH"
|
||||
echo " New author: $AUTHOR_NAME <$AUTHOR_EMAIL>"
|
||||
echo " Mode: $([[ $PUSH == 1 ]] && echo 'PUSH (will force-push)' || echo 'DRY RUN (no push)')"
|
||||
echo "================================================================"
|
||||
echo
|
||||
|
||||
WORK_DIR="$(mktemp -d -t tx-publish-XXXXXX)"
|
||||
trap 'rm -rf "$WORK_DIR"' EXIT
|
||||
|
||||
# -- 1. Acquire git-filter-repo (single-file Python script) -------------------
|
||||
FILTER_REPO="$WORK_DIR/git-filter-repo"
|
||||
if command -v git-filter-repo >/dev/null 2>&1; then
|
||||
FILTER_REPO="$(command -v git-filter-repo)"
|
||||
echo "[1/5] Using system git-filter-repo: $FILTER_REPO"
|
||||
else
|
||||
echo "[1/5] Downloading git-filter-repo into temp dir ..."
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL -o "$FILTER_REPO" \
|
||||
"https://raw.githubusercontent.com/newren/git-filter-repo/v2.47.0/git-filter-repo"
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O "$FILTER_REPO" \
|
||||
"https://raw.githubusercontent.com/newren/git-filter-repo/v2.47.0/git-filter-repo"
|
||||
else
|
||||
echo "ERROR: neither curl nor wget is available." >&2
|
||||
exit 1
|
||||
fi
|
||||
chmod +x "$FILTER_REPO"
|
||||
fi
|
||||
|
||||
# -- 2. Mirror-clone the local repo into the temp dir -------------------------
|
||||
MIRROR="$WORK_DIR/mirror"
|
||||
echo "[2/5] Cloning a fresh mirror of the local repo ..."
|
||||
git clone --no-local --bare "$REPO_ROOT" "$MIRROR" >/dev/null 2>&1 || \
|
||||
git clone --bare "$REPO_ROOT" "$MIRROR" >/dev/null
|
||||
|
||||
# -- 3. Strip Replit-only paths from the entire history -----------------------
|
||||
echo "[3/5] Removing Replit-specific files from every commit ..."
|
||||
"$FILTER_REPO" --force --source "$MIRROR" --target "$MIRROR" \
|
||||
--invert-paths \
|
||||
--path .replit \
|
||||
--path .replitignore \
|
||||
--path replit.nix \
|
||||
--path replit.md \
|
||||
--path .local \
|
||||
--path .agents \
|
||||
--path attached_assets \
|
||||
--path .gitsafe-backup \
|
||||
--path-glob '**/.replit-artifact' \
|
||||
--path-glob '**/.replit-artifact/**'
|
||||
|
||||
# -- 4. Rewrite commit messages and author identity ---------------------------
|
||||
echo "[4/5] Stripping 'Replit-*' trailers and rewriting author identity ..."
|
||||
MSG_CALLBACK='
|
||||
import re
|
||||
text = message.decode("utf-8", errors="replace")
|
||||
# Drop every line that begins with "Replit-"
|
||||
cleaned = "\n".join(
|
||||
line for line in text.splitlines()
|
||||
if not re.match(r"^\s*Replit-", line)
|
||||
)
|
||||
# Collapse trailing whitespace
|
||||
cleaned = re.sub(r"\n{3,}$", "\n\n", cleaned).rstrip() + "\n"
|
||||
return cleaned.encode("utf-8")
|
||||
'
|
||||
|
||||
NAME_BYTES="$(printf '%s' "$AUTHOR_NAME")"
|
||||
EMAIL_BYTES="$(printf '%s' "$AUTHOR_EMAIL")"
|
||||
|
||||
NAME_CALLBACK="return b\"$NAME_BYTES\""
|
||||
EMAIL_CALLBACK="return b\"$EMAIL_BYTES\""
|
||||
|
||||
"$FILTER_REPO" --force --source "$MIRROR" --target "$MIRROR" \
|
||||
--message-callback "$MSG_CALLBACK" \
|
||||
--name-callback "$NAME_CALLBACK" \
|
||||
--email-callback "$EMAIL_CALLBACK"
|
||||
|
||||
# -- 5. Push (or preview) -----------------------------------------------------
|
||||
echo "[5/5] Final state of the sanitized mirror:"
|
||||
echo
|
||||
git --git-dir="$MIRROR" log --pretty=format:'%h %an <%ae> %s' -n 5
|
||||
echo
|
||||
echo
|
||||
echo "Tip: inspect the cleaned tree with:"
|
||||
echo " git --git-dir=$MIRROR log --all --stat | less"
|
||||
echo
|
||||
|
||||
if [[ $PUSH -eq 1 ]]; then
|
||||
echo "Force-pushing branch '$GITEA_BRANCH' to $GITEA_REMOTE_URL ..."
|
||||
git --git-dir="$MIRROR" remote add gitea "$GITEA_REMOTE_URL" 2>/dev/null || \
|
||||
git --git-dir="$MIRROR" remote set-url gitea "$GITEA_REMOTE_URL"
|
||||
git --git-dir="$MIRROR" push --force gitea "HEAD:refs/heads/$GITEA_BRANCH"
|
||||
echo
|
||||
echo "Done. Open $GITEA_REMOTE_URL to verify."
|
||||
else
|
||||
echo "DRY RUN complete — nothing was pushed."
|
||||
echo "Re-run with --push to publish: ./scripts/publish-to-gitea.sh --push"
|
||||
fi
|
||||
Reference in New Issue
Block a user