svn_git_init 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # From inside the SVN subdir you want to extract:
  2. set -euo pipefail
  3. SRC_DIR="$(pwd)"
  4. MIRROR_ROOT="${GIT_SVN_MIRROR_ROOT:-$HOME/git_svn_mirror}"
  5. # Derive a collision-resistant mirror name from the full path (unless overridden).
  6. raw_name="${1:-$(pwd -P)}"
  7. BASE_NAME="$(printf "%s" "$raw_name" | sed 's#^[\\/]*##; s#[\\/]#_#g')"
  8. DEST="${MIRROR_ROOT}/${BASE_NAME}"
  9. echo "Exporting SVN working copy to $DEST (versioned files only)..."
  10. rm -rf -- "$DEST"
  11. mkdir -p "$MIRROR_ROOT"
  12. # Optionally compute total items upfront for a rough percentage
  13. total_items=""
  14. if total=$(svn list -R . 2>/dev/null | wc -l || true); then
  15. total_items="$total"
  16. fi
  17. start_ts="$(date +%s.%N)"
  18. elapsed() {
  19. local now
  20. now="${1:-$(date +%s.%N)}"
  21. 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}'
  22. }
  23. # Run export in background so we can emit our own progress based on files created.
  24. svn export --quiet . "$DEST" &
  25. export_pid=$!
  26. last_reported=-1
  27. while kill -0 "$export_pid" 2>/dev/null; do
  28. if [[ -d "$DEST" ]]; then
  29. current=$(find "$DEST" -mindepth 1 -print | wc -l)
  30. else
  31. current=0
  32. fi
  33. # Only log when count changes to reduce noise.
  34. if [[ "$current" -ne "$last_reported" ]]; then
  35. elapsed_val="$(elapsed)"
  36. pct=""
  37. if [[ -n "$total_items" && "$total_items" -gt 0 ]]; then
  38. pct=$(awk -v c="$current" -v t="$total_items" 'BEGIN{printf(" (%.1f%%)", (c*100)/t)}')
  39. fi
  40. printf "[%ss] Exported %d items%s\n" "$elapsed_val" "$current" "$pct"
  41. last_reported="$current"
  42. fi
  43. sleep 1
  44. done
  45. wait "$export_pid"
  46. final_count=$(find "$DEST" -mindepth 1 -print | wc -l 2>/dev/null || echo 0)
  47. printf "[%ss] Exported %d items (done)\n" "$(elapsed)" "$final_count"
  48. cd "$DEST"
  49. echo "[$(elapsed) s] Initializing git repository..."
  50. GIT_QUIET=1 git init >/dev/null
  51. git config init.defaultBranch trunk || true
  52. git config core.fileMode false || true
  53. git config core.autocrlf true || true
  54. git config core.safecrlf false || true
  55. echo "[$(elapsed) s] Staging files..."
  56. git add -A
  57. echo "[$(elapsed) s] Creating initial commit..."
  58. GIT_QUIET=1 git commit -q -m "Import SVN snapshot" || true
  59. # Reuse the repo for the source working tree by linking .git back to the new repo.
  60. echo "[$(elapsed) s] Linking git metadata to source working tree..."
  61. DEST_ABS="$(pwd -P)"
  62. cd "$SRC_DIR"
  63. if [[ -e .git || -L .git ]]; then
  64. echo "[$(elapsed)s] Replacing existing .git in $SRC_DIR..."
  65. rm -rf -- .git
  66. fi
  67. printf "gitdir: %s/.git\n" "$DEST_ABS" > .git
  68. echo "[$(elapsed)s] Linked .git to $DEST_ABS/.git"
  69. # Normalize working tree to match repo filters (e.g., CRLF handling).
  70. echo "[$(elapsed) s] Syncing working tree to repo content..."
  71. GIT_QUIET=1 git checkout -q -- .