Explorar o código

Add svn_git_sync CLI with init command

cere hai 1 mes
pai
achega
17f21abdbc
Modificáronse 1 ficheiros con 112 adicións e 0 borrados
  1. 112 0
      svn_interact/svn_git_sync

+ 112 - 0
svn_interact/svn_git_sync

@@ -0,0 +1,112 @@
+#!/usr/bin/env bash
+# svn_git_sync — sync current SVN working copy into a Git mirror
+# Usage:
+#   svn_git_sync init [mirror_name]
+
+set -euo pipefail
+
+show_usage() {
+  echo "Usage: $0 init [mirror_name]" >&2
+  exit 1
+}
+
+subcommand="${1:-}"
+[[ -n "$subcommand" ]] || show_usage
+shift
+
+case "$subcommand" in
+  init)
+    ;;
+  -h|--help|help)
+    show_usage
+    ;;
+  *)
+    echo "Unknown command: $subcommand" >&2
+    show_usage
+    ;;
+esac
+
+SRC_DIR="$(pwd)"
+MIRROR_ROOT="${GIT_SVN_MIRROR_ROOT:-$HOME/git_svn_mirror}"
+
+# Derive a collision-resistant mirror name from the full path (unless overridden).
+raw_name="${1:-$(pwd -P)}"
+BASE_NAME="$(printf "%s" "$raw_name" | sed 's#^[\\/]*##; s#[\\/]#_#g')"
+DEST="${MIRROR_ROOT}/${BASE_NAME}"
+
+echo "Exporting SVN working copy to $DEST (versioned files only)..."
+rm -rf -- "$DEST"
+mkdir -p "$MIRROR_ROOT"
+
+# Optionally compute total items upfront for a rough percentage
+total_items=""
+if total=$(svn list -R . 2>/dev/null | wc -l || true); then
+  total_items="$total"
+fi
+
+start_ts="$(date +%s.%N)"
+elapsed() {
+  local now
+  now="${1:-$(date +%s.%N)}"
+  awk -v s="$start_ts" -v n="$now" 'BEGIN{split(s,sa,".");split(n,na,".");printf "%.1f", (na[1]-sa[1]) + (na[2]-sa[2])/1e9}'
+}
+
+# Run export in background so we can emit our own progress based on files created.
+svn export --quiet . "$DEST" &
+export_pid=$!
+
+last_reported=-1
+while kill -0 "$export_pid" 2>/dev/null; do
+  if [[ -d "$DEST" ]]; then
+    current=$(find "$DEST" -mindepth 1 -print | wc -l)
+  else
+    current=0
+  fi
+
+  if [[ "$current" -ne "$last_reported" ]]; then
+    elapsed_val="$(elapsed)"
+    pct=""
+    if [[ -n "$total_items" && "$total_items" -gt 0 ]]; then
+      pct=$(awk -v c="$current" -v t="$total_items" 'BEGIN{printf(" (%.1f%%)", (c*100)/t)}')
+    fi
+    printf "[%ss] Exported %d items%s\n" "$elapsed_val" "$current" "$pct"
+    last_reported="$current"
+  fi
+
+  sleep 1
+done
+
+wait "$export_pid"
+
+final_count=$(find "$DEST" -mindepth 1 -print | wc -l 2>/dev/null || echo 0)
+printf "[%ss] Exported %d items (done)\n" "$(elapsed)" "$final_count"
+
+cd "$DEST"
+
+echo "[$(elapsed) s] Initializing git repository..."
+GIT_QUIET=1 git init >/dev/null
+git config init.defaultBranch trunk || true
+git config core.fileMode false || true
+git config core.autocrlf true || true
+git config core.safecrlf false || true
+
+echo "[$(elapsed) s] Staging files..."
+git add -A
+
+echo "[$(elapsed) s] Creating initial commit..."
+GIT_QUIET=1 git commit -q -m "Import SVN snapshot" || true
+
+# Reuse the repo for the source working tree by linking .git back to the new repo.
+echo "[$(elapsed) s] Linking git metadata to source working tree..."
+DEST_ABS="$(pwd -P)"
+cd "$SRC_DIR"
+if [[ -e .git || -L .git ]]; then
+  echo "[$(elapsed)s] Replacing existing .git in $SRC_DIR..."
+  rm -rf -- .git
+fi
+printf "gitdir: %s/.git\n" "$DEST_ABS" > .git
+echo "[$(elapsed)s] Linked .git to $DEST_ABS/.git"
+
+# Normalize working tree to match repo filters (e.g., CRLF handling).
+echo "[$(elapsed) s] Syncing working tree to repo content..."
+GIT_QUIET=1 git checkout -q -- .