views:

1913

answers:

4

I am using git-svn with the following workflow now

git clone <SVN TRUNK URL> #done once

subsequently when I work on a feature

git branch featureZ
git checkout featureZ
#make edits for featureZ
git commit

git checkout master
git svn rebase # fetch changes from server

git checkout featureZ #go back to branch
#git merge master 
git rebase master #get the changes from SVN->master onto the branch now. Optional if I want the branch to be current. (EDITED: Got from the answer given below)

#make edits for featureZ
git commit #featureZ completed

git checkout master
git merge featureZ #getting featureZ onto master. Prepare to send to SVN

git svn dcommit #push featureZ back to SVN

Now some points of note when I do git merge of feature onto master, all the individual commits in featureZ branch gets merged as one which is fine with me.

The commit message is replaced as "merged with featureZ". That can be fixed with merge fmt msg.

Now my question is Is there anything that can go wrong with this workflow or needs to be taken care of. I read in git-svn manual that merge should not be done when working with git svn. Is what I am doing in my workflow is what that they are referring to? if so what kind of problem will it cause? One thing is I don't want to do something that messes with the SVN mainline.

+8  A: 

SVN cannot handle non-linear history (it simply has no notation of it). So what you want to do is a rebase instead of a merge as it preserves linear history with SVN (this is indicated in on the git-svn man page here.

To elaborate, linear histories are trivial. They go in a straight line (A to B to C to D). Whereas non-linear histories can go from (A to B to C, B to D then C + D to E--in other words, they off sprout into branches).

Rebasing will give you a linear history. Remember that rebases should be done from your private local-only branches. For instances, if you have 2 branches: master and experimental. You would checkout experimental and do 'git rebase master' preferably with the -i flag. Doing it the other way around may result in undesirable side effects.

It is then you checkout master and merge in the changes from the experimental branch. Your history should remain linear.

Fake Code Monkey Rashid
could you explain what is non-linear history? Another thing is I don't want(care) that SVN needs to know that I had local branches that I merged from. where do you suggest rebase needs to be done in my workflow? git rebase featureZ?
Pradeep
I elaborated on my answer. Hope it helps. :)
Fake Code Monkey Rashid
Thanks for the explanation. I understood what non-linear history is though I create only linear histories so far(new to branching itself).So now to be prepared for non-linear histories I started using git rebase master from the feature branch to pull the changes from master on to the feature branch. This works fine. It pulled the changes from the master onto my branch and replayed my commits on top of it.So the only change is to use "git rebase master" instead of "git merge master" from branch.The final "git merge featureZ" from the master branch is ok then?
Pradeep
Yes, that's basically it. So to rehash again you want to do 'git rebase master' instead of 'git merge master' from the featureZ branch and then 'git merge featureZ' from the master branch. Of course remember to verify your history using 'git log --graph --decorate --abbrev-commit', gitk or gitview to make sure you achieved the results you wanted.
Fake Code Monkey Rashid
Thanks Rashid. Understood the use of rebase command in this workflow. I am able to follow rebase manual now as it relates to this.(Note I only tested this with a linear history in featureZ branch but according to the manual rebase can transplant non-linear histories as well)
Pradeep
+2  A: 

You should look at this merge option:

git checkout master
git merge --squash featureZ

It will squash all commits on the branch into a single commit on the master branch. You will get an opportunity to edit the log message, which is initialized with a summary of what was done on the branch.

It has the disadvantage that the individual commits on the feature branch are not recorded. Furthermore, you should only do this once, and not do any more work on the branch, because it is not registered as a proper merge, and any subsequent merge might give undesired results.

Ropez
Squashes destroy branch history and thus I cannot recommend them. If I could down-vote you I would (and I will).
Fake Code Monkey Rashid
Squashes would make sense if I don't the want the local feature branch history to be captured. I could send a single fat commit to SVN on the mainline which would hide all the branching I had done if I wish. good that git doesn't prevent that. Thanks Ropez.
Pradeep
Yes, it arguably has it uses but I believe history to be precious. The furthest I'd go is lightly rewriting it using the least invasive method available and a squash is very invasive. It destroys all the changes you made and the order you made them in. It hides all the mistakes and the silver linings that helped you fix them. It erases the person and gives you a vastly impersonal end result (ie: that single fat commit).But that's just my latest opinion and you are not me. So I agree on the point that it is good that git is flexible. :)
Fake Code Monkey Rashid
Sizzler said, "all the individual commits in featureZ branch gets merged as one which is fine with me". Squashing commits might not be a smart thing to do in general, but it is an option that is meant for exactly the situation described above, if the individual commits in the feature branch is not important. It is certainly an option that is relevant to this question.
Ropez
Edit to include a warning about loosing individual commits
Ropez
As an additional note, you don't actually 'lose' that history - it still exists in your git repository. If you needed to share that history, I'm pretty sure you could do a git-svn branch and apply those commits to that branch and then merge it back in with git-svn
deterb
A: 

The answer given by fake-code-monkey-rashid is correct. This is less of an answer and more of a simplification.

You can svn rebase/dcommit from any git branch. The only use master would have is if you had other local changes you needed to merge with the changes from featureZ.

git branch featureZ
git checkout featureZ
#bunch of changes
git commit
git svn rebase
# solve any conflicts
git svn dcommit

If you want to keep a clean master then you can either git svn rebase it or git merge featuresZ

John K
A: 

Hey Guys,

I have been using git and git svn for a little bit now but still have problems with finalising the merge and commit to svn. My current workflow is this :

  • git co master "this is the svn trunk"
  • git co -b work-branch
  • git commit etc.....
  • g/finished working on branch
  • git co master
  • git svn rebase
  • git merge work-branch
  • git diff work-branch // no differences in code
  • git log master..work-branch // no differences in log messages
  • git svn dcommit
  • git svn rebase
  • git diff work-branch // no differences in code
  • git log master..work-branch //now all the log differences show up
  • git branch -d work-branch //cannot delete because of unmerged changes???

This is where i am getting confused because the logs don't match and the only way i can delete the branch is with -D. I don't know if i like this idea because i would like to see what happened on branches? Is it just my misunderstanding of this whole process ;)

thanks in advance

donkeyx