git-svn and local feature branch (git svn dcommit error ?)

John Ralls jralls at ceridwen.us
Sun Jul 17 18:03:39 EDT 2011


On May 24, 2011, at 4:04 AM, Geert Janssens wrote:

> On maandag 23 mei 2011, John Ralls wrote:
>> On May 22, 2011, at 12:54 PM, Christian Stimming wrote:
>>> Am Sonntag, 22. Mai 2011 schrieb John Ralls:
>>>> The procedure in the Wiki page is what I think is correct (and what I've
>>>> done).
>>>> 
>>>> It's perfectly normal in git to get part of a complicated feature done
>>>> and copy that bit to the main branch (trunk for us, but "master" is the
>>>> usual name in git repos) and then to keep working on the feature
>>>> branch. In that case one should periodically merge the main branch into
>>>> the feature branch
>>> 
>>> Yes, absolutely, for the normal git workflow.
>>> 
>>> However, here we are talking about the git-svn branch from which we want
>>> to
>>> 
>>> dcommit to SVN. The IMHO unexpected part here is this:
>>>> git checkout trunk
>>>> git rebase feature
>>>> git svn dcommit
>>> 
>>> I.e. why is the "trunk" rebased on top of the "feature" branch, then
>>> being d- committed? Either all of the feature branch should go into SVN,
>>> in which case I would rebase "feature" on top of "trunk" (i.e. the other
>>> way round compared to the above steps). Or the "feature" commits should
>>> not (yet) be committed, in which case I would do
>>> 
>>>> git checkout feature
>>>> git merge trunk
>>> 
>>> and then occasionally cherry-pick some of "feature"'s commits into trunk
>>> and d-commit from there. In the end, I would again rebase "feature" on
>>> top of "trunk" and this way d-commit all the commits that haven't been
>>> cherry-picked to trunk before.
>>> 
>>> I agree this "git merge trunk" is written in the end of this new section,
>>> and that's what I have expected. But the "git rebase feature" still
>>> looks unexpected to me.
>> 
>> Sorry, you're right. I got the direction of rebase backwards. So it should
>> be
>> 
>> git checkout feature
>> git rebase trunk
>> (Or just `git rebase trunk feature` which does both steps at once)
>> git svn dcommit
>> 
> Right, that is what I have been doing all the time and why I was surprised 
> about your setup. But considering my limited experience with git, I was 
> willing to follow your workflow.
> 
>> You're probably right about cherry-picking, too. (You can cherry-pick all
>> of the changes at once with `git cherry-pick ..trunk` when checked out in
>> feature.) Rebasing might have contributed to Geert's remote refs getting
>> messed up.
>> 
> Yes, I think so too. And particularly rebasing while the two remotes involved 
> (svn and John's github master repo) are not in sync.
> As said before, I wanted to dcommit two separate feature branches right one 
> after the other. They were both rebased to the actual remote trunk just before 
> I started the process of dcomitting.
> 
>    B - D - E      Feature 1
>  /
> A                  Trunk (both local and remote)
>  \
>    G              Feature 2
> 
> 
> The first dcommit worked fine:
> 
>    B' - D' - E'      Feature 1, Trunk local, Trunk svn
>  /
> A                  Trunk github
>  \
>    G              Feature 2
> 
> At that point I got unsure. Just to be sure I now ran git-update, which 
> resulted in this:
> 
>    B' - D' - E'      Feature 1, Trunk svn
>  /
> A                  Trunk github, Trunk local
>  \
>    G              Feature 2
> 
> And I think that was a mistake. Github hadn't synched yet with subversion, so 
> it rebased trunk back to the github's trunk, while svn's trunk was pointing to 
> my feature 1. Perhaps internally, this also messed up git-svn's state, I can't 
> tell.
> 
> Assuming I should always commit to trunk, and my Feature 2 branch was again 
> based on trunk due to the git-update action, I continued to dcommit Feature 2. 
> This worked fine, although I don't know exactly what the new state became.
> 
> After that I didn't do anything anymore until after the next github svn sync. 
> And from there on, I got the issues I reported.
> 
> I now think I would have avoided these problems if I didn't run the git-update 
> command in between the two dcommits. Instead I should have rebased feature 2 
> on top of feature 1. Wether I'd have done that before or after the first 
> dcommit is probably not really important.
> 
>> Starting with
>>     B - D - E		Feature
>>  /
>> A  - C - F		Trunk
>> 
>> Rebasing does this:
>> 
>>                 B' - D' - E'
>>               /
>> A - C- F
>> 
>> If you dcommit with E' checked out (which is where you'll be after the
>> rebase), Github:Gnucash/gnucash will see
>> 
>> A - C - F - B" - D" - E"
>> 
> ...that is, after the next time github and svn are synched together.
> 
>> When you run git-update you'll have
>> 
>>                  B' - D' - E'
>>               /
>> A - C - F - B" - D" - E"
>> 
> Again, only if you wait until after the next sync. If you don't wait before 
> running git-update, your local trunk will be dissociated from git-svn's trunk 
> and be reset to F.
> 
>> And a merge will adjust your references to
>> 
>>                  B'   -   D'   -   E'
>>               /                     /
>> A - C - F - B" - D" - E"
>> 
>> On the other hand, cherry-picking the whole thing will produce
>>    B - D - E
>>  /
>> A  - C - F - B' - D' - E'
>> 
>> Which after dcommitting, git-updating, and merging will look like:
>> 
>>    B       -        D      -      E
>>  /                                  /
>> A  - C - F - B" - D" - E"
>> 
>> Which is a better reflection of history and has less chance of references
>> getting screwed up. On the other hand, you have to make sure that your
>> checked out on trunk at E' when you dcommit (or say `git svn dcommit
>> trunk`) or you'll wind up dcommitting your feature branch to subversion,
>> which will make a bit of a mess.
>> 
> Cherry picking does look like a good alternative.
> 
> But in my opinion the actual thing that allowed me to make my mess is that 
> github and svn can be out of sync for 4 hours. If you run a git-update during 
> that time it can have a backwards effect if your local git and svn are more 
> recent than github. My mistake is not avoided by using either cherry-pick or 
> using rebase, because a git-update with an out of sync git-hub resets your 
> (more recent) trunk from underneath you.

This bit me this afternoon in spite of having the commit hook in place. I eventually worked it out, and I've written up various fixes on the Git wiki page [1].

Regards,
John Ralls

[1] http://wiki.gnucash.org/wiki/Git#Trouble




More information about the gnucash-devel mailing list