<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/git.git, branch jk/pack-objects-optim-skimming</title>
<subtitle>github.com: git/git.git
</subtitle>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/'/>
<entry>
<title>pack-objects: compute local/ignore_pack_keep early</title>
<updated>2016-07-26T20:37:09+00:00</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2016-07-25T18:50:31+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=0ecfb53594352e8af5fe2ba5a7da3efca78897cb'/>
<id>0ecfb53594352e8af5fe2ba5a7da3efca78897cb</id>
<content type='text'>
In want_object_in_pack(), we can exit early from our loop if
neither "local" nor "ignore_pack_keep" are set. If they are,
however, we must examine each pack to see if it has the
object and is non-local or has a ".keep".

It's quite common for there to be no non-local or .keep
packs at all, in which case we know ahead of time that
looking further will be pointless. We can pre-compute this
by simply iterating over the list of packs ahead of time,
and dropping the flags if there are no packs that could
match.

Another similar strategy would be to modify the loop in
want_object_in_pack() to notice that we have already found
the object once, and that we are looping only to check for
"local" and "keep" attributes. If a pack has neither of
those, we can skip the call to find_pack_entry_one(), which
is the expensive part of the loop.

This has two advantages:

  - it isn't all-or-nothing; we still get some improvement
    when there's a small number of kept or non-local packs,
    and a large number of non-kept local packs

  - it eliminates any possible race where we add new
    non-local or kept packs after our initial scan. In
    practice, I don't think this race matters; we already
    cache the packed_git information, so somebody who adds a
    new pack or .keep file after we've started will not be
    noticed at all, unless we happen to need to call
    reprepare_packed_git() because a lookup fails.

    In other words, we're already racy, and the race is not
    a big deal (losing the race means we might include an
    object in the pack that would not otherwise be, which is
    an acceptable outcome).

However, it also has a disadvantage: we still loop over the
rest of the packs for each object to check their flags. This
is much less expensive than doing the object lookup, but
still not free. So if we wanted to implement that strategy
to cover the non-all-or-nothing cases, we could do so in
addition to this one (so you get the most speedup in the
all-or-nothing case, and the best we can do in the other
cases). But given that the all-or-nothing case is likely the
most common, it is probably not worth the trouble, and we
can revisit this later if evidence points otherwise.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In want_object_in_pack(), we can exit early from our loop if
neither "local" nor "ignore_pack_keep" are set. If they are,
however, we must examine each pack to see if it has the
object and is non-local or has a ".keep".

It's quite common for there to be no non-local or .keep
packs at all, in which case we know ahead of time that
looking further will be pointless. We can pre-compute this
by simply iterating over the list of packs ahead of time,
and dropping the flags if there are no packs that could
match.

Another similar strategy would be to modify the loop in
want_object_in_pack() to notice that we have already found
the object once, and that we are looping only to check for
"local" and "keep" attributes. If a pack has neither of
those, we can skip the call to find_pack_entry_one(), which
is the expensive part of the loop.

This has two advantages:

  - it isn't all-or-nothing; we still get some improvement
    when there's a small number of kept or non-local packs,
    and a large number of non-kept local packs

  - it eliminates any possible race where we add new
    non-local or kept packs after our initial scan. In
    practice, I don't think this race matters; we already
    cache the packed_git information, so somebody who adds a
    new pack or .keep file after we've started will not be
    noticed at all, unless we happen to need to call
    reprepare_packed_git() because a lookup fails.

    In other words, we're already racy, and the race is not
    a big deal (losing the race means we might include an
    object in the pack that would not otherwise be, which is
    an acceptable outcome).

However, it also has a disadvantage: we still loop over the
rest of the packs for each object to check their flags. This
is much less expensive than doing the object lookup, but
still not free. So if we wanted to implement that strategy
to cover the non-all-or-nothing cases, we could do so in
addition to this one (so you get the most speedup in the
all-or-nothing case, and the best we can do in the other
cases). But given that the all-or-nothing case is likely the
most common, it is probably not worth the trouble, and we
can revisit this later if evidence points otherwise.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pack-objects: break out of want_object loop early</title>
<updated>2016-07-26T20:34:49+00:00</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2016-07-25T18:50:10+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=1ceddba29036f2efd4f243ce30158a3152c39b11'/>
<id>1ceddba29036f2efd4f243ce30158a3152c39b11</id>
<content type='text'>
When pack-objects collects the list of objects to pack
(either from stdin, or via its internal rev-list), it
filters each one through want_object_in_pack().

