views:

21

answers:

1

Basically when i want to commit two separate changes in the same file that resulted from an git add --patch <file> operation, git svn rebase later on throws 1-2 conflicts upon comitting the second change when using git add for the second change.

so i'm basically doing this (i'm on master branch and have fetched the svn repository):

git checkout -b feature
... make two unrelated changes to file test.txt...
git add --patch test.txt
... add first change but ignore second one
git commit -m "change1"
git stash
git checkout master
git merge feature
git svn rebase
git svn dcommit
git checkout feature
git stash apply

now here there's two ways to do it, first the one that works:

git add --patch test.txt
... select everything (which is the second change in this case)
git commit -m "change 2"
git checkout master
git merge feature
git svn rebase
git svn dcommit

here's the one that doesn't work:

git add test.txt #notice there's no --patch
git commit -m "change 2"
git checkout master
git merge feature
git svn rebase #yields a conflict

So why is it that when using git add --patch for the second change, I can commit to the svn repository without problems, but when just using git add for the second change, it results in a conflict? I'm quite new to git, so this might be a stupid question, but as I see it, both commandsets should do exactly the same.

+1  A: 

why are you creating a branch for your 2 commits and then merge back? i guess this could give problems, since merges in git work differently from how they work in svn.

this should work ("should", but i'm pretty sure it does):

# on master, no need to create a branch
$ git add -p file
$ git commit -m "first set of changes"
$ git add file
$ git commit -m "the remaining changes"
# apply your commit on top of eventually new changes upstream
$ git svn rebase
# commit your 2 commits to svn
$ git svn dcommit

in svn branches are just copies of a directory (most often the trunk directory), and merge commits do not differ from normal commits (except the new svn:mergeinfo property starting with svn 1.6)

commits in git are different, each commit stores a link to it's parent commit. svn does not need this, as it can simply use REV-1. merge commits in git thus have multiple parents (the merging branch and the merged branch)

i do not know what happens if you dcommit a git to svn, but it will probably only commit the merge commit itself, without history (message being something like "merged branch 'bla' into 'master').

when you run svn commit only your new changes are sent to the server to save bandwidth. now, merges in git work different and the difference to previous versions will probably not be what you expect it to be, that's why git svn dcommit fails.

it even says so in the git svn documentation: do not merge branches using git and dcommit them to svn, it will most likely mess up your history

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. git svn docs

knittl
http://andy.delcambre.com/2008/03/04/git-svn-workflow.html I've been following this tutorial (I'm pretty new to git) and he says it's not recommended to work on the master branch. I tried it on master (not exactly your way, as I want to be two different rebase/dcommit to svn) and it worked without a problem. Would you mind explaining the difference between an svn and git merge to me, it would be greatly appreciated?
Zenon
@Zenon: i do not understand your »i want to be two different rebase/dcommit to svn«? can you elaborate?
knittl
Zenon
Basically it's a combination of this tutorial: http://tomayko.com/writings/the-thing-about-git and the one I posted earlier
Zenon
i think i still don't fully understand what you are trying to do. why are you using stash at all? and the master branch does not mean the thing is in svn. use `remotes/git-svn` (or `remotes/trunk`) instead
knittl
git won't let me merge the feature branch with the master and/or dcommit the changes when there's uncommitted changes, so I stash them away and apply them again after I committed the first changeset
Zenon
oh just saw your edit, that clears up a lot. So i guess the right way to do this with git-svn and a git branch would be to commit the git branch directly to svn? Or I'll just work with the master branch. Anyways, thanks for your help and I'll accept this as answer.
Zenon
@zenon: you can either directly dcommit your branch, or rebase first. anyways, you can run `git commit` several times and `git svn dcommit` will then commit each to svn. so if you run `git commit` 3 times and then `git svn dcommit` once, you will have three new commits in svn. for dcommit stash is sometimes necessary, that's true
knittl