提交 c90f9e13 编写于 作者: J Jeff King 提交者: Junio C Hamano

repack: pack objects mentioned by the index

When we pack all objects, we use only the objects reachable
from references and reflogs. This misses any objects which
are reachable from the index, but not yet referenced.

By itself this isn't a big deal; the objects can remain
loose until they are actually used in a commit. However, it
does create a problem when we drop packed but unreachable
objects. We try to optimize out the writing of objects that
we will immediately prune, which means we must follow the
same rules as prune in determining what is reachable. And
prune uses the index for this purpose.

This is rather uncommon in practice, as objects in the index
would not usually have been packed in the first place. But
it could happen in a sequence like:

  1. You make a commit on a branch that references blob X.

  2. You repack, moving X into the pack.

  3. You delete the branch (and its reflog), so that X is
     unreferenced.

  4. You "git add" blob X so that it is now referenced only
     by the index.

  5. You repack again with git-gc. The pack-objects we
     invoke will see that X is neither referenced nor
     recent and not bother loosening it.
Signed-off-by: NJeff King <peff@peff.net>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 edfbb2aa
...@@ -2617,6 +2617,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) ...@@ -2617,6 +2617,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
int all_progress_implied = 0; int all_progress_implied = 0;
struct argv_array rp = ARGV_ARRAY_INIT; struct argv_array rp = ARGV_ARRAY_INIT;
int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0; int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0;
int rev_list_index = 0;
struct option pack_objects_options[] = { struct option pack_objects_options[] = {
OPT_SET_INT('q', "quiet", &progress, OPT_SET_INT('q', "quiet", &progress,
N_("do not show progress meter"), 0), N_("do not show progress meter"), 0),
...@@ -2663,6 +2664,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) ...@@ -2663,6 +2664,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
{ OPTION_SET_INT, 0, "reflog", &rev_list_reflog, NULL, { OPTION_SET_INT, 0, "reflog", &rev_list_reflog, NULL,
N_("include objects referred by reflog entries"), N_("include objects referred by reflog entries"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 }, PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
{ OPTION_SET_INT, 0, "indexed-objects", &rev_list_index, NULL,
N_("include objects referred to by the index"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
OPT_BOOL(0, "stdout", &pack_to_stdout, OPT_BOOL(0, "stdout", &pack_to_stdout,
N_("output pack to stdout")), N_("output pack to stdout")),
OPT_BOOL(0, "include-tag", &include_tag, OPT_BOOL(0, "include-tag", &include_tag,
...@@ -2720,6 +2724,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) ...@@ -2720,6 +2724,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
use_internal_rev_list = 1; use_internal_rev_list = 1;
argv_array_push(&rp, "--reflog"); argv_array_push(&rp, "--reflog");
} }
if (rev_list_index) {
use_internal_rev_list = 1;
argv_array_push(&rp, "--indexed-objects");
}
if (rev_list_unpacked) { if (rev_list_unpacked) {
use_internal_rev_list = 1; use_internal_rev_list = 1;
argv_array_push(&rp, "--unpacked"); argv_array_push(&rp, "--unpacked");
......
...@@ -209,6 +209,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) ...@@ -209,6 +209,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
argv_array_push(&cmd_args, "--non-empty"); argv_array_push(&cmd_args, "--non-empty");
argv_array_push(&cmd_args, "--all"); argv_array_push(&cmd_args, "--all");
argv_array_push(&cmd_args, "--reflog"); argv_array_push(&cmd_args, "--reflog");
argv_array_push(&cmd_args, "--indexed-objects");
if (window) if (window)
argv_array_pushf(&cmd_args, "--window=%s", window); argv_array_pushf(&cmd_args, "--window=%s", window);
if (window_memory) if (window_memory)
......
...@@ -109,4 +109,17 @@ test_expect_success 'do not bother loosening old objects' ' ...@@ -109,4 +109,17 @@ test_expect_success 'do not bother loosening old objects' '
test_must_fail git cat-file -p $obj2 test_must_fail git cat-file -p $obj2
' '
test_expect_success 'keep packed objects found only in index' '
echo my-unique-content >file &&
git add file &&
git commit -m "make it reachable" &&
git gc &&
git reset HEAD^ &&
git reflog expire --expire=now --all &&
git add file &&
test-chmtime =-86400 .git/objects/pack/* &&
git gc --prune=1.hour.ago &&
git cat-file blob :file
'
test_done test_done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册