Subject: Re: A workflow for local patch maintenance

From: Jonathan Nieder <[email-masked]>
Date: Thu, 10 Oct 2013 12:18:27 -0700

Jeff King wrote:

>   3. The pain in doing the big rebase-test-deploy cycle meant that we
>      often delayed it, keeping us several versions behind upstream.
>      This is bad not only for the end product (you aren't getting other
>      bugfixes from upstream as quickly), but also because the longer you
>      wait to rebase or merge, the more painful it generally is.
>
> That being said, there are some new downsides, as you noted:
>
>   1. Resolving conflicts between your version and the reworked upstream
>      version can be a pain.
>
>   2. If your local development does not happen in a clean series, it can
>      be hard to create a clean series for upstream, and/or revert in
>      favor of upstream when necessary.

That suggests a possible hybrid approach: use a normal merge-heavy
workflow day to day, but occasionally clean up, for example by
rebasing against upstream.

That doesn't address the question of "how do I preserve old versions
of my patchset after a rebase", though.

The msysgit project uses a script called merging-rebase.sh[1] to
keep their patches current on top of the shifting target of git's
"next".  It's similar to your "merge -s theirs" approach.  It has some
problems (once you get past the current version of the patch stack,
history mining is complicated by all the old versions of the patch
stack) but for their day-to-day development it works ok.

There is an interesting approach that involves only merging and never
rebasing, while still being able to create a presentable patch series
when you're done.  The idea is to keep each patch meant for upstream
consumption in a separate (specially named) branch, with tracked files
like ".topmsg" containing its commit message, dependencies, and other
metadata.  There is a tool called 'tg' (TopGit) for working with this
kind of repo[2].  The Hurd uses it for their binutils and glibc
patches.

Another tool for maintaining a public patch stack, this time using a
"quilt"-style workflow instead of aggressively using native git
commands, is guilt[3], used for example to maintain the ext4 patch
queue.

In practice I tend to find all these too formal, and just keep one
branch that moves forward and is never rebased and a separate branch
that is constantly rebased with commits explaining all my changes to
the upstream code.  E.g., see [4].  This probably only works when the
patch stack is not very large.

Jonathan

[1] https://github.com/msysgit/msysgit/blob/master/share/msysGit/merging-rebase.sh
[2] https://github.com/greenrd/topgit#readme
[3] http://repo.or.cz/w/guilt.git
[4] git://repo.or.cz/xz/debian.git

    Here the constantly-rebased branch is not even published, since
    it is easy to re-create by applying the patches.

    The constantly-advancing branch is "master", which consists of
    patched upstream source + extra metadata in the debian/
    subdirectory.

    The constantly-rebased branch can be revived by applying the
    patches from debian/diff/ to the "upstream" branch.