software:svnsyncgit
Differences
This shows you the differences between two versions of the page.
| — | software:svnsyncgit [2021/05/14 22:23] (current) – created - external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Creating a two-way SVN <> GitHub sync ====== | ||
| + | ===== Intro ===== | ||
| + | |||
| + | When migrating [[pdclib: | ||
| + | |||
| + | As Erin Shepherd pointed out in one of the many emails we exchanged, Git seems to have pretty much won the Version Control battle. I still much prefer Subversion, but I realize that being present on GitHub would certainly not hurt the project. | ||
| + | |||
| + | But that meant keeping the Subverion repo and the GitHub repo in sync... and Erin was quite certain that '' | ||
| + | |||
| + | There were multiple how-to' | ||
| + | |||
| + | In the end, I figured a write-up that is //not// missing one or two crucial steps would be nice, so I did one. | ||
| + | |||
| + | ===== Initial Setup ===== | ||
| + | |||
| + | So I had the SVN repo at '' | ||
| + | |||
| + | I did set up an GitHub account and a [[https:// | ||
| + | |||
| + | ===== Get a local clone ===== | ||
| + | |||
| + | This is easy: | ||
| + | |||
| + | < | ||
| + | git clone git@github.com:/ | ||
| + | </ | ||
| + | |||
| + | You need to have copied your SSH pubkey to your GitHub account for this kind of authorization to work (click on your avatar in the top-right corner, select " | ||
| + | |||
| + | Change into the freshly cloned Git Directory: | ||
| + | |||
| + | < | ||
| + | cd pdclib | ||
| + | </ | ||
| + | |||
| + | ===== Tell Git about SVN ===== | ||
| + | |||
| + | Now we tell Git that there is another repository which we want to fetch data from (a.k.a. " | ||
| + | |||
| + | < | ||
| + | git svn init -s svn:// | ||
| + | </ | ||
| + | |||
| + | The '' | ||
| + | |||
| + | ===== Map the authors ===== | ||
| + | |||
| + | Subversion logs commits with the user's login name. For Git, '' | ||
| + | |||
| + | < | ||
| + | solar = Martin Baute < | ||
| + | erin = Erin Shepherd < | ||
| + | cycl0ne = cycl0ne < | ||
| + | </ | ||
| + | |||
| + | ===== Fetch the data ===== | ||
| + | |||
| + | Now we can fetch all the revision data from Subversion. For this, we need '' | ||
| + | |||
| + | < | ||
| + | git svn fetch --authors-file=authors.txt | ||
| + | </ | ||
| + | |||
| + | If '' | ||
| + | |||
| + | After this step is complete (which might take a while), the latest Subversion information is available to Git. | ||
| + | |||
| + | ===== Git Branches ===== | ||
| + | |||
| + | Let's set up the '' | ||
| + | |||
| + | < | ||
| + | git branch --no-track shepherd | ||
| + | </ | ||
| + | |||
| + | I selected '' | ||
| + | |||
| + | ===== Sync Branches ===== | ||
| + | |||
| + | Now here comes the trick. Git users do not really like '' | ||
| + | |||
| + | We set up //two additional branches// for the //sole purpose// of synchronizing SVN <> GIT: | ||
| + | |||
| + | < | ||
| + | git branch --no-track trunksvn | ||
| + | git branch --no-track shepherdsvn | ||
| + | </ | ||
| + | |||
| + | Then we link up both of these branches to their respective SVN remote. (This is where Ben Lobaugh' | ||
| + | |||
| + | < | ||
| + | git checkout trunksvn | ||
| + | git reset --hard remotes/ | ||
| + | </ | ||
| + | |||
| + | If you look at the contents of your directory, you will now see the '' | ||
| + | |||
| + | Make sure that everything is up-to-date (which it will be anyway at this point, but get into the habit early). We are talking to Subversion again, so '' | ||
| + | |||
| + | < | ||
| + | git svn rebase | ||
| + | </ | ||
| + | |||
| + | Now switch to the //target// branch, and merge in the sync branch. We need to tell Git explicitly that it is OK to merge '' | ||
| + | |||
| + | < | ||
| + | git checkout master | ||
| + | git merge trunksvn --allow-unrelated-histories | ||
| + | </ | ||
| + | |||
| + | We do the same thing for the second branch-to-be-synced: | ||
| + | |||
| + | < | ||
| + | git checkout shepherdsvn | ||
| + | git reset --hard remotes/ | ||
| + | git svn rebase | ||
| + | git checkout shepherd | ||
| + | git merge shepherdsvn --allow-unrelated-histories | ||
| + | </ | ||
| + | |||
| + | ===== Push Branches ===== | ||
| + | |||
| + | We can now push the '' | ||
| + | |||
| + | < | ||
| + | git push --set-upstream origin shepherd | ||
| + | </ | ||
| + | |||
| + | Then we switch to our local '' | ||
| + | |||
| + | < | ||
| + | git checkout master | ||
| + | git push | ||
| + | </ | ||
| + | |||
| + | Any Git user cloning our GitHub repo now will see //only// '' | ||
| + | |||
| + | ===== Sync SVN -> Git ===== | ||
| + | |||
| + | To update the Git repo with changes made to SVN, we follow these steps (in our local clone directory which **does** have the SVN remote and the sync branches): | ||
| + | |||
| + | < | ||
| + | git checkout trunksvn | ||
| + | git svn rebase | ||
| + | git checkout master | ||
| + | git merge trunksvn | ||
| + | git push origin master | ||
| + | </ | ||
| + | |||
| + | Or, for the '' | ||
| + | |||
| + | < | ||
| + | git checkout shepherdsvn | ||
| + | git svn rebase | ||
| + | git checkout shepherd | ||
| + | git merge shepherdsvn | ||
| + | git push origin shepherd | ||
| + | </ | ||
| + | |||
| + | ===== Sync Git -> SVN ===== | ||
| + | |||
| + | To update the SVN repo with changes made to Git, we follow these steps (in our local clone directory which **does** have the SVN remote and the sync branches): | ||
| + | |||
| + | < | ||
| + | git checkout master | ||
| + | git pull origin master | ||
| + | git checkout trunksvn | ||
| + | git svn rebase | ||
| + | git merge --no-ff master | ||
| + | git commit | ||
| + | git svn dcommit | ||
| + | </ | ||
| + | |||
| + | Or, for the '' | ||
| + | |||
| + | < | ||
| + | git checkout shepherd | ||
| + | git pull origin shepherd | ||
| + | git checkout shepherdsvn | ||
| + | git svn rebase | ||
| + | git merge --no-ff shepherd | ||
| + | git commit | ||
| + | git svn dcommit | ||
| + | </ | ||
| + | |||
| + | ===== Re-Building ===== | ||
| + | |||
| + | If, for some reason, you lose that Git setup created above, you need to re-build it: | ||
| + | |||
| + | < | ||
| + | git clone git@github.com:/ | ||
| + | cd pdclib | ||
| + | git svn init -s svn:// | ||
| + | </ | ||
| + | |||
| + | Now you need to re-build the '' | ||
| + | |||
| + | < | ||
| + | commit 5950958ff57391789d9a164a56cd1ed87dedaa12 (HEAD -> master, origin/ | ||
| + | Merge: 02e56d5 ec5835f | ||
| + | Author: Martin Baute < | ||
| + | Date: Tue Feb 2 10:59:34 2021 +0100 | ||
| + | |||
| + | Merge branch ' | ||
| + | |||
| + | commit ec5835f129d8f9629d334657d4c31b40d6190724 | ||
| + | Author: solar < | ||
| + | Date: Mon Feb 1 21:15:12 2021 +0000 | ||
| + | |||
| + | git-svn-id: https:// | ||
| + | ^^^ | ||
| + | </ | ||
| + | |||
| + | A bit easier is to have the computer extract the number for you: | ||
| + | |||
| + | < | ||
| + | REVISION=$(git log | grep git-svn-id | head -n1 | sed -e " | ||
| + | </ | ||
| + | |||
| + | Now fetch everything from your SVN repository //up to that revision//: | ||
| + | |||
| + | < | ||
| + | git svn fetch -r0: | ||
| + | </ | ||
| + | |||
| + | Set up the sync branch, and link it to the SVN remote: | ||
| + | |||
| + | < | ||
| + | git branch --no-track trunksvn | ||
| + | git checkout trunksvn | ||
| + | git reset --hard remotes/ | ||
| + | </ | ||
| + | |||
| + | Now rebase the branch //to what you already fetched//. The '' | ||
| + | |||
| + | < | ||
| + | git svn rebase --local | ||
| + | </ | ||
| + | |||
| + | Now we merge the sync branch to our master. This is basically a no-op, but it sets the merge point from which we will proceed. | ||
| + | |||
| + | < | ||
| + | git checkout master | ||
| + | git merge trunksvn --allow-unrelated-histories | ||
| + | </ | ||
| + | |||
| + | Now we are set up again, and can sync the SVN revisions we left out previously by the " | ||
| + | |||
| + | < | ||
| + | git checkout trunksvn | ||
| + | git svn rebase | ||
| + | git checkout master | ||
| + | git merge trunksvn | ||
| + | git push origin master | ||
| + | </ | ||
| + | |||
| + | ===== Conclusion ===== | ||
| + | |||
| + | I hope this little how-to helps you settling the holy VCS war. | ||
