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

Re: Dealing with an upstream cherry-picked branch

From
Jay Soffian <jaysoffian@gmail.com>
Date
Mar 15, 2010, 21:07 UTC
Message-ID
<76718491003151407p3cdecf8fx1ddebf19ce304f83@mail.gmail.com>
In-Reply-To
<32541b131003151146qeb6b15bqa9317c6d56443e8e@mail.gmail.com>
On Mon, Mar 15, 2010 at 2:46 PM, Avery Pennarun <apenwarr@gmail.com> wrote:
> You forgot option 0: tell upstream not to do that.

I have no control over upstream and its currently policy absolutely is not going to change.

However, I do have control of my mirror of upstream so...
Show 21 quoted lines
> 0a) Have them do their bugfixes directly in the upstream-a branch,
> then merge sometimes from upstream-a to upstream-master.  Then when
> they cut upstream-b from upstream-master, it should be an easy merge
> for you (since they've already resolved any conflicts between
> upstream-a and upstream-master as they arose over time).
>
> 0b) If they really need to do their bugfixes on upstream-master and
> then cherry-pick them back to upstream-a, have them merge upstream-a
> into upstream-master sometimes *anyway*, resolving any (probably
> trivial) conflicts as they arise.  I say the conflicts should be
> trivial because they're just cherry-picks anyway, so git will mostly
> notice they're identical and ignore them.  This is easy to do a little
> at a time, but gets more complicated if you wait a long time between
> merges.
>
> 0c) Like 0b), only use 'git merge -s ours' to merge from upstream-a
> into upstream-master.  This assumes that upstream-a *never* has a fix
> other than one that is already in upstream-master, so that all
> conflicts necessarily resolve to exactly what's already in
> upstream-master.  This makes it easier for downstream people to merge
> but doesn't actually cost any extra effort.

... I can locally perform the 0b or 0c that they will not do. They never have a fix not already in upstream-master, so I can do 0c. [EDIT: I see this is what you suggest below.] I can also put a sanity check in place to make sure there isn't something unexpected in upstream-a.

I will explore this option.
Show 11 quoted lines
> As for your original suggestions:
>
>> 1) Create a local-a integration branch, merged from upstream-a and
>> local-master. Keep this branch up-to-date by periodically merging
>> local-master and upstream-a:
>
> This will be inconvenient since local-master won't actually be useful;
> if upstream-a contains a critical patch, you won't be able to test
> your changes in local-master until you merge them into local-a.  Thus
> the history of local-master, while "clean", will actually be
> meaningless.
Okay.
Show 13 quoted lines
>> 2) Periodically merge upstream-a into local-master:
>> [...]
>> Then when it is next time to merge upstream-master into local-master either:
>>
>> (a) Backout the upstream-a merges to local-master by reverting the
>> merge commits which introduced them to local-master, then merge
>> upstream-master.
>
> Don't try to revert merge commits; that generally ends in disaster,
> both in terms of your tree's correctness and your ability to
> accurately retrace the history of your branch.  Possibly you can make
> it work, but I don't know anybody who has.  Even if you can, you'll
> still hate yourself in the morning.
Okay, I'll take this as sage advice. :-)
Show 24 quoted lines
>> (b) Just merge upstream-master and carefully deal with all the
>> conflicts. I think this will necessarily be an evil merge.
>
> This is probably not as hard as it sounds, particularly if upstream-a
> is *purely* a subset (in terms of cherry-picks, not in terms of
> history) of upstream-master.  I'd recommend something like this (just
> once when it's time to move to a new release branch):
>
>       git checkout -b mergey upstream-master
>       # take the history of upstream-a but not the content:
>       git merge -s ours upstream-a
>       # assuming local-master is your branch based on upstream-a:
>       git checkout -b local-b local-master
>       # merge the changes from upstream-a to upstream-master into local-b:
>       git merge mergey
>
>> (c) Create a new branch at point Ma and cherry-pick only the local
>> commits from local-master past point Ma. This essentially gives me the
>> clean local-master I would've had if I'd been doing (1) all along.
>
> This will work, but the short form for exactly the same operation is:
>
>        git checkout -b local-b local-master
>        git rebase --onto upstream-master upstream-a

Are you sure that will skip the merges into local-master from upstream-a? I didn't think so and it's not my recollection based on using --onto previously.

Show 14 quoted lines
> It will result in a cleaner history, and importantly, one that
> upstream would probably be willing to merge someday.  You won't have
> any extra cherry-picked commits confusingly merged into your history
> with the original commits.
>
> The disadvantage is that each of your branches will have a disjoint
> history: there will be no branch showing how you got from local-a to
> local-b, since they're actually two totally different things.  In git,
> the ideal case is that if you look at the history of HEAD, you can see
> the *entire* evolution of the product, and using a different
> merge-base for each branch gets in the way of that.
>
> The best option above, IMHO, is my proposed option 0.  But any of the
> others will work.
Thank you.
j.
Previous: Avery PennarunNext: Avery Pennarun
Message 3 of 7 in “Dealing with an upstream cherry-picked branch”
  1. Jay SoffianMar 15, 2010
  2. Avery PennarunMar 15, 2010
  3. Jay SoffianMar 15, 2010
  4. Avery PennarunMar 15, 2010
  5. Junio C HamanoMar 15, 2010
  6. Jay SoffianMar 16, 2010
  7. Junio C HamanoMar 16, 2010

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.