tags:

views:

952

answers:

5

I'm using Git-Svn to interact with a Svn repository at work and I can't seem to find a way to effectively resolve conflicts for the life of me. I've read the other questions on this topic, but evidently I need something even more remedial because i always seem to end up in some kind of endless loop. I rebase, use mergetool (meld) to resolve my conflicts and, when I get to the end of all that, I try to do a dcommit and I get a merge conflict during commit error.

I know this feels like a duplicate, but frustration is making me ask again, with some very specific details about how I'm going about this so that hopefully someone can tell me exactly where my process is screwed up.

My setup:

I have a remote branch (svn/trunk), a local branch (trunk) and another local branch that I typically work in (working-trunk). trunk was checked out from svn/trunk and working-trunk was checked out from trunk.

Here's what I've been doing:

  1. On my trunk, git svn rebase (returns conflicts)
  2. git mergetool
  3. [resolve the conflicts for that file]
  4. Save the merged file from meld and close meld.
  5. git add .
  6. git rebase --continue
  7. [rinse, repeat]
  8. If I get a message asking whether I used git add, I git rebase --skip

When I get to the end of all the reported changes, everything just kind of stops and I guess maybe I'm not sure what to do at this point. Git shows nothing to be committed and I appear to be back on the trunk. Git then allows me to dcommit, but if I try a rebase immediately thereafter, I end up re-resolving the conflicts I just resolved.

There's clearly a critical piece I'm missing here, but I just don't see it and it's causing a lot of problems and frustration. Merges may be easy in Git, but I'm sure not finding that to be the case.

Thanks.

UPDATE: Just wanted to throw out a quick update to describe my workflow in case that's part (or all) of the problem.

To start, after cloning my repository with a svn/ prefix, I have my svn/trunk remote branch. Given that:

  1. I git co -b trunk svn/trunk to check out my remote to a local branch.
  2. I git co -b working-trunk to create a working branch that I use to create one more degree of separation so that my local trunk can always mirror my remote trunk.
  3. I delete the default master branch (when working with svn, I find it easier to think in terms of "trunk" rather than "master").

Once I have all of my branches, my typical workflow looks like this:

  1. On working-trunk, I make my changes and commit them.
  2. I git co trunk and do a git svn rebase.
  3. Assuming new code was rebased, I git rebase working-trunk.
  4. git co working-trunk
  5. git merge trunk
  6. git rebase trunk
  7. git co trunk
  8. git merge working-trunk
  9. git svn dcommit

It's a lot of steps, I know, but that's what everyone here and elsewhere has recommended. Could my fatal flaw be somewhere in that process?

Thanks again.

A: 

I tried this with a(n admittedly small) conflict I forced, and after the git svn dcommit I had no further conflicts. One difference is that I did not receive a message about git add. Is it possible that your team is just sending in lots of commits that happen to conflict with your work? It seems unlikely, but it seems to be the simplest explanation.

It might be worth your time to get the repo again in a different location and test whether you can push nonconflicting changes to make sure there's not a communication problem during the dcommit stage that is being hidden somehow.

UPDATE: One other thought I had: I did a git add foo.bar when I had finished resolving the conflict. Is it possibe that git add . is doing something unexpected? I don't really stretch the capabilities of git svn all that much, so these are pretty much WAGs.

Hank Gay
It could also be that I'm too sloppy with how I handle my repository, but I'm not sure how/why that would be. I've run into this several times and have ended up completely killing and rebuilding my repos each time. Hugely frustrating.Thanks for your thoughts.
Rob Wilkerson
A: 

It seems something is not operating the way you think it is. If it's not the unlikely things that Hank Gay suggested, then it is some other unlikely thing.

My unlikely possibility is that your branch structure is not what you think it is or you are not rebasing on the branch that you think you are. So I suggest that you:

  1. git branch just to confirm your branch structure is what you expect

  2. Add
    export PS1='\e[0;31m\n\w$(__git_ps1 "(%s)") $ \e[m'
    to ~/.bash_profile and login again,
    to show the branch (and any in-process git command) in your prompt:

    /workspace/wikka(featurebranch1|REBASE-i) $

That will give you more feedback (and probably eliminate this WAG as a possibility).

Paul
A: 

I would recommend using git-svn only between your local trunk and the remote trunk. Between your local trunk and local mytrunk, stick to standard git only features. You could possibly try a work flow like this:

[SVN]---git-svn---[trunk]---branch---[mytrunk]

To merge, switch to trunk and do a:

git svn rebase

This pulls in changes from the remote and merges it with trunk. Then, switch over to mytrunk and do a:

git rebase

This pulls the changes from trunk and merges it with mytrunk. I think that it should work. Otherwise, just git-clone the local trunk and work on the clone instead.

sybreon
That sounds like what I do, if I understand you correctly. I'll update my original question with my workflow.
Rob Wilkerson
+2  A: 

I'd recommending using git rebase instead of git merge. Svn keeps a linear history and seems to get confused with git branch merges sometimes. Using git rebase ensures a linear history svn understands.

see: http://learn.github.com/p/git-svn.html for a bit more info and guidelines.

Justin
A: 

I've just encountered this problem while using the recommended workflow, so I think we lack an answer here.

Here's how I got into this situation.

I have a git repo via git svn, using the Apache infrastructure.

I have a local branch.

I try to follow this procedure:

1) rebase trunk. 2) merge trunk into private branch. 3) do work. 4) rebase trunk. 5) merge private into trunk. 6) dcommit.

However, I messed up, and I had forgot to push a change from private to trunk. I then made a series of other changes to my private branch, and ended up in the rinse-and-repeat loop on a completely spurious conflict. The last change I had pushed up was to comment out a single line. When I then deleted that line in the neglected change, it produced the conflict that would not resolve, no matter what. I eventually used --skip on it.

bmargulies