Created
November 16, 2024 04:44
-
-
Save CJHarmath/ff1af5a66b4582541b4bb997166d998b to your computer and use it in GitHub Desktop.
Revisions
-
CJHarmath created this gist
Nov 16, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,232 @@ #!/bin/bash # SVN to Git Migration Script # ========================== # # This script performs a complete migration from SVN to Git while preserving # history, usernames, branches, and tags. # # Usage: # ./svn-to-git-migrate.sh <SVN_REPO_URL> <GIT_REPO_NAME> # # Examples: # ./svn-to-git-migrate.sh http://svn.example.com/repo my-project # ./svn-to-git-migrate.sh svn://svn.example.com/repo/trunk project-name # ./svn-to-git-migrate.sh file:///path/to/local/svn/repo local-project # # Prerequisites: # - git # - git-svn # - svn # # The script will: # 1. Create an authors mapping file (authors.txt) # 2. Convert SVN history to Git format # 3. Convert SVN branches and tags to Git format # 4. Create a server-ready Git repository # 5. Provide instructions for pushing to GitHub/GitLab # # Important Notes: # - Review authors.txt before proceeding with migration # - Ensure sufficient disk space (at least 2x the SVN repository size) # - Large repositories may take several hours to migrate # - The script assumes standard SVN layout (trunk/branches/tags) # - Have your GitHub/GitLab repository URL ready for the final push # # Output: # - authors.txt: SVN to Git username mapping # - migration.log: Detailed migration log # - temp_migration/: Temporary working directory # - <GIT_REPO_NAME>.git/: Final server-ready Git repository with complete history # # Post-Migration: # The script will provide instructions for pushing to GitHub/GitLab: # 1. Create an empty repository on GitHub/GitLab (DO NOT initialize with README) # 2. Follow the provided commands to push all branches and tags # # Example authors.txt format: # svnuser = Git User <[email protected]> # john = John Doe <[email protected]> # set -e SVN_REPO_URL="" GIT_REPO_NAME="" AUTHORS_FILE="authors.txt" TEMP_DIR="temp_migration" LOG_FILE="migration.log" # Function to show usage show_usage() { grep '^#' "$0" | tail -n +2 | cut -c 3- exit 1 } # Function to log messages log_message() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # Function to verify prerequisites check_prerequisites() { log_message "Checking prerequisites..." # Check for required commands commands=("git" "git-svn" "svn") for cmd in "${commands[@]}"; do if ! command -v "$cmd" >/dev/null 2>&1; then log_message "ERROR: $cmd is not installed" exit 1 fi done } # Function to create authors file create_authors_file() { log_message "Creating authors mapping file..." if [ -f "$AUTHORS_FILE" ]; then log_message "Authors file already exists, skipping..." return } svn log -q "$SVN_REPO_URL" | \ awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2}' | \ sort -u | \ while read -r author; do echo "$author = $author <$author@example.com>" done > "$AUTHORS_FILE" log_message "AUTHORS_FILE created. Please review and update email addresses!" exit 1 } # Function to display post-migration instructions show_post_migration_instructions() { local repo_name="$1" echo echo "=== Post-Migration Instructions ===" echo echo "Your repository is ready! Follow these steps to push to GitHub or GitLab:" echo echo "1. Create a new empty repository on GitHub or GitLab" echo " - DO NOT initialize it with a README, license, or .gitignore" echo " - GitHub: Click 'New' at github.com/yourname?tab=repositories" echo " - GitLab: Click 'New project' at gitlab.com/projects/new" echo echo "2. Push the repository (replace REMOTE_URL with your GitHub/GitLab URL):" echo echo " cd ${repo_name}.git" echo " # For GitHub:" echo " git remote add origin https://github.com/YOUR_USERNAME/${repo_name}.git" echo " # OR for GitLab:" echo " git remote add origin https://gitlab.com/YOUR_USERNAME/${repo_name}.git" echo echo " # Push all branches and tags:" echo " git push origin --all" echo " git push origin --tags" echo echo "3. Verify the migration:" echo " - Check the repository on GitHub/GitLab" echo " - Verify branches and tags are present" echo " - Review commit history" echo " - Clone a fresh copy and check the contents:" echo " git clone https://github.com/YOUR_USERNAME/${repo_name}.git" echo echo "4. Clean up local migration files (optional):" echo " cd .." echo " rm -rf temp_migration" echo " # Keep ${repo_name}.git if you want a local backup" echo echo "Migration log is available in: migration.log" echo } # Function to perform the migration perform_migration() { log_message "Starting migration process..." # Create and enter temporary directory mkdir -p "$TEMP_DIR" cd "$TEMP_DIR" # Initialize git-svn log_message "Initializing git-svn..." git svn init "$SVN_REPO_URL" --no-metadata \ --authors-file="../$AUTHORS_FILE" \ --trunk=trunk \ --tags=tags \ --branches=branches \ --prefix=origin/ # Fetch SVN repository log_message "Fetching SVN repository (this may take a while)..." git svn fetch # Fix tags log_message "Converting SVN tags to Git tags..." git for-each-ref refs/remotes/origin/tags | cut -d / -f 5- | \ while read -r tag; do git tag "$tag" "origin/tags/$tag^" || true git branch -r -d "origin/tags/$tag" || true done # Fix branches log_message "Converting SVN branches to Git branches..." git for-each-ref refs/remotes/origin | cut -d / -f 4- | \ while read -r branch; do if [ "$branch" != "trunk" ]; then git branch "$branch" "refs/remotes/origin/$branch" || true git branch -r -d "origin/$branch" || true fi done # Create master from trunk log_message "Creating master branch from trunk..." git branch -m trunk master # Clean up log_message "Cleaning up..." git gc --aggressive git prune # Create server-ready repository log_message "Creating server-ready repository with complete history..." cd .. git clone --bare "$TEMP_DIR" "$GIT_REPO_NAME.git" # Verify repository integrity cd "$GIT_REPO_NAME.git" log_message "Verifying repository integrity..." git fsck --full log_message "Migration completed successfully! Repository is ready for GitHub/GitLab." # Return to original directory cd .. # Show instructions for pushing to GitHub/GitLab show_post_migration_instructions "$GIT_REPO_NAME" } # Main execution main() { # Show usage if --help flag is passed or no arguments provided if [ "$1" = "--help" ] || [ "$1" = "-h" ] || [ -z "$1" ] || [ -z "$2" ]; then show_usage fi SVN_REPO_URL="$1" GIT_REPO_NAME="$2" # Initialize log file echo "=== Migration Log Started $(date) ===" > "$LOG_FILE" check_prerequisites create_authors_file perform_migration } main "$@"