This function loops through each existing packfile, looking
for the object. When we find it, we mark the pack/offset
combo for later use. However, we can't just return "yes, we
want it" at that point. If --honor-pack-keep is in effect,
we must keep looking to find it in _all_ packs, to make sure
none of them has a .keep. Likewise, if --local is in effect,
we must make sure it is not present in any non-local pack.

As a result, the sum effort of these calls is effectively
O(nr_objects * nr_packs). In an ordinary repository, we have
only a handful of packs, and this doesn't make a big
difference. But in pathological cases, it can slow the
counting phase to a crawl.

This patch notices the case that we have neither "--local"
nor "--honor-pack-keep" in effect and breaks out of the loop
early, after finding the first instance. Note that our worst
case is still "objects * packs" (i.e., we might find each
object in the last pack we look in), but in practice we will
often break out early. On an "average" repo, my git.git with
8 packs, this shows a modest 2% (a few dozen milliseconds)
improvement in the counting-objects phase of "git
pack-objects --all &lt;foo" (hackily instrumented by sticking
exit(0) right after list_objects).

But in a much more pathological case, it makes a bigger
difference. I ran the same command on a real-world example
with ~9 million objects across 1300 packs. The counting time
dropped from 413s to 45s, an improvement of about 89%.

Note that this patch won't do anything by itself for a
normal "git gc", as it uses both --honor-pack-keep and
--local.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When pack-objects collects the list of objects to pack
(either from stdin, or via its internal rev-list), it
filters each one through want_object_in_pack().

This function loops through each existing packfile, looking
for the object. When we find it, we mark the pack/offset
combo for later use. However, we can't just return "yes, we
want it" at that point. If --honor-pack-keep is in effect,
we must keep looking to find it in _all_ packs, to make sure
none of them has a .keep. Likewise, if --local is in effect,
we must make sure it is not present in any non-local pack.

As a result, the sum effort of these calls is effectively
O(nr_objects * nr_packs). In an ordinary repository, we have
only a handful of packs, and this doesn't make a big
difference. But in pathological cases, it can slow the
counting phase to a crawl.

This patch notices the case that we have neither "--local"
nor "--honor-pack-keep" in effect and breaks out of the loop
early, after finding the first instance. Note that our worst
case is still "objects * packs" (i.e., we might find each
object in the last pack we look in), but in practice we will
often break out early. On an "average" repo, my git.git with
8 packs, this shows a modest 2% (a few dozen milliseconds)
improvement in the counting-objects phase of "git
pack-objects --all &lt;foo" (hackily instrumented by sticking
exit(0) right after list_objects).

But in a much more pathological case, it makes a bigger
difference. I ran the same command on a real-world example
with ~9 million objects across 1300 packs. The counting time
dropped from 413s to 45s, an improvement of about 89%.

Note that this patch won't do anything by itself for a
normal "git gc", as it uses both --honor-pack-keep and
--local.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Sixth batch of topics for 2.10</title>
<updated>2016-07-19T20:26:16+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:26:16+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=08bb3500a2a718c3c78b0547c68601cafa7a8fd9'/>
<id>08bb3500a2a718c3c78b0547c68601cafa7a8fd9</id>
<content type='text'>
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'ls/p4-tmp-refs'</title>
<updated>2016-07-19T20:22:24+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:24+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=36cafe44443fcca9eb35399ef0e9bfe289ec5dde'/>
<id>36cafe44443fcca9eb35399ef0e9bfe289ec5dde</id>
<content type='text'>
"git p4" used a location outside $GIT_DIR/refs/ to place its
temporary branches, which has been moved to refs/git-p4-tmp/.

* ls/p4-tmp-refs:
  git-p4: place temporary refs used for branch import under refs/git-p4-tmp
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
"git p4" used a location outside $GIT_DIR/refs/ to place its
temporary branches, which has been moved to refs/git-p4-tmp/.

* ls/p4-tmp-refs:
  git-p4: place temporary refs used for branch import under refs/git-p4-tmp
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'js/am-call-theirs-theirs-in-fallback-3way'</title>
<updated>2016-07-19T20:22:23+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:23+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=3d55eea805c5451afd0a56a4f5aa045ba63083f9'/>
<id>3d55eea805c5451afd0a56a4f5aa045ba63083f9</id>
<content type='text'>
One part of "git am" had an oddball helper function that called
stuff from outside "his" as opposed to calling what we have "ours",
which was not gender-neutral and also inconsistent with the rest of
the system where outside stuff is usuall called "theirs" in
contrast to "ours".

* js/am-call-theirs-theirs-in-fallback-3way:
  am: counteract gender bias
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
One part of "git am" had an oddball helper function that called
stuff from outside "his" as opposed to calling what we have "ours",
which was not gender-neutral and also inconsistent with the rest of
the system where outside stuff is usuall called "theirs" in
contrast to "ours".

