git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Avery Pennarun <apenwarr@gmail.com>
To: Jay Soffian <jaysoffian@gmail.com>
Cc: git <git@vger.kernel.org>
Subject: Re: Dealing with an upstream cherry-picked branch
Date: Mon, 15 Mar 2010 13:46:17 -0500	[thread overview]
Message-ID: <32541b131003151146qeb6b15bqa9317c6d56443e8e@mail.gmail.com> (raw)
In-Reply-To: <76718491003142117w4fd10449j51deef27548c4d2e@mail.gmail.com>

On Sun, Mar 14, 2010 at 11:17 PM, Jay Soffian <jaysoffian@gmail.com> wrote:
> The question is how to best integrate the fixes on upstream-a into
> local-master, w/o causing a headache when upstream cuts the next
> tentative release branch, at which point upstrea-master will again
> need to be merged into local-master (and that will also have other
> local development). Here are two options I've considered:

You forgot option 0: tell upstream not to do that.

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.

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.

> 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.

> (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

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.

Have fun,

Avery

  reply	other threads:[~2010-03-15 18:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-15  4:17 Dealing with an upstream cherry-picked branch Jay Soffian
2010-03-15 18:46 ` Avery Pennarun [this message]
2010-03-15 21:07   ` Jay Soffian
2010-03-15 23:39     ` Avery Pennarun
2010-03-15 21:30 ` Junio C Hamano
2010-03-16 17:38   ` Jay Soffian
2010-03-16 22:56     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=32541b131003151146qeb6b15bqa9317c6d56443e8e@mail.gmail.com \
    --to=apenwarr@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jaysoffian@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).