简体   繁体   中英

Git with SVN trunk and branches

Since I've been using Git, I liked the fact that you can create a local branch which you can squash to your master branch and DCommit to SVN (on trunk), and then delete that local branch (on Git).

Now I want to find out how to deal with SVN branches. I need to work with a team on a new feature but we don't want to do that on Trunk. So obviously we need to branch from trunk and work on that branch till we're happy with the work and merge back to Trunk.

Any ideas on how to do that from a Git front-end perspective? I'm sure there are plenty of resources out there but I haven't found something that explains that to me.

So just to make sure I explain myself, I know how to use Git with SVN trunk alone. That's easy and good. But I need to branch on SVN from trunk and use Git to work on that branch (while hopefully still having access to SVN trunk with Git) till the work is done and then merge that branch back to trunk on SVN (again using Git). If anyone can give me insight to that, I'd be VERY grateful! Is it possible to have that within a single Git repo?

Thanks in advance. (If it's still not clear please let me know).

I blogged about this topic a few months ago: http://www.jillesvangurp.com/2012/08/04/git-presentation/

In short, you can track multiple svn branches in a single git repository but you really shouldn't. Having messed up on one occasion I would basically never ever try tracking multiple svn branches in one repository again. It's just too volatile and too easy to major damage in svn. Basically everything seemed fine locally and I dcommitted my changes. But actually I reordered some commits that really shouldn't have been reordered and did a lot of damage upstream. In the end I had to do a big svn revert. Very embarrassing.

So, instead work with separate git repositories to track each svn branch and use those repositories as a remote on a git only repository where you actually work pushing to the different remote repositories as you go. Isolating git and svn like this makes a lot of sense. Make sure to keep your history linear (svn doesn't do non linear) and make sure to always rebase against upstream.

A safer way to move commits between branches/repositories (same thing in the git world) in this context is to use git format-patch and git am. Alternatively, you can use git cherry-pick inside a repository.

I have finally discovered what I need to do in order to work with SVN branches using Git. I have tried the stuff mentioned below (except where I specify) so I am fairly confident that as long as I don't do anything funny or out of line, my commits from Git to SVN should work just fine. But of course I don't take any responsibility for any problems that might occur! I am open for further comments / remarks.

Even if I don't clone the SVN repo with the standard layout, I should have remotes configured that are pointing to the relevant SVN paths on subversion.

To clone a SVN branch (the SVN path should be pointing to the root path containing trunk, branches and tags):

git svn clone -s http://myrepo.com c:/my/local/path

If you are already have a clone of an SVN branch you need to manually add remotes to other SVN branches, check these out:

What is important is that you have a local branch that is tracking the remote branch.

git checkout -b localbranch remotes/remote_branch

Now you can commit against that local branch and each time when done do this just like in trunk:

git svn fetch
git svn dcommit

When you are finally done with that SVN branch and you would like to merge to trunk, you can do the following (it takes everything from that branch and rebases it into master):

git checkout master
git merge localbranch
git rebase -i trunk  (just save the message)
git svn fetch
git svn dcommit

You can also just do a squash merge if you want to (if you don't want to bring all those little check-ins accross):

git merge --squash localbranch
git svn fetch
git svn dcommit

You might be doing a dry-run before doing a real DCOMMIT to make sure everything is fine (including the destination).

git svn dcommit -dry-run

However, if you anticipate merge conflicts (this is what I read on the web but I haven't tried it which I'm just mentioning) do the following before the git checkout master line shown above. This is a local branch that doesn't track the remote branch which should be used to tackle merge conflicts and stuff. Whether this is necessary is another story.

git checkout -b merge_work master
git merge localbranch
git checkout master
git rebase merge_work

I'm writing this down for myself and for other people who might want to try this in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM