I hope you are never in the situation where you need to use these instructions. It means you are stuck and really don’t want to use SVN. You think there has to be some way I can use a git repo on my project. I was in the same place and wrote these steps down to remind myself how to do it. Things can go very wrong if you don’t follow these step by step.
These instructions are for setting up a two way sync between an existing SVN repository and a GitHub repository. We will be creating an SVN tracking branch (release branch) to push changes into SVN.
Setup
- Create a directory on your computer for the git repository (Ex. ~/git)
- Download svn-migration-scripts.jar to your home directory (Ex. /Users/rwinkle or ~)
- Open your Terminal
- Run this command to verify you have all the appropriate software (git, svn, JRE). NOTE: On Mac you will get an error: “You appear to be running on a case-insensitive file-system. This is unsupported, and can result in data loss.” I ignored this message at my own peril.
java -jar ~/svn-migration-scripts.jar verify
- Change the directory to the folder created in step 1 “cd ~/git”
- Create the author mapping file (authors.txt) from SVN to Git. SVN only has username whereas Git includes username and email. Run the following command:
java -jar ~/svn-migration-scripts.jar authors https://mycompany.com/path/to/svn/repo > authors.txt
- Open authors.txt in a text editor and update the the email address domain from mycompany.com to your particular domain. Here’s what my authors.txt file contained:
fffff = fffff <fffff@aaaaa.com> sssss = sssss <sssss@aaaaa.com> lllll = lllll <lllll@aaaaa.com> scmadmin = scmadmin <scmadm@aaaaa.com> rrrrrr = rrrrrr <rrrrr@aaaaa.com>
- Clone the SVN repository to a local repository using git svn command
git clone https://github.com/olsondigital/repo-1234 cd repo-1234
git svn clone --stdlayout --authors-file=authors.txt https://mycompany.com/path/to/svn/repo repo-1234
- Update your local git user profile so that it is accurate and reflects your GitHub username and email
computername:repo-1234 username$ git config --global --edit # This is Git's per-user configuration file. [user] # Please adapt and uncomment the following lines: name = winklerj email = robb.winkle@gmail.com
-
If you have an empty GitHub repo, create a README.md file with the following and commit it
# My Title This repository is synced with the current SVN repository on a tracking branch svnsync-* where * is the SVN branch. For example svnsync-trunk
git add README.md git commit -m "Initial commit"
- Create a branch to sync with an SVN branch. Use the naming convention svnsync-{svn_branch_name} where svn_branch_name is the branch name in SVN. For the initial sync it should be the latest release branch. You can have multiple git branches that map to the corresponding SVN branch. Below is just one example. (NEVER COMMIT DIRECTLY TO THIS BRANCH OR YOU WILL HAVE CONFLICTS)
git branch --no-track svnsync-DEV_1_0_0_Release git checkout svnsync-DEV_1_10_0_Release
- Initialize and fetch the SVN repository while the new branch is checked out. NOTE: The fetch timed out on me the first time I ran it. I ran it a second time and it completed.
git svn init -s https://mycompany.com/path/to/svn/repo git svn fetch --authors-file=../authors.txt
- Set the author location so you don’t have to enter it each time when fetching
git config svn-remote.svn.authorsfile ../authors.txt
- Hard reset master to the branch specified 2 steps back (DEV_1_0_0_Release). This will now make the code from DEV_1_0_0_Release the current commit on master
git reset --hard remotes/origin/DEV_1_0_0_Release
- Switch to master, merge your SVN tracking branch into master, and push to the GitHub origin master branch
git checkout master git reset --hard svnsync-DEV_1_0_0_Release git push origin master
- You should now see the SVN code in the GitHub repository https://github.com/olsondigital/repo-1234
- Create a develop branch off of master and push to origin
git checkout master git checkout -b develop git push origin develop
- Set develop to the default branch in GitHub
Setup Sync with a New SVN Release Branch
- Perform step 11 in the previous section and create a tracking branch in git
- Pull down SVN changes
git svn fetch
- Perform step 14 and 15 in the previous section and now your master branch should be on the new SVN branch
Syncing from SVN to Git
This is for keeping Git and SVN in sync. All changes from svn are going to be merged locally and staged to be pushed out to the Github repository.
- Update the authors.txt file in the directory created in step 1 of setup (Ex. ~/git). This can be done manually or there are options described here: https://www.atlassian.com/git/tutorials/migrating-synchronize
- Checkout the SVN tracking branch
git checkout svnsync-DEV_1_0_0_Release
- Fetch the latest changes from SVN
git svn rebase
- Switch to master and merge the SVN tracking branch
git checkout master git merge svnsync-DEV_1_0_0_Release
- Push the merged changes to GitHub origin master
git push origin master
Syncing from Git to SVN
Now going the other direction. This is a bit more complicated than pulling in from svn, but make sure you follow all the steps or you will get nasty errors with the sync. Keep in mind the –no-ff on the merge is very important to include. We also want to make sure everything is fully updated from both Github and the svn server before performing the push to svn.
Typically you will be merging a release branch into SVN so I’m using an example release branch
- Checkout the release branch and pull the latest changes from origin
git checkout release-1_0_0 git pull origin release-1_0_0
- Checkout the SVN tracking branch and pull down the latest changes
git checkout svnsync-DEV_1_0_0_Release git svn fetch git svn rebase
- Merge the release into the SVN tracking branch
git merge --no-ff release-1_0_0
- Resolve any conflicts
- Commit the changes locally
git commit -a
- Commit the changes to SVN (NOTE: the order of this and the previous operation are important. If you do them in the wrong order the histories will conflict.)
git svn dcommit
References
Note that these instructions were done on a OS X and branch naming conventions are based on gitflow. The instructions may vary for Windows or different branching models. Also the article mentions Github and git interchangeably. These instructions were done against Github but can be used with any git repository.
Here are the pages I referenced to come up with this method of syncing
- https://www.atlassian.com/git/tutorials/migrating-prepare (Only using the author mapping part. This method will create a one way sync for migration NOT a two way sync)
- https://ben.lobaugh.net/blog/147853/creating-a-two-way-sync-between-a-github-repository-and-subversion
Step 11: git branch –no-track svnsync-DEV_1_0_0_Release
git checkout svnsync-DEV_1_10_0_Release
I think in second line it should be “DEV_1_0_0_Release”
Not works well when you are using LFS…