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

Geert Janssens janssens-geert at telenet.be
Tue May 24 04:04:43 EDT 2011


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.

If at all possible, I would recommend to initiate the sync action as part of 
an svn post-commit hook. I realize this may not be easy because two different 
people manage the involved repos on independent servers.

Geert


More information about the gnucash-devel mailing list