* js/am-call-theirs-theirs-in-fallback-3way:
  am: counteract gender bias
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'jk/write-file'</title>
<updated>2016-07-19T20:22:23+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:23+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=2b6456b8089e42232d80672525edbe411ba41549'/>
<id>2b6456b8089e42232d80672525edbe411ba41549</id>
<content type='text'>
General code clean-up around a helper function to write a
single-liner to a file.

* jk/write-file:
  branch: use write_file_buf instead of write_file
  use write_file_buf where applicable
  write_file: add format attribute
  write_file: add pointer+len variant
  write_file: use xopen
  write_file: drop "gently" form
  branch: use non-gentle write_file for branch description
  am: ignore return value of write_file()
  config: fix bogus fd check when setting up default config
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
General code clean-up around a helper function to write a
single-liner to a file.

* jk/write-file:
  branch: use write_file_buf instead of write_file
  use write_file_buf where applicable
  write_file: add format attribute
  write_file: add pointer+len variant
  write_file: use xopen
  write_file: drop "gently" form
  branch: use non-gentle write_file for branch description
  am: ignore return value of write_file()
  config: fix bogus fd check when setting up default config
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'jk/printf-format'</title>
<updated>2016-07-19T20:22:22+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:22+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=96e08010ee5b9d1dbfbcc8561fa69f972a415a38'/>
<id>96e08010ee5b9d1dbfbcc8561fa69f972a415a38</id>
<content type='text'>
Code clean-up to avoid using a variable string that compilers may
feel untrustable as printf-style format given to write_file()
helper function.

* jk/printf-format:
  commit.c: remove print_commit_list()
  avoid using sha1_to_hex output as printf format
  walker: let walker_say take arbitrary formats
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Code clean-up to avoid using a variable string that compilers may
feel untrustable as printf-style format given to write_file()
helper function.

* jk/printf-format:
  commit.c: remove print_commit_list()
  avoid using sha1_to_hex output as printf format
  walker: let walker_say take arbitrary formats
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'rs/help-c-source-with-gitattributes'</title>
<updated>2016-07-19T20:22:21+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:21+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=f5236a776f31de2654bca9001aa74ef9fe0819d8'/>
<id>f5236a776f31de2654bca9001aa74ef9fe0819d8</id>
<content type='text'>
The .c/.h sources are marked as such in our .gitattributes file so
that "git diff -W" and friends would work better.

* rs/help-c-source-with-gitattributes:
  .gitattributes: set file type for C files
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The .c/.h sources are marked as such in our .gitattributes file so
that "git diff -W" and friends would work better.

* rs/help-c-source-with-gitattributes:
  .gitattributes: set file type for C files
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'nd/fetch-ref-summary'</title>
<updated>2016-07-19T20:22:21+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:21+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=566fdaf611f44724120412a43132c07b020fc4f1'/>
<id>566fdaf611f44724120412a43132c07b020fc4f1</id>
<content type='text'>
Improve the look of the way "git fetch" reports what happened to
each ref that was fetched.

* nd/fetch-ref-summary:
  fetch: reduce duplicate in ref update status lines with placeholder
  fetch: align all "remote -&gt; local" output
  fetch: change flag code for displaying tag update and deleted ref
  fetch: refactor ref update status formatting code
  git-fetch.txt: document fetch output
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Improve the look of the way "git fetch" reports what happened to
each ref that was fetched.

* nd/fetch-ref-summary:
  fetch: reduce duplicate in ref update status lines with placeholder
  fetch: align all "remote -&gt; local" output
  fetch: change flag code for displaying tag update and deleted ref
  fetch: refactor ref update status formatting code
  git-fetch.txt: document fetch output
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'jk/test-match-signal'</title>
<updated>2016-07-19T20:22:20+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-07-19T20:22:20+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/git.git/commit/?id=39cadeec0db35a79a2713eceaf998f2745236f0c'/>
<id>39cadeec0db35a79a2713eceaf998f2745236f0c</id>
<content type='text'>
The test framework learned a new helper test_match_signal to
check an exit code from getting killed by an expected signal.

* jk/test-match-signal:
  t/lib-git-daemon: use test_match_signal
  test_must_fail: use test_match_signal
  t0005: use test_match_signal as appropriate
  tests: factor portable signal check out of t0005
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The test framework learned a new helper test_match_signal to
check an exit code from getting killed by an expected signal.

* jk/test-match-signal:
  t/lib-git-daemon: use test_match_signal
  test_must_fail: use test_match_signal
  t0005: use test_match_signal as appropriate
  tests: factor portable signal check out of t0005
</pre>
</div>
</content>
</entry>
</feed>
