From: Johannes Schindelin <johannes.schinde...@gmx.de>

While it is true that we never add unreachable commits into pack files
intentionally (as `git repack`'s documentation states), we must not
forget that a `git fetch --prune` (or even a `git fetch` when a ref was
force-pushed in the meantime) can make a commit unreachable that was
reachable before.

Therefore it is not safe to assume that a `git repack -adlf` will keep
unreachable commits alone (under the assumption that they had not been
packed in the first place).

This is particularly important to keep in mind when looking at the
`.git/shallow` file: if any commits listed in that file become
unreachable, it is not a problem, but if they go missing, it *is* a
problem. One symptom of this problem is that a deepening fetch may now
fail with

        fatal: error in object: unshallow <commit-hash>

To avoid this problem, let's prune the shallow list in `git repack` when
the `-d` option is passed, unless `-A` is passed, too (which would force
the now-unreachable objects to be turned into loose objects instead of
being deleted).

Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
---
 builtin/repack.c         | 4 ++++
 t/t5537-fetch-shallow.sh | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/builtin/repack.c b/builtin/repack.c
index 6c636e159..45f321b23 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -444,6 +444,10 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
                if (!quiet && isatty(2))
                        opts |= PRUNE_PACKED_VERBOSE;
                prune_packed_objects(opts);
+
+               if (!(pack_everything & LOOSEN_UNREACHABLE) &&
+                   is_repository_shallow())
+                       prune_shallow(0);
        }
 
        if (!no_update_server_info)
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 561485d31..d32ba20f9 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -186,7 +186,7 @@ EOF
        test_cmp expect actual
 '
 
-test_expect_failure '.git/shallow is edited by repack' '
+test_expect_success '.git/shallow is edited by repack' '
        git init shallow-server &&
        test_commit -C shallow-server A &&
        test_commit -C shallow-server B &&
-- 
gitgitgadget

Reply via email to