A Python 3 tool for migrating git repositories to Gitea. This tool can migrate a single repository or recursively search a directory for multiple repositories and migrate them all.
- ✅ Migrate single repositories or multiple repositories recursively
- ✅ Automatically create repositories in Gitea if they don't exist
- ✅ Handle conflicts when repositories already exist in Gitea
- ✅ Support for both SSH and HTTPS remotes
- ✅ Interactive conflict resolution prompts
- ✅ Non-interactive mode for automation
- Python 3.8 or higher
- Git installed on your local machine
- A Gitea account with a valid personal access token
- SSH access to your Gitea server (if using SSH remotes)
# Clone the repository
git clone <repository-url>
cd gitea
# Install in development mode
pip install -e .
# Or install normally
pip install .pip install gitea-migrateThe tool uses environment variables for configuration. Set the following:
export GITEA_HOST="gitea.example.com" # Gitea hostname (required)
export GITEA_USER="your_username" # Gitea username (required)
export GITEA_TOKEN="your_access_token" # Personal access token (required)
export GITEA_USE_SSH="true" # Use SSH URLs (default: true)
export GITEA_SSH_PORT="30009" # Custom SSH port (optional, if not standard port 22)You can also override these values using command-line arguments (see Usage below).
- Log in to your Gitea instance
- Go to Settings → Applications → Generate New Token
- Give it a name (e.g., "migration-tool")
- Select the
reposcope (orwrite:repositorypermission) - Copy the token and set it in
GITEA_TOKEN
Migrate the current directory (single repository):
gitea-migrate .Migrate a specific repository:
gitea-migrate /path/to/repositoryMigrate all repositories in a directory recursively:
gitea-migrate /path/to/parent/dir --recursiveMigrate multiple specific repositories:
gitea-migrate /path/to/repo1 /path/to/repo2 /path/to/repo3Migrate a mix of repositories and directories:
gitea-migrate /path/to/repo1 /path/to/dir1 /path/to/repo2 --recursivepositional arguments:
paths Path(s) to repository/repositories or directory/directories to migrate
optional arguments:
-h, --help Show help message
-r, --recursive Recursively search for repositories in directory
--host HOST Gitea hostname (overrides GITEA_HOST env var)
--username USERNAME Gitea username (overrides GITEA_USER env var)
--token TOKEN Gitea personal access token (overrides GITEA_TOKEN env var)
--no-ssh Use HTTPS instead of SSH
--ssh-port PORT Custom SSH port for git operations (overrides GITEA_SSH_PORT env var)
--non-interactive Non-interactive mode (abort on conflicts)
Migrate current directory with HTTPS:
GITEA_USE_SSH=false gitea-migrate .Migrate with custom SSH port:
GITEA_SSH_PORT=30009 gitea-migrate .
# or
gitea-migrate . --ssh-port 30009Migrate all repos in a directory non-interactively:
gitea-migrate /path/to/repos --recursive --non-interactiveOverride configuration via command line:
gitea-migrate . --host gitea.example.com --username myuser --token mytoken --ssh-port 30009When a repository already exists in Gitea, the tool will prompt you to choose an action:
- Abort (default): Skip this repository and continue with others
- Overwrite remote: Delete the remote repository and recreate it, then push local content
- Overwrite local: Reset the local repository to match the remote (discards local changes)
In non-interactive mode (--non-interactive), the tool will automatically abort on conflicts.
-
Repository Detection: The tool checks if the specified path is a git repository, or searches recursively for git repositories in a directory.
-
Gitea Check: For each repository, it checks if a repository with the same name already exists in Gitea.
-
Repository Creation: If the repository doesn't exist, it creates it in Gitea using the API.
-
Remote Setup: It replaces the
originremote (or creates it if it doesn't exist) with the Gitea repository URL. -
Push: It pushes the default branch (main or master) to Gitea.
-
Conflict Handling: If the repository exists, it prompts for conflict resolution (unless in non-interactive mode).
When migrating multiple repositories, the tool displays a summary:
============================================================
Migration Summary
============================================================
Total repositories: 5
Successful: 4
Failed: 1
============================================================
Make sure you've set the GITEA_HOST environment variable or use the --host argument.
- Verify your Gitea token has the correct permissions
- Check that the repository name is valid (no special characters)
- Ensure you have permission to create repositories
- Verify SSH access to your Gitea server (if using SSH)
- Check that your SSH key is added to Gitea
- For HTTPS, ensure your token has push permissions
If you're trying to migrate a repository that doesn't exist locally, make sure:
- The path is correct
- The directory contains a
.gitfolder - You have read permissions to the directory
MIT License. Use freely and modify as needed.