diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index 457a793fa8..717e0a8e41 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -11,7 +11,7 @@ SYNOPSIS [verse] 'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m] [--window=] [--depth=] [--threads=] [--keep-pack=] - [--write-midx] [--full-name-hash] + [--write-midx] [--full-name-hash] [--path-walk] DESCRIPTION ----------- @@ -251,6 +251,19 @@ linkgit:git-multi-pack-index[1]). Write a multi-pack index (see linkgit:git-multi-pack-index[1]) containing the non-redundant packs. +--path-walk:: + This option passes the `--path-walk` option to the underlying + `git pack-options` process (see linkgit:git-pack-objects[1]). + By default, `git pack-objects` walks objects in an order that + presents trees and blobs in an order unrelated to the path they + appear relative to a commit's root tree. The `--path-walk` option + enables a different walking algorithm that organizes trees and + blobs by path. This has the potential to improve delta compression + especially in the presence of filenames that cause collisions in + Git's default name-hash algorithm. Due to changing how the objects + are walked, this option is not compatible with `--delta-islands` + or `--filter`. + CONFIGURATION ------------- diff --git a/builtin/repack.c b/builtin/repack.c index c113eb3785..e2a7d66156 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -40,7 +40,7 @@ static char *packdir, *packtmp_name, *packtmp; static const char *const git_repack_usage[] = { N_("git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=] [--depth=] [--threads=] [--keep-pack=]\n" - "[--write-midx] [--full-name-hash]"), + "[--write-midx] [--full-name-hash] [--path-walk]"), NULL }; @@ -60,6 +60,7 @@ struct pack_objects_args { int quiet; int local; int full_name_hash; + int path_walk; struct list_objects_filter_options filter_options; }; @@ -293,6 +294,8 @@ static void prepare_pack_objects(struct child_process *cmd, strvec_pushf(&cmd->args, "--no-reuse-object"); if (args->full_name_hash) strvec_pushf(&cmd->args, "--full-name-hash"); + if (args->path_walk) + strvec_pushf(&cmd->args, "--path-walk"); if (args->local) strvec_push(&cmd->args, "--local"); if (args->quiet) @@ -1164,6 +1167,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix) N_("pass --no-reuse-object to git-pack-objects")), OPT_BOOL(0, "full-name-hash", &po_args.full_name_hash, N_("(EXPERIMENTAL!) pass --full-name-hash to git-pack-objects")), + OPT_BOOL(0, "path-walk", &po_args.path_walk, + N_("(EXPERIMENTAL!) pass --path-walk to git-pack-objects")), OPT_NEGBIT('n', NULL, &run_update_server_info, N_("do not run git-update-server-info"), 1), OPT__QUIET(&po_args.quiet, N_("be quiet")), diff --git a/t/perf/p5313-pack-objects.sh b/t/perf/p5313-pack-objects.sh index bf6f0d69e4..9903b4a23e 100755 --- a/t/perf/p5313-pack-objects.sh +++ b/t/perf/p5313-pack-objects.sh @@ -36,6 +36,14 @@ test_size 'thin pack size with --full-name-hash' ' test_file_size out ' +test_perf 'thin pack with --path-walk' ' + git pack-objects --thin --stdout --revs --sparse --path-walk out +' + +test_size 'thin pack size with --path-walk' ' + wc -c out ' @@ -52,6 +60,14 @@ test_size 'big pack size with --full-name-hash' ' test_file_size out ' +test_perf 'big pack with --path-walk' ' + git pack-objects --stdout --revs --sparse --path-walk out +' + +test_size 'big pack size with --path-walk' ' + wc -c