git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: How to structure a project distributed with varyingly interdependent feature branches?

From
Junio C Hamano <gitster@pobox.com>
Date
Jan 2, 2008, 22:12 UTC
Message-ID
<7vwsqrvpur.fsf@gitster.siamese.dyndns.org>
In-Reply-To
<1199139613.2360.83.camel@localhost>
Matt McCutchen <matt@mattmccutchen.net> writes:
Show 10 quoted lines
> Rsync presents a unique challenge because it has a number of long-term
> feature patches that are maintained and distributed with the main source
> code.  Furthermore, some of the patches depend on other patches.
> ...
> 1. How to properly represent the history of an individual branch and
> update it when the trunk (or the branch on which it depends) changes.
> Right now, Wayne updates the branch by rebasing; unfortunately, if the
> trunk changes in such a way that one of the intermediate commits no
> longer makes sense, it is impossible to update the branch while
> preserving a record that the intermediate commit once existed.
I take this to mean a situation like this:
 * There is a series of patch X Y Z that implements some nicety
   not present in the mainline yet.  This set applies to older
   codebase at point A.
 * Newer codebase B does things differently from codebase A and
   patch X is no longer needed --- IOW, what X achieves on top
   of A has already been incorporated somewhere between A and B.
   Applying Y and Z suffices to obtain that nice feature on top
   of B.
               .---X---Y---Z       .---Y'--Z' 
              /                   /
      ---o---A---o---.....---o---B

This is natively expressed with git, if your history were like this:

               .----------X------Y-------Z
              /            \
      ---o---A---o---....---M---....---B

and you publish Z. People who would want to apply the series to their codebase simply merge Z. The patch dependency of X is captured in the mainline history because the effect of X is incorporated to the mainline as a merge at M. If the point they want to apply the series is older than point M (where patch X becomes unnecessary because of the mainline change), X, Y and Z will be brought in, while people basing on commits newer than M will pull in only Y and Z (because they already have X).

But that works only in theory and with a developer with perfect vision. Nobody would be able to forsee that X would become such a crucial change when it is developed. Often you would just create a regular commit M somewhere between A and B that has the effect of X, and later regret that you had made a separate X forked from an earlier A and recorded M as a merge.

People use quilt (or guilt) to manage patch stacks for things like this.

Having said that, I think you can maintain a single patch series (say the above X-Y-Z) and publish it as a few variants for downloaders as a prefabricated set of branches.

Say if you have this (the first picture), you do not create Y'-Z' history (again, M is the point patch X becomes unnecessary, but we live in the real world and it was not recorded as a merge of X into the mainline):

                 .---X---Y---Z
                /
               /
              /
      ---o---A---o---.....---M---...---o---B

and X-Y-Z _is_ what you would maintain and keep tweaking. You can publish Z and people who would want to "apply" the series can cleanly apply X-Y-Z (or merge Z if they are git users).

But people who would want to "apply" the series to codebase newer than point M would individually need to resolve conflicts or know X is unneeded for them. To alleviate this, you would publish _another_ commit:

                 .---X---Y---Z
                /             \
               /               Z'
              /               /
      ---o---A---o---.....---M---...---o---B

That is, you merge Z to newer mainline for them to create Z', and:

 * publish Z' for git users --- they can merge this to their
   codebase that is newer than M and they do not have to resolve
   conflicts you needed to resolve, arising from the overlap
   between X and M, when you created Z'.
 * publish diff between M-Z', for non git users who would want
   to apply it with "patch".

You suggested that you would keep rebasing X--Y--Z while improving the long living patch series. You would recreate Z' whenever the series is updated (and rerere will hopefully help you re-resolve the conflicts between X and M automatically).

Previous: Matt McCutchenNext: Matt McCutchen
Message 2 of 3 in “How to structure a project distributed with varyingly interdependent feature branches?”
  1. Matt McCutchenDec 31, 2007
  2. Junio C HamanoJan 2, 2008
  3. Matt McCutchenJan 15, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.