Long ago, someone, for some reason, thought it was a good idea to use branches in SVN as if they were repositories, so one repository contained many different branches each branch being its own completely independent project. When we moved to GIT we agreed to not repeat this mistake. We converted the entire SVN repo to a GIT repo long ago using Svn2Git, this worked well, except we still had all of those crazy branches in there. I don’t remember how we got the other branches out originally, but I am sure it was not the best way…or even a good way. We have been using GIT for some time and understand it better, and we still have a few old branches that we never extracted, but the time has come for us to do so. It was much easier now that we have some clue what is going on, and I though I would explain how we did it because it is rather simple…if you know what you are doing.
Overview:
For us we actually want these to be bare remote repositories can be pushed to. Basically all you need to do is push the single branch into a new GIT repository and create a “master” branch in it. If you are making a bare repository, you then just need to clone the new repository to a bare one. Really, that is it, so here is a breakdown.
Breakdown:
So, working on the assumption that we have our entire SVN repo (or whatever is your poison) converted to a GIT repo, we start by creating a new empty repo. Create a new directory to hold the repo, then go into that directory and run:
git init
This creates a new empty repository.
Now, push the branch from the old repo into the new one by going into the directory of the old repo and running:
git push /path/to/new/repo branch-to-extract
At this point your new repo contains only the single branch you extracted!
Next we have to create a new “master” branch for this repository. To do so, first we have to checkout the old branch. Navigate to the directory for the new repo you just created and run:
git checkout branch-to-extract
You should now see the code that was in that branch. Now we create a new “master” branch with:
git branch master
At this point you have a GIT repo for you project that is good to go! If this is all you need, you are done! If you want to turn this into a bare remote repository that someone can use, simply clone it –bare as normal.
Simply clone this new repo to the new remote one:
git clone --bare /path/to/new/repo /path/to/bare/repo
You can now clone this repo to your local machine and use it normally, with all the great pushing, pulling, branching and everything else GIT has to offer. If you like you can delete the “/path/to/new/repo” repo that we setup to extract old branch from, or delete the branch that you imported from from your fantastic new repo.
It really is that easy. It all makes perfect sense now and took me only a few minutes to figure out. When we were first trying to move to GIT though, and didn’t really understand it, this was not easy and did not make perfect sense. Hopefully if someone else out there has done the same bad thing or something similar and is now trying to fix the problem this will help them out.
Ollie Glad the guide is helpful!If you’re wronikg with other people, who are using Git exclusively, then you’ve got a whole host of other worries to deal with. From my understanding, when you rebase against the svn trunk, git-svn renames each commit to be in accordance with svn’s linear commit numbering. That means that when you commit a change with Git hash 12345, and then svn dcommit (or git rebase svn/trunk), the commit ID is changed to something else say 54321. If you push that change back up to Github (at least, if you force push it), you are effectively replacing your pure Git history. This is a problem for collaborators who are getting their information through Git, because commit 12345 (which they had already pulled) is in conflict with (because it is identical to) 54321.You can get around some of this by omitting the rebase flag from your git pull. Git merge will detect your conflicts and will usually do a pretty good job of wronikg around them automatically. However, you may find that there is still some funny business you might end up, for instance, with two versions of every commit (the Git version and the SVN version) in your commit logs.For your setup, you might consider using SVN in a slightly dumber way, where at release time you copy over your files from Git into a fresh svn checkout of your trunk, svn add any new stuff, and then just commit the changes. That’ll mean that your svn commit history will not be in sync with your Git history, but at least it means that you won’t have any problems with being out of sync with your collaborators. Let me know what you figure out I’m still learning as I go along with this stuff!