refs.c: remove extra git_path calls from read_loose_refs
commitf5b2dec1657e09a22f8b2aefa25d022988e3e467
authorJeff King <peff@peff.net>
Mon, 10 Aug 2015 09:36:19 +0000 (10 05:36 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Aug 2015 22:37:13 +0000 (10 15:37 -0700)
treed52fffa732793ecf912cf9f8119a7f8df0a04051
parentb21a5d66055e0a446e61a12d540406f2757f6263
refs.c: remove extra git_path calls from read_loose_refs

In iterating over the loose refs in "refs/foo/", we keep a
running strbuf with "refs/foo/one", "refs/foo/two", etc. But
we also need to access these files in the filesystem, as
".git/refs/foo/one", etc. For this latter purpose, we make a
series of independent calls to git_path(). These are safe
(we only use the result to call stat()), but assigning the
result of git_path is a suspicious pattern that we'd rather
avoid.

This patch keeps a running buffer with ".git/refs/foo/", and
we can just append/reset each directory element as we loop.
This matches how we handle the refnames. It should also be
more efficient, as we do not keep formatting the same
".git/refs/foo" prefix (which can be arbitrarily deep).

Technically we are dropping a call to strbuf_cleanup() on
each generated filename, but that's OK; it wasn't doing
anything, as we are putting in single-level names we read
from the filesystem (so it could not possibly be cleaning up
cruft like "./" in this instance).

A clever reader may also note that the running refname
buffer ("refs/foo/") is actually a subset of the filesystem
path buffer (".git/refs/foo/"). We could get by with one
buffer, indexing the length of $GIT_DIR when we want the
refname. However, having tried this, the resulting code
actually ends up a little more confusing, and the efficiency
improvement is tiny (and almost certainly dwarfed by the
system calls we are making).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs.c