Is git-svn dcommit after merging in git dangerous?

Knut Eldhuset picture Knut Eldhuset · Oct 10, 2008 · Viewed 36.4k times · Source

My motivation for trying out git-svn is the effortless merging and branching. Then I noticed that man git-svn(1) says:

Running git-merge or git-pull is NOT recommended on a branch you plan to dcommit from. Subversion does not represent merges in any reasonable or useful fashion; so users using Subversion cannot see any merges you've made. Furthermore, if you merge or pull from a git branch that is a mirror of an SVN branch, dcommit may commit to the wrong branch.

Does this mean I cannot create a local branch from svn/trunk (or a branch), hack away, merge back into svn/trunk, then dcommit? I understand that svn users will see the same mess that merges in svn pre 1.5.x have always been, but are there any other drawbacks? That last sentence worries me, too. Do people routinely do these kinds of things?

Answer

Sebastien Varrette picture Sebastien Varrette · Nov 21, 2010

Actually, I found an even better way with the --no-ff option on git merge. All this squash technic I used before is no longer required.

My new workflow is now as follows:

  • I have a "master" branch that is the only branch that I dcommit from and that clone the SVN repository (-s assume you have a standard SVN layout in the repository trunk/, branches/, and tags/):

    git svn clone [-s] <svn-url>
    
  • I work on a local branch "work" (-b creates the branch "work")

    git checkout -b work
    
  • commit locally into the "work" branch (-s to sign-off your commit message). In the sequel, I assume you made 3 local commits

    ...
    (work)$> git commit -s -m "msg 1"
    ...
    (work)$> git commit -s -m "msg 2"
    ...
    (work)$> git commit -s -m "msg 3"
    

Now you want to commit onto the SVN server

  • [Eventually] stash the modifications you don't want to see committed on the SVN server (often you commented some code in the main file just because you want to accelerate the compilation and focus on a given feature)

    (work)$> git stash
    
  • rebase the master branch with the SVN repository (to update from the SVN server)

    (work)$> git checkout master
    (master)$> git svn rebase
    
  • go back to the work branch and rebase with master

    (master)$> git checkout work
    (work)$> git rebase master
    
  • Ensure everything is fine using, for instance:

    (work)$> git log --graph --oneline --decorate
    
  • Now it's time to merge all three commits from the "work" branch into "master" using this wonderful --no-ff option

    (work)$> git checkout master
    (master)$> git merge --no-ff work
    
  • You can notice the status of the logs:

    (master)$> git log --graph --oneline --decorate
    * 56a779b (work, master) Merge branch 'work'
    |\  
    | * af6f7ae msg 3
    | * 8750643 msg 2
    | * 08464ae msg 1
    |/  
    * 21e20fa (git-svn) last svn commit
    
  • Now you probably want to edit (amend) the last commit for your SVN dudes (otherwise they will only see a single commit with the message "Merge branch 'work'"

    (master)$> git commit --amend
    
  • Finally commit on the SVN server

    (master)$> git svn dcommit
    
  • Go back to work and eventually recover your stashed files:

    (master)$> git checkout work
    (work)$> git stash pop