<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/log-tree.c, branch v2.33.6</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=v2.33.6</id>
<link rel='self' href='https://git.shady.money/git/atom?h=v2.33.6'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2021-07-14T17:11:02Z</updated>
<entry>
<title>load_ref_decorations(): fix decoration with tags</title>
<updated>2021-07-14T17:11:02Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2021-07-14T16:31:36Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=d1ed8d6cee57c91ec770a8a183ed40c3ec867ac1'/>
<id>urn:sha1:d1ed8d6cee57c91ec770a8a183ed40c3ec867ac1</id>
<content type='text'>
Commit 88473c8bae ("load_ref_decorations(): avoid parsing non-tag
objects", 2021-06-22) introduced a shortcut to `add_ref_decoration()`:
Rather than calling `parse_object()`, we go for `oid_object_info()` and
then `lookup_object_by_type()` using the type just discovered. As
detailed in the commit message, this provides a significant time saving.

Unfortunately, it also changes the behavior: We lose all annotated tags
from the decoration.

The reason this happens is in the loop where we try to peel the tags, we
won't necessarily have parsed that first object. If we haven't, its
`tagged` field will be NULL, so we won't actually add a decoration for
the pointed-to object.

Make sure to parse the tag object at the top of the peeling loop. This
effectively restores the pre-88473c8bae parsing -- but only of tags,
allowing us to keep most of the possible speedup from 88473c8bae.

On my big ~220k ref test case (where it's mostly non-tags), the
timings [using "git log -1 --decorate"] are:

  - before either patch: 2.945s
  - with my broken patch: 0.707s
  - with [this patch]: 0.788s

The simplest way to do this is to just conditionally parse before the
loop:

  if (obj-&gt;type == OBJ_TAG)
          parse_object(&amp;obj-&gt;oid);

But we can observe that our tag-peeling loop needs to peel already, to
examine recursive tags-of-tags. So instead of introducing a new call to
parse_object(), we can simply move the parsing higher in the loop:
instead of parsing the new object before we loop, parse each tag object
before we look at its "tagged" field.

This has another beneficial side effect: if a tag points at a commit (or
other non-tag type), we do not bother to parse the commit at all now.
And we know it is a commit without calling oid_object_info(), because
parsing the surrounding tag object will have created the correct in-core
object based on the "type" field of the tag.

Our test coverage for --decorate was obviously not good, since we missed
this quite-basic regression. The new tests covers an annotated tag
(showing the fix), but also that we correctly show annotations for
lightweight tags and double-annotated tag-of-tags.

Reported-by: Martin Ågren &lt;martin.agren@gmail.com&gt;
Helped-by: Martin Ågren &lt;martin.agren@gmail.com&gt;
Signed-off-by: Martin Ågren &lt;martin.agren@gmail.com&gt;
Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Reviewed-by: Martin Ågren &lt;martin.agren@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>add_ref_decoration(): rename s/type/deco_type/</title>
<updated>2021-06-29T03:32:32Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2021-06-22T17:09:26Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=6afb265b9675b1e6061f53a323825db239f6e0fa'/>
<id>urn:sha1:6afb265b9675b1e6061f53a323825db239f6e0fa</id>
<content type='text'>
Now that we have two types (a decoration type and an object type) in the
function, let's give them both unique names to avoid accidentally using
one instead of the other.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>load_ref_decorations(): avoid parsing non-tag objects</title>
<updated>2021-06-29T03:31:40Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2021-06-22T17:06:48Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=88473c8baeefafe6b95ab0f62eb2f12e2b098ac7'/>
<id>urn:sha1:88473c8baeefafe6b95ab0f62eb2f12e2b098ac7</id>
<content type='text'>
When we load the ref decorations, we parse the object pointed to by each
ref in order to get a "struct object". This is unnecessarily expensive;
we really only need the object struct, and don't even look at the parsed
contents. The exception is tags, which we do need to peel.

We can improve this by looking up the object type first (which is much
cheaper), and skipping the parse entirely for non-tags. This increases
the work slightly for annotated tags (which now do a type lookup _and_ a
parse), but decreases it a lot for other types. On balance, this seems
to be a good tradeoff.

In my git.git clone, with ~2k refs, most of which are branches, the time
to run "git log -1 --decorate" drops from 34ms to 11ms. Even on my
linux.git clone, which contains mostly tags and only a handful of
branches, the time drops from 30ms to 19ms. And on a more extreme
real-world case with ~220k refs, mostly non-tags, the time drops from
2.6s to 650ms.

That command is a lop-sided example, of course, because it does as
little non-loading work as possible. But it does show the absolute time
improvement. Even in something like a full "git log --decorate" on that
extreme repo, we'd still be saving 2s of CPU time.

Ideally we could push this even further, and avoid parsing even tags, by
relying on the packed-refs "peel" optimization (which we could do by
calling peel_iterated_oid() instead of peeling manually). But we can't
do that here. The packed-refs file only stores the bottom-layer of the
peel (so in a "tag-&gt;tag-&gt;commit" chain, it stores only the commit as the
peel result).  But the decoration code wants to peel the layers
individually, annotating the middle layers of the chain.

If the packed-refs file ever learns to store all of the peeled layers,
then we could switch to it. Or even if it stored a flag to indicate the
peel was not multi-layer (because most of them aren't), then we could
use it most of the time and fall back to a manual peel for the rare
cases.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>hash: provide per-algorithm null OIDs</title>
<updated>2021-04-27T07:31:39Z</updated>
<author>
<name>brian m. carlson</name>
<email>sandals@crustytoothpaste.net</email>
</author>
<published>2021-04-26T01:02:56Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=14228447c9ce664a4e9c31ba10344ec5e4ea4ba5'/>
<id>urn:sha1:14228447c9ce664a4e9c31ba10344ec5e4ea4ba5</id>
<content type='text'>
Up until recently, object IDs did not have an algorithm member, only a
hash.  Consequently, it was possible to share one null (all-zeros)
object ID among all hash algorithms.  Now that we're going to be
handling objects from multiple hash algorithms, it's important to make
sure that all object IDs have a correct algorithm field.

Introduce a per-algorithm null OID, and add it to struct hash_algo.
Introduce a wrapper function as well, and use it everywhere we used to
use the null_oid constant.

Signed-off-by: brian m. carlson &lt;sandals@crustytoothpaste.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>format-patch: allow a non-integral version numbers</title>
<updated>2021-03-23T19:49:47Z</updated>
<author>
<name>ZheNing Hu</name>
<email>adlternative@gmail.com</email>
</author>
<published>2021-03-23T11:12:25Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=db91988aa102d48af1c1203d8cc2d01240df7365'/>
<id>urn:sha1:db91988aa102d48af1c1203d8cc2d01240df7365</id>
<content type='text'>
The `-v&lt;n&gt;` option of `format-patch` can give nothing but an
integral iteration number to patches in a series.  Some people,
however, prefer to mark a new iteration with only a small fixup
with a non integral iteration number (e.g. an "oops, that was
wrong" fix-up patch for v4 iteration may be labeled as "v4.1").

Allow `format-patch` to take such a non-integral iteration
number.

`&lt;n&gt;` can be any string, such as '3.1' or '4rev2'. In the case
where it is a non-integral value, the "Range-diff" and "Interdiff"
headers will not include the previous version.

Signed-off-by: ZheNing Hu &lt;adlternative@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'ab/diff-deferred-free'</title>
<updated>2021-02-23T00:12:43Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2021-02-23T00:12:43Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=45df6c4d756df25d04f82f4803923baaf0c12a33'/>
<id>urn:sha1:45df6c4d756df25d04f82f4803923baaf0c12a33</id>
<content type='text'>
A small memleak in "diff -I&lt;regexp&gt;" has been corrected.

* ab/diff-deferred-free:
  diff: plug memory leak from regcomp() on {log,diff} -I
  diff: add an API for deferred freeing
</content>
</entry>
<entry>
<title>Merge branch 'bc/signed-objects-with-both-hashes'</title>
<updated>2021-02-23T00:12:42Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2021-02-23T00:12:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=15af6e6fee54632358798bef548d89dd3764805d'/>
<id>urn:sha1:15af6e6fee54632358798bef548d89dd3764805d</id>
<content type='text'>
Signed commits and tags now allow verification of objects, whose
two object names (one in SHA-1, the other in SHA-256) are both
signed.

* bc/signed-objects-with-both-hashes:
  gpg-interface: remove other signature headers before verifying
  ref-filter: hoist signature parsing
  commit: allow parsing arbitrary buffers with headers
  gpg-interface: improve interface for parsing tags
  commit: ignore additional signatures when parsing signed commits
  ref-filter: switch some uses of unsigned long to size_t
</content>
</entry>
<entry>
<title>Merge branch 'js/range-diff-one-side-only'</title>
<updated>2021-02-18T01:21:41Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2021-02-18T01:21:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=dadc91ff0c15b655070ad334a27a734e91635bd5'/>
<id>urn:sha1:dadc91ff0c15b655070ad334a27a734e91635bd5</id>
<content type='text'>
The "git range-diff" command learned "--(left|right)-only" option
to show only one side of the compared range.

* js/range-diff-one-side-only:
  range-diff: offer --left-only/--right-only options
  range-diff: move the diffopt initialization down one layer
  range-diff: combine all options in a single data structure
  range-diff: simplify code spawning `git log`
  range-diff: libify the read_patches() function again
  range-diff: avoid leaking memory in two error code paths
</content>
</entry>
<entry>
<title>diff: add an API for deferred freeing</title>
<updated>2021-02-11T17:21:05Z</updated>
<author>
<name>Ævar Arnfjörð Bjarmason</name>
<email>avarab@gmail.com</email>
</author>
<published>2021-02-11T10:45:34Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e900d494dcff7bb9033865e61b452128ff232481'/>
<id>urn:sha1:e900d494dcff7bb9033865e61b452128ff232481</id>
<content type='text'>
Add a diff_free() function to free anything we may have allocated in
the "diff_options" struct, and the ability to make calling it a noop
by setting "no_free" in "diff_options".

This is required because when e.g. "git diff" is run we'll allocate
things in that struct, use the diff machinery once, and then exit.

But if we run e.g. "git log -p" we're going to re-use what we
allocated across multiple diff_flush() calls, and only want to free
things at the end.

We've thus ended up with features like the recently added "diff -I"[1]
where we'll leak memory. As it turns out it could have simply used the
pattern established in 6ea57703f6 (log: prepare log/log-tree to reuse
the diffopt.close_file attribute, 2016-06-22).

Manually adding more such flags to things log_tree_commit() every time
we need to allocate something would be tedious. Let's instead move
that fclose() code it to a new diff_free(), in anticipation of freeing
more things in that function in follow-up commits.

Some functions such as log_tree_commit() need an idiom of optionally
retaining a previous "no_free", as they may either free the memory
themselves, or their caller may do so. I'm keeping that idiom in
log_show_early() for good measure, even though I don't think it's
currently called in this manner. It also gets passed an existing
"struct rev_info", so future callers may want to set the "no_free"
flag.

This change is a bit hard to read because while the freeing pattern
we're introducing isn't unusual, the "file" member is a special
snowflake. We usually don't want to fclose() it. This is because
"file" is usually stdout, in which case we don't want to fclose()
it. We only want to opt-in to closing it when we e.g. open a file on
the filesystem. Thus the opt-in "close_file" flag.

So the API in general just needs a "no_free" flag to defer freeing,
but the "file" member still needs its "close_file" flag. This is made
more confusing because while refactoring this code we could replace
some "close_file=0" with "no_free=1", whereas others need to set both
flags.

This is because there were some cases where an existing "close_file=0"
meant "let's defer deallocation", and others where it meant "we don't
want to close this file handle at all".

1. 296d4a94e7 (diff: add -I&lt;regex&gt; that ignores matching changes,
   2020-10-20)

Signed-off-by: Ævar Arnfjörð Bjarmason &lt;avarab@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>gpg-interface: improve interface for parsing tags</title>
<updated>2021-02-11T07:35:42Z</updated>
<author>
<name>brian m. carlson</name>
<email>sandals@crustytoothpaste.net</email>
</author>
<published>2021-02-11T02:08:03Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=482c119186987110bfccf705a5ac75d399b08766'/>
<id>urn:sha1:482c119186987110bfccf705a5ac75d399b08766</id>
<content type='text'>
We have a function which parses a buffer with a signature at the end,
parse_signature, and this function is used for signed tags.  However,
we'll need to store values for multiple algorithms, and we'll do this by
using a header for the non-default algorithm.

Adjust the parse_signature interface to store the parsed data in two
strbufs and turn the existing function into parse_signed_buffer.  The
latter is still used in places where we know we always have a signed
buffer, such as push certs.

Adjust all the callers to deal with this new interface.

Signed-off-by: brian m. carlson &lt;sandals@crustytoothpaste.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
