Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

git svn - How can I use two SVN projects and corresponding git-svn branches with a single working directory?

I'm relatively new to Git, but I want to give it a try (vs SVN and Bazaar).

Can anyone recommend me a workflow for a situation similar to the following:

  • 1 SVN repo, with several projects
  • 1 working copy "src"

The ideea is that in "src" I need to checkout project A or sometimes project B. Both projects have several branches.

For now, I have made 2 git clones of the SVN repo, one for each project. (I would have preferred --bare repos, but it does not work with git svn clone)

Then, I made a git repo in "src", and git remote add projA ..a_repo_git, "git remote add projB ..b_repo_git".

Now, I can see both of them from "src" using "git remote", and I can see their branches with "git remote show projA"

And now the trouble..

  • How can I get in "src" any of the branches in projA/projB ?
  • How can I modify them, and then be able to push them back (first to the git_repos, or directly to the SVN repo)?
  • Is this "workflow" ok, or do you have a better idea?

I did try in src: git checkout --track -b work_branch projA branch_in_A and after some fiddleing with "fetch" I managed to get the things. But then, I had problems pushing it back to the a_repo_git, and then to SVN. It was mostly trial and error.

I have to admit, I still have problems with remote branches! (and I get lost when I have to use "origin local_branch:origin_branch" or "origin origin_branch:local_branch", or "origin origin_branch" or "origin/origin_branch"! Back to the Git manual for some more reading.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I haven't updated the question, because in the last several days I was able to work really nice and easy with the help of my new repo :)

Here is what I did in the end:

Init two SVN repos in the same directory. (I can't rember at this time, but it may be possible that a "git init" was done in the same dir, before:

mkdir src && cd src
(not sure about this: git init)
git svn init --stdlayout --prefix=projA/ -RprojA file:///path/to/svn/repo/A
git svn init --stdlayout --prefix=projB/ -RprojB file:///path/to/svn/repo/B

The "--stdlayout" means that the SVN repos are in the standard format, with trunk, branches and tags on the same level.

The "--prefix" is used for the branches name. When we do "git branch -a", all SVN branches from project A have the prefix "projA" (ex: projA/branch_name_of_A). The same thing is for B.

The -R option sets the name of the SVN repo, inside of the git repo (it's the name we use with git when refering to the SVN repository/project)

The file:///path is the path to the SVN repo, and to the project inside the repo, in this case. I use "file://" because I used a flat-file repo, with no server. I am sure it work ok with http:// too, for a SVN server.

After this step, out of curiosity I had a look at the file src/.git/config. The two commands above created several "svn-remote" sections, one for each project (the -R option), and a generic one called "svn". I've modified the entries, so there will be only references to the projects. Each reference had entries for the repo path (fetch) and for tags/branches/trunk. If you look at the file, you'll understand what needs to be changed.

After this, I've fetched the contents of each project, using

git svn fetch projA #the contents of project A repo are downloaded
git svn fetch projB #the contents of project B repo are downloaded

Now, runnig "git branch -a" displayed all branches from the two repos, and the master branch (local). "git branch -r" did not displayed any branches; probably because they are "svn-remote" and not "remote"

The current "master" branch was pointing to the trunk of the second project. I've decided to get rid of it, since it would cause problems when switching from a project to the other.

I've created two new branches to point to the trunks of each project, then removed the "master" branch:

git checkout -b master_project_A projA/trunk
git checkout -b master_project_B projB/trunk
git branch -D master

And now, for the "workflow"; to work on project A:

git checkout master_project_A #switch to project A
git svn rebase #check for any updates on SVN repo
git checkout -b work_on_A master_project_A #create a branch starting from the master of project A

work work work on work_on_A; commit, etc

git checkout master_project_A #go back to master of project A
git svn rebase #check again for any update on SVN repo
git checkout work_on_A #go back to the work branch
git rebase master_project_A #update branch with any changes from the master of project A
git checkout master_project_A #go back to the master of project A
git merge work_on_A #merge to the master of project A the changes from the work branch
git svn dcommit #commit changes to the SVN repo, in trunk, because master_project_A was pointing to its trunk

If I want to checkout an existing branch from the SVN, I can do it with:

git checkout -b work_on_branch projA/branch_name

work work work

git svn rebase #update any changes from projA/branch_name
git svn dcommit #commit updates back to the branch in the SVN repo

For project B I can do the exact same things. In the end, I can have the contents of project A or B in the same dir "src", and have access to both projects on the SVN repository from the same git repo! :D

I still haven't figure it out how to create a local branch then push it to the SVN repo - I was close, but it didn't work.

Also, it may be useful to know the command "reset" ("git reset --hard projPrefix/branch") but I broke a few things using it, so it may be better to leave this for some other time.

I hope this helps someone!

Cheers, Alex


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...