Re: More gitweb queries..
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:41:58
Instead of inflicting a Perl script on us, maybe writing a
textual specification of what you want it to do would help to
clarify your thinking and help us understand the problem you are
trying to describe a lot better. I think Linus publicly stated
he does not do Perl much. I am OK with Perl but I'd rather
answer questions posed in a more reader-friendly manner, rather
than having to guess what the caller is expected to give this
"merge" sub, which you do not document well.
I think I've already asked you something quite similar when you
posted another part of your script for parsing the new diff-raw
format, which I responded with something like: "Without knowing
how this sub is supposed to be called, I think you are stripping
leading colon from a filename if there is one". Anyhow.
Are you trying to implement an Octopus capable N-way merger?
If so, the way I would do would be something like this:
- Accept N parameters, which are heads being merged.
- Sanity check that given heads are commits, and N <= 16.
- Initialize a set, HTM (heads to be merged), to contain all of
the supplied heads.
- Remove one commit from HTM, call it H0.
- Initialize a variable, BASE, with H0. This variable
determines the base of the merge in the commit topology.
- Initialize a variable, T, with tree associated with H0. This
variable holds the "current intermediate merge result" tree.
- While HTM is not empty, loop over the following:
- Remove one commit out of HTM; call it H1.
- MB = git-merge-base BASE H1;
- If MB is either BASE or H1, then you have a fast forward.
Take either BASE or H1 that is not MB and update variable
BASE with it, and update variable T with the tree
associated with it. Continue with the loop (i.e. Perl
"next").
- Run your usual read-tree -m MB T H1 and git-merge-cache; as
Linus explained, if this step ends up involving any
non-trivial merges, you should not do an Octopus. So in
such a case, if HTM is not empty yet, barf (i.e. Perl
"die", or at least "last").
- Do not touch your ${GIT-.git}/HEAD in any way at this
moment.
- Update variable T with git-write-tree of the resolved cache
contents.
- Update varaible BASE with MB.
- Continue with the loop.
- We exited the loop by now. HTM being empty means that T has
the result of N-way merge. Create a single commit object
that has all the commits you have merged as its parents, and
register T as its associated tree. I would imagine recording
that commit in ${GIT-.git}/HEAD is what the user usually
wants but there may be use cases that it may not be
appropriate (I do not do Porcelain so I do not know).