[U-Boot] U-Boot git usage model

Scott Wood
2012-10-10T00:20:09Z

On 10/09/2012 06:25:47 PM, Stephen Warren wrote:
> On 10/09/2012 05:00 PM, Scott Wood wrote:
> > On 10/09/2012 05:14:23 PM, Stephen Warren wrote:
> >> I don't quite follow that; linux-next is also purely merge-based.
> Are
> >> you referring to the fact that it's re-created every day, and the
> >> source branches that go into the merge can be rebased if needed?
> >
> > What's the difference between "re-created every day" and "rebased
> every
> > day"?
>
> The linux-next model (and what I mean by "re-created every day") is
> roughly the following approximately daily:
>
> git fetch --all
> git branch -D tmp
> git checkout -b tmp u-boot/master # or latest rc in fact
> git merge u-boot-arm/next
> git merge u-boot-i2c/next
> git merge u-boot-video/next
> etc.
> git tag next-${datestamp}
>
> I'm not sure what "rebased every day means"; perhaps it's running the
> following on u-boot/next every day?
>
> git rebase u-boot/master
>
> That doesn't pull in any new commits from child trees though.

By "rebasing" I was referring to rewriting history in any form. It
looks like the difference is that linux-next gives the result a new
name each time, instead of working a branch with a fixed name.

> > How does merging back down prevent incremental pull requests?
>
> It doesn't prevent incremental pull requests, but it does pollute the
> history if you merge back down. Instead of a fairly simple:
>
> (M* == main branch, B* == side branch)
>
> B1-B2-B3-B4-B5-B6
> / \ \
> M1-M2-M3-M4-M4-M5-M6-M7
>
> you might end up with:
>
> B1-B2-B3-B4-X1-B6
> / \ / \
> M1-M2-M3-M4-M4-M5-M6-M7
>
> ... where X1 is the merge back from main to the side-branch. That
> doesn't look a lot more complex, but once there are many
> side-branches,
> and the master branch ends up merging a whole bunch of side-branches
> between M4 and M5 above, the commits in B* that add actual new work
> are
> split between a point before the X1 merge-back and after it. This can
> make tracking down what exactly will get merged into M* when B* is
> re-merged a bit trickier. git log M..B can probably show it fine, but
> if
> you start looking at gitk it'll look quite complex.

I don't use gitk much, but wouldn't it just show the mergeback as
another edge in the graph (plus the merge commit itself of course)? It
doesn't seem like a big deal.

> >> >> Or often when u-boot/master has made a complete new release
> >> >> does:
> >> >>
> >> >> b) Creates a new branch based on the latest rc or release from
> >> >> u-boot/master.
> >
> > That's a rebase. How is that better than a (likely fast-forward)
> merge?
>
> No, that's not a rebase.

Fine, a reset. Or a new branch name, which in practice is the same
thing except with a much more cluttered branch list, unless you have a
specific need to refer to an older iteration of this process.

> Rebase is when you take some existing commits
> based on one commit and apply them to a different baseline commit
> instead. If you're creating a new branch to take commits for a new
> release, you're simply not applying the commits for release N+1 until
> there's a branch ready to take them.

There is a branch ready to take them -- the custodian tree. Why wait
until there's an upstream tree ready to pull?

> >> >> (in practice, downstream branches typically end up with
> something
> >> >> like for-3.5 based on v3.4-rcN, for-3.6 based on v3.5-rcN,
> >> >> for-3.7 based on v3.6-rcN, some running in parallel containing
> >> >> either important bugfixes for the release or new development as
> >> >> determined by the current state of the various releases in the
> >> >> mainline tree).
> >
> > I thought you said your way was less work? :-)
>
> And I believe it is; no rebasing required.
> The difference probably isn't
> that big though I admit. Still, creating a fresh branch from scratch
> for
> each release one time and only then applying patches for that release
> seems a lot simpler that constantly rebasing stuff all over the place.

We've already dropped the rebasing. I'd rather do merges than
constantly create new branches.

> >> but with the Linux model, you simply:
> >>
> >> a) Send pull request.
> >>
> >> Admittedly the recipient then might need to resolve some merge
> >> conflicts. However, hopefully people have been planning for these
> and
> >> have avoided them.
> >
> > How do you plan for them and avoid them, and how is that less work
> that
> > what we do now?
>
> People have to be aware what is going on.
>
> If you're submitting a bunch of patches which depend on each-other,
> the
> submitter had better call that out when sending the patch series.

Sometimes it's not obvious in advance. Not all conflicts (whether they
be merge conflicts, build breaks, or runtime failures) come from
intrusive tree-wide changes.

> > I especially do not want to have to work with some artificially
> chosen
> > old tree as my base. I also do not want to create a bunch of named
> > branches for each
>
> Linux requires that branches be based only on rc or release tags in
> the
> equivalent of u-boot/master.

So how do you sort out dependencies? If I have a patch that depends on
some patches that have been already applied by custodian X, and others
that have already been applied by custodian Y (yes, this happened
recently), I have to wait until the next release to deal with them?

> U-Boot could choose to be different, and

U-Boot is already different in what RCs mean -- the merge window ends
well before rc1. So I couldn't even use my tree to send fixes for
issues caused by the merge, until shortly before release. Or rather,
I'd have to awkwardly backport the fixes to an old tree and hope that
they make it OK when merged into the real tree.

-Scott