git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Avery Pennarun" <apenwarr@gmail.com>
To: "David Brown" <git@davidb.org>
Cc: "Git Mailing List" <git@vger.kernel.org>
Subject: Re: Help breaking up a large merge.
Date: Thu, 18 Sep 2008 13:40:55 -0400	[thread overview]
Message-ID: <32541b130809181040p4785f877s7502c578e46745d8@mail.gmail.com> (raw)
In-Reply-To: <20080918152154.GA27019@linode.davidb.org>

On Thu, Sep 18, 2008 at 11:21 AM, David Brown <git@davidb.org> wrote:
> The difficulty I'm having is that there are a lot of conflicts
> resulting from the merge (expected), and it would be nice to somehow
> be able to work on a smaller set of these conflicts at a time.
>
> Some of the conflicts are caused by a single change in the other tree.
> This is easy to cherry-pick into my tree, resolve, and then test those
> changes independently.

I've had the same sort of problem at work and I've gone through
several iterations trying to solve a problem.  The short version is
that all the solutions proposed here so far, plus some other ones I
thought of, don't seem to cut down the work for me :)

But here's one that has helped quite a bit, assuming that breaking up
the merge by *files* makes sense.

...

Let's say you have two branches, A and B, derived from a base X.  We
want to merge the branch with fewer changes on top of the branch with
more changes, because it'll be less work to divide up :)  Let's assume
the branch with fewer changes is A.

1) Generate a giant patch file using 'git diff X..A'.  Call the patch P.

2) Using an editor, divide up the patch by files/subdirs based on how
you want to subdivide the work.  Or alternatively, do that with 'git
diff' itself, but beware of accidentally forgetting to ask for some
files if you do it that way.  Call these n individual patches P1..Pn.

3) Create new branches called A1..An, copied directly from X.

4) Apply each patch P1..Pn to each branch A1..An.  (They will all
apply cleanly, because they are all patches against X in the first
place.)

5) Create new branches called B1..Bn, copied directly from *B*.

6) 'git merge' A1 into B1, A2 into B2, and so on.  Resolve the conflicts.

7) Create a new branch, TEST, copied from B.  Do an octopus merge from
B1..Bn.  There will be no conflicts, because those branches all make
mutually exclusive changes, and they're all based on B.  You now have
a combined branch containing A+B, but the history from A is missing.

8) Create a new patch, PFINAL, using 'git diff B..TEST'.  This is the
complete set of changes to turn B into A+B.

9) Checkout B.  'git merge A'; there will be conflicts.  'git checkout
HEAD .' to go back to B's files. Patch in PFINAL, and commit.

Now you have a single merge commit with all the changes, and the
history will be correct.

10) Optional: 'git merge B1..Bn' so that you don't lose the history of
the individual sub-merges (you might want to look at them later or use
them for blame purposes).  There shouldn't be any conflicts, as the
changes in those branches are identical to the changes you just
committed, and git will discard them in the extra merge.

10b) Optional advanced-only trick: amend the main commit so that it
looks like an octopus merge of B, A, and B1..Bn, instead of having a
separate fake merge commit.

Note that this also helps a lot (for me) even if it's just a single
person doing the merge: I like to do the library changes first, get
all the library unit tests passing, then move up to bigger and bigger
components.

Hope this helps.

Have fun,

Avery

  parent reply	other threads:[~2008-09-18 17:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-18 15:21 Help breaking up a large merge David Brown
2008-09-18 15:55 ` Santi Béjar
2008-09-18 16:25   ` David Brown
2008-09-18 16:41 ` Johannes Sixt
2008-09-18 17:40 ` Avery Pennarun [this message]
2008-09-18 17:47   ` David Brown

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=32541b130809181040p4785f877s7502c578e46745d8@mail.gmail.com \
    --to=apenwarr@gmail.com \
    --cc=git@davidb.org \
    --cc=git@vger.kernel.org \
    /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).