From: kirr@navytux•spb.ru
To: Junio C Hamano <gitster@pobox•com>
Cc: kirr@mns•spb.ru, git@vger•kernel.org
Subject: Re: What's cooking in git.git (Mar 2014, #04; Thu, 20)
Date: Fri, 21 Mar 2014 21:20:46 +0400 [thread overview]
Message-ID: <20140321172046.GA6157@mini.zxlink> (raw)
In-Reply-To: <xmqqsiqcwlh4.fsf@gitster.dls.corp.google.com>
Junio,
On Thu, Mar 20, 2014 at 03:31:35PM -0700, Junio C Hamano wrote:
> Junio C Hamano <gitster@pobox•com> writes:
>
> > Quite a few topics are still outside 'pu' and I suspect some of the
> > larger ones deserve deeper reviews to help moving them to 'next'.
> > In principle, I'd prefer to keep any large topic that touch core
> > part of the system cooking in 'next' for at least a full cycle, and
> > the sooner they get merged to 'next', the better. Help is greatly
> > appreciated.
> > ...
> > * ks/tree-diff-nway (2014-03-04) 19 commits
> > - combine-diff: speed it up, by using multiparent diff tree-walker directly
> > - tree-diff: rework diff_tree() to generate diffs for multiparent cases as well
> > - Portable alloca for Git
> > - tree-diff: reuse base str(buf) memory on sub-tree recursion
> > - tree-diff: no need to call "full" diff_tree_sha1 from show_path()
> > - tree-diff: rework diff_tree interface to be sha1 based
> > - tree-diff: diff_tree() should now be static
> > - tree-diff: remove special-case diff-emitting code for empty-tree cases
> > - tree-diff: simplify tree_entry_pathcmp
> > - tree-diff: show_path prototype is not needed anymore
> > - tree-diff: rename compare_tree_entry -> tree_entry_pathcmp
> > - tree-diff: move all action-taking code out of compare_tree_entry()
> > - tree-diff: don't assume compare_tree_entry() returns -1,0,1
> > - tree-diff: consolidate code for emitting diffs and recursion in one place
> > - tree-diff: show_tree() is not needed
> > - tree-diff: no need to pass match to skip_uninteresting()
> > - tree-diff: no need to manually verify that there is no mode change for a path
> > - combine-diff: move changed-paths scanning logic into its own function
> > - combine-diff: move show_log_first logic/action out of paths scanning
> >
> > Instead of running N pair-wise diff-trees when inspecting a
> > N-parent merge, find the set of paths that were touched by walking
> > N+1 trees in parallel. These set of paths can then be turned into
> > N pair-wise diff-tree results to be processed through rename
> > detections and such. And N=2 case nicely degenerates to the usual
> > 2-way diff-tree, which is very nice.
>
> So I started re-reading this series, and decided that it might be
> easier to advance the topic piece-by-piece. Will be merging up to
> "consolidate code for emitting diffs" to 'next', after tweaking that
> last commit a bit (see below).
Thanks, yes, I agree - merging it step-by-step is good approach as doing
it all at once requires more one-time effort, which is harder to do, and
otherwise the topic just stays without progress. So yes, let's do it
incrementally.
> Kirill Smelkov <kirr@mns•spb.ru> writes:
>
> > Currently both compare_tree_entry() and show_path() invoke opt diff
>
> s/show_path/show_entry/;
I agree, thanks for noticing.
> > callbacks (opt->add_remove() and opt->change()), and also they both have
> > code which decides whether to recurse into sub-tree, and whether to emit
> > a tree as separate entry if DIFF_OPT_TREE_IN_RECURSIVE is set.
> >
> > I.e. we have code duplication and logic scattered on two places.
> >
> > Let's consolidate it...
> > ...
> > +/* convert path, t1/t2 -> opt->diff_*() callbacks */
> > +static void emit_diff(struct diff_options *opt, struct strbuf *path,
> > + struct tree_desc *t1, struct tree_desc *t2)
> > +{
> > + unsigned int mode1 = t1 ? t1->entry.mode : 0;
> > + unsigned int mode2 = t2 ? t2->entry.mode : 0;
> > +
> > + if (mode1 && mode2) {
> > + opt->change(opt, mode1, mode2, t1->entry.sha1, t2->entry.sha1,
> > + 1, 1, path->buf, 0, 0);
>
> This is not too bad per-se, but it would have been even better if
> this part was done as:
>
> if (t1 && t2) {
> opt->change(opt, t1->entry.mode1, t1->entry.mode2,
> t1->entry.sha1, t2->entry.sha1,
> 1, 1, path->buf, 0, 0);
> }
>
> Then we do not have to rely on an extra convention, "'mode == 0'
> means the entry is missing", in addition to what we already have,
> i.e. "t == NULL means the entry is missing".
I agree, but the reason it is done here so is to prepare for later changes in
"tree-diff: rework diff_tree() to generate diffs for multiparent cases as
well", where modes will be right-available from `struct combine_diff_path` and
would also indicate absent entries:
-/* convert path, t1/t2 -> opt->diff_*() callbacks */
-static void emit_diff(struct diff_options *opt, struct strbuf *path,
- struct tree_desc *t1, struct tree_desc *t2)
+/*
+ * convert path -> opt->diff_*() callbacks
+ *
+ * emits diff to first parent only, and tells diff tree-walker that we are done
+ * with p and it can be freed.
+ */
+static int emit_diff_first_parent_only(struct diff_options *opt, struct combine_diff_path *p)
{
- unsigned int mode1 = t1 ? t1->entry.mode : 0;
- unsigned int mode2 = t2 ? t2->entry.mode : 0;
-
- if (mode1 && mode2) {
- opt->change(opt, mode1, mode2, t1->entry.sha1, t2->entry.sha1,
- 1, 1, path->buf, 0, 0);
+ struct combine_diff_parent *p0 = &p->parent[0];
+ if (p->mode && p0->mode) {
+ opt->change(opt, p0->mode, p->mode, p0->sha1, p->sha1,
+ 1, 1, p->path, 0, 0);
}
else {
const unsigned char *sha1;
unsigned int mode;
int addremove;
- if (mode2) {
+ if (p->mode) {
addremove = '+';
- sha1 = t2->entry.sha1;
- mode = mode2;
+ sha1 = p->sha1;
+ mode = p->mode;
}
else {
addremove = '-';
- sha1 = t1->entry.sha1;
- mode = mode1;
+ sha1 = p0->sha1;
+ mode = p0->mode;
}
- opt->add_remove(opt, addremove, mode, sha1, 1, path->buf, 0);
+ opt->add_remove(opt, addremove, mode, sha1, 1, p->path, 0);
}
...
So this way we are preparing the code for that big interesting patch.
> This is minor, so I will not squash such a change in while merging
> to 'next', but we may want to revisit and fix it up as a follow up
> patch once the series is settled.
I agree that this is minor, and could be reworked in-place, but
squashing it later is not applicable as the code is later removed.
>
> > + }
> > + else {
>
> Style; I've merged these two lines into one, i.e.
>
> } else {
>
> There was another instance of it in show_path(), which I also
> tweaked.
Ok and thanks,
Kirill
prev parent reply other threads:[~2014-03-21 17:23 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-20 21:09 What's cooking in git.git (Mar 2014, #04; Thu, 20) Junio C Hamano
2014-03-20 22:03 ` Torsten Bögershausen
2014-03-20 22:36 ` Junio C Hamano
2014-03-21 20:58 ` Junio C Hamano
2014-03-21 21:33 ` Junio C Hamano
2014-03-20 22:31 ` Junio C Hamano
2014-03-21 17:20 ` kirr [this message]
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=20140321172046.GA6157@mini.zxlink \
--to=kirr@navytux$(echo .)spb.ru \
--cc=git@vger$(echo .)kernel.org \
--cc=gitster@pobox$(echo .)com \
--cc=kirr@mns$(echo .)spb.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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