{"thread":{"id":"18454","subject":"[PATCH 2/2] pack-objects: don't loosen objects available in alternate or kept packs","startedAt":"2009-03-21T22:23:18Z","lastAt":"2009-03-21T22:23:18Z","messageCount":1,"participants":["Brandon Casey"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"108842","messageId":"ee63ef30903211523l1d25db8br9bf644e2f253d32@mail.gmail.com","threadId":"18454","inReplyTo":null,"subject":"[PATCH 2/2] pack-objects: don't loosen objects available in alternate or kept packs","fromName":"Brandon Casey","fromEmail":"drafnel@gmail.com","sentAt":"2009-03-21T22:23:18Z","receivedAt":"2009-03-21T22:23:18Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"If pack-objects is called with the --unpack-unreachable option then it will\nunpack (i.e. loosen) all unreferenced objects from local not-kept packs,\nincluding those that also exist in packs residing in an alternate object\ndatabase or a local kept pack.  The primary(sole?) user of this option is\ngit-repack.  In this case, repack will follow the call to pack-objects with\na call to prune-packed which will delete these newly loosened objects,\nmaking the act of loosening a waste of time.  The unnecessary loosening can\nbe avoided by checking whether an object exists in a non-local pack or a\nlocal kept pack before loosening it.\n\nThis fixes the 'local packed unreachable obs that exist in alternate ODB\nare not loosened' test in t7700.\n---\n builtin-pack-objects.c |   26 +++++++++++++++++++++++++-\n t/t7700-repack.sh      |    2 +-\n 2 files changed, 26 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex 6222f19..3f477c5 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -1944,6 +1944,29 @@ static void\nadd_objects_in_unpacked_packs(struct rev_info *revs)\n \tfree(in_pack.array);\n }\n\n+static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)\n+{\n+\tstatic struct packed_git *last_found = (void *)1;\n+\tstruct packed_git *p;\n+\n+\tp = (last_found == (void *)1) ? packed_git : last_found;\n+\n+\twhile (p) {\n+\t\tif ((!p->pack_local || p->pack_keep) &&\n+\t\t\tfind_pack_entry_one(sha1, p)) {\n+\t\t\tlast_found = p;\n+\t\t\treturn 1;\n+\t\t}\n+\t\tif (p == last_found)\n+\t\t\tp = packed_git;\n+\t\telse\n+\t\t\tp = p->next;\n+\t\tif (p == last_found)\n+\t\t\tp = p->next;\n+\t}\n+\treturn 0;\n+}\n+\n static void loosen_unused_packed_objects(struct rev_info *revs)\n {\n \tstruct packed_git *p;\n@@ -1959,7 +1982,8 @@ static void loosen_unused_packed_objects(struct\nrev_info *revs)\n\n \t\tfor (i = 0; i < p->num_objects; i++) {\n \t\t\tsha1 = nth_packed_object_sha1(p, i);\n-\t\t\tif (!locate_object_entry(sha1))\n+\t\t\tif (!locate_object_entry(sha1) &&\n+\t\t\t\t!has_sha1_pack_kept_or_nonlocal(sha1))\n \t\t\t\tif (force_object_loose(sha1, p->mtime))\n \t\t\t\t\tdie(\"unable to force loose object\");\n \t\t}\ndiff --git a/t/t7700-repack.sh b/t/t7700-repack.sh\nindex 013e488..9ce546e 100755\n--- a/t/t7700-repack.sh\n+++ b/t/t7700-repack.sh\n@@ -113,7 +113,7 @@ test_expect_success 'packed unreachable obs in\nalternate ODB are not loosened' '\n \ttest_must_fail git show $csha1\n '\n\n-test_expect_failure 'local packed unreachable obs that exist in\nalternate ODB are not loosened' '\n+test_expect_success 'local packed unreachable obs that exist in\nalternate ODB are not loosened' '\n \techo `pwd`/alt_objects > .git/objects/info/alternates &&\n \techo \"$csha1\" | git pack-objects --non-empty --all --reflog pack &&\n \trm -f .git/objects/pack/* &&\n-- \n1.6.2.12.g83676\n"}]}