{"thread":{"id":"66251","subject":"[PATCH 1/2] environment: move grafts_keep_true_parents into repo_config_values","startedAt":"2026-09-02T11:31:16Z","lastAt":"2026-09-02T11:31:18Z","messageCount":2,"participants":["Yuvraj Singh Chauhan"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"551743","messageId":"20260902113109.686014-1-ysinghcin@gmail.com","threadId":"66251","inReplyTo":null,"subject":"[PATCH 1/2] environment: move grafts_keep_true_parents into repo_config_values","fromName":"Yuvraj Singh Chauhan","fromEmail":"ysinghcin@gmail.com","sentAt":"2026-09-02T11:30:45Z","receivedAt":"2026-09-02T11:31:16Z","isPatch":true,"body":"Move the global 'grafts_keep_true_parents' configuration variable into\nthe repository-specific 'repo_config_values' struct.\n\nIntroduce the getter function 'repo_grafts_keep_true_parents(repo)'\nwhich checks whether 'repo->initialized' is set, falling back to 0\nwhen uninitialized.\n\nUpdate call sites in commit.c to use 'repo_grafts_keep_true_parents(r)'\nwith the existing repository context 'r'. In builtin/pack-objects.c,\nbind the '--keep-true-parents' option directly to\n'cfg->grafts_keep_true_parents'.\n\nWhen accessing 'repo_config_values' in cmd_pack_objects, use a NULL\nguard 'repo ? repo : the_repository'. This ensures that invocations\nwithout a repository context (e.g. 'git pack-objects -h' outside a repo)\ndo not dereference a NULL pointer.\n\nSigned-off-by: Yuvraj Singh Chauhan <ysinghcin@gmail.com>\n---\n builtin/pack-objects.c | 6 +++---\n commit.c               | 2 +-\n environment.c          | 9 ++++++++-\n environment.h          | 5 +++--\n 4 files changed, 15 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 65c2ad9a86..0d213dead1 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -5120,7 +5120,7 @@ static int parse_stdin_packs_mode(const struct option *opt, const char *arg,\n int cmd_pack_objects(int argc,\n \t\t     const char **argv,\n \t\t     const char *prefix,\n-\t\t     struct repository *repo UNUSED)\n+\t\t     struct repository *repo)\n {\n \tint use_internal_rev_list = 0;\n \tint all_progress_implied = 0;\n@@ -5131,7 +5131,7 @@ int cmd_pack_objects(int argc,\n \tstruct string_list keep_pack_list = STRING_LIST_INIT_NODUP;\n \tstruct list_objects_filter_options filter_options =\n \t\tLIST_OBJECTS_FILTER_INIT;\n-\tstruct repo_config_values *cfg = repo_config_values(the_repository);\n+\tstruct repo_config_values *cfg = repo_config_values(repo ? repo : the_repository);\n \n \tstruct option pack_objects_options[] = {\n \t\tOPT_CALLBACK_F('q', \"quiet\", &progress, NULL,\n@@ -5215,7 +5215,7 @@ int cmd_pack_objects(int argc,\n \t\t\t\tN_(\"ignore this pack\")),\n \t\tOPT_INTEGER(0, \"compression\", &cfg->pack_compression_level,\n \t\t\t    N_(\"pack compression level\")),\n-\t\tOPT_BOOL(0, \"keep-true-parents\", &grafts_keep_true_parents,\n+\t\tOPT_BOOL(0, \"keep-true-parents\", &cfg->grafts_keep_true_parents,\n \t\t\t N_(\"do not hide commits by grafts\")),\n \t\tOPT_BOOL(0, \"use-bitmap-index\", &use_bitmap_index,\n \t\t\t N_(\"use a bitmap index if available to speed up counting objects\")),\ndiff --git a/commit.c b/commit.c\nindex ad26f0b40a..5a7ae0696c 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -566,7 +566,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b\n \t\t * The clone is shallow if nr_parent < 0, and we must\n \t\t * not traverse its real parents even when we unhide them.\n \t\t */\n-\t\tif (graft && (graft->nr_parent < 0 || !grafts_keep_true_parents))\n+\t\tif (graft && (graft->nr_parent < 0 || !repo_grafts_keep_true_parents(r)))\n \t\t\tcontinue;\n \t\tnew_parent = lookup_commit(r, &parent);\n \t\tif (!new_parent)\ndiff --git a/environment.c b/environment.c\nindex 76ee65e62b..53e8ab1255 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -56,7 +56,6 @@ char *check_roundtrip_encoding;\n #ifndef OBJECT_CREATION_MODE\n #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS\n #endif\n-int grafts_keep_true_parents;\n unsigned long pack_size_limit_cfg;\n \n #ifndef PROTECT_HFS_DEFAULT\n@@ -152,6 +151,13 @@ int repo_has_symlinks(struct repository *repo)\n \t\t: platform_has_symlinks();\n }\n \n+int repo_grafts_keep_true_parents(struct repository *repo)\n+{\n+\treturn repo->initialized\n+\t\t? repo_config_values(repo)->grafts_keep_true_parents\n+\t\t: 0;\n+}\n+\n const char *repo_excludes_file(struct repository *repo)\n {\n \tstruct repo_config_values *cfg = repo_config_values(repo);\n@@ -770,6 +776,7 @@ void repo_config_values_init(struct repo_config_values *cfg)\n \tcfg->core_sparse_checkout_cone = 0;\n \tcfg->sparse_expect_files_outside_of_patterns = 0;\n \tcfg->warn_on_object_refname_ambiguity = 1;\n+\tcfg->grafts_keep_true_parents = 0;\n }\n \n void repo_config_values_clear(struct repo_config_values *cfg)\ndiff --git a/environment.h b/environment.h\nindex e7ec5b0437..b9f31a0aef 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -139,6 +139,7 @@ struct repo_config_values {\n \tint ignore_case;\n \tint trust_executable_bit;\n \tint has_symlinks;\n+\tint grafts_keep_true_parents;\n \n \t/* section \"sparse\" config values */\n \tint sparse_expect_files_outside_of_patterns;\n@@ -193,6 +194,8 @@ int repo_trust_executable_bit(struct repository *repo);\n \n int repo_has_symlinks(struct repository *repo);\n \n+int repo_grafts_keep_true_parents(struct repository *repo);\n+\n const char *repo_excludes_file(struct repository *repo);\n \n void repo_config_values_init(struct repo_config_values *cfg);\n@@ -235,8 +238,6 @@ extern int minimum_abbrev, default_abbrev;\n extern int assume_unchanged;\n extern unsigned long pack_size_limit_cfg;\n \n-extern int grafts_keep_true_parents;\n-\n const char *get_log_output_encoding(void);\n const char *get_commit_output_encoding(void);\n \n-- \n2.43.0\n"},{"id":"551744","messageId":"20260902113109.686014-2-ysinghcin@gmail.com","threadId":"66251","inReplyTo":"20260902113109.686014-1-ysinghcin@gmail.com","subject":"[PATCH 2/2] pack-objects: add tests for keep-true-parents","fromName":"Yuvraj Singh Chauhan","fromEmail":"ysinghcin@gmail.com","sentAt":"2026-09-02T11:30:46Z","receivedAt":"2026-09-02T11:31:18Z","isPatch":true,"body":"Add tests for '--keep-true-parents' to\n't5300-pack-object.sh' to ensure that:\n1. Grafts hide parents by default during pack-objects.\n2. The flag successfully reveals grafted-over parents.\n3. It safely skips shallow commits (where 'nr_parent < 0')\n   without causing failures or undefined behavior.\n\nSigned-off-by: Yuvraj Singh Chauhan <ysinghcin@gmail.com>\n---\n t/t5300-pack-object.sh | 55 ++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 55 insertions(+)\n\ndiff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh\nindex aac139e6a0..62b29c7e05 100755\n--- a/t/t5300-pack-object.sh\n+++ b/t/t5300-pack-object.sh\n@@ -766,4 +766,59 @@ test_expect_success '--path-walk thin pack' '\n \tgit -C server index-pack --fix-thin --stdin <out.pack\n '\n \n+test_expect_success 'setup graft and test repos' '\n+\tgit init graft-test &&\n+\t(\n+\t\tcd graft-test &&\n+\t\tgit commit --allow-empty -m \"root\" &&\n+\t\tgit commit --allow-empty -m \"commit_A\" &&\n+\t\tA=$(git rev-parse HEAD) &&\n+\t\tgit commit --allow-empty -m \"commit_B\" &&\n+\t\tB=$(git rev-parse HEAD) &&\n+\t\tgit commit --allow-empty -m \"commit_C\" &&\n+\t\tC=$(git rev-parse HEAD) &&\n+\t\tmkdir -p .git/info &&\n+\t\techo \"$C $A\" >.git/info/grafts &&\n+\t\techo \"$C\" >../C_sha &&\n+\t\techo \"$B\" >../B_sha &&\n+\t\techo \"$A\" >../A_sha\n+\t)\n+'\n+\n+test_expect_success 'pack-objects without --keep-true-parents respects graft (hides real parent)' '\n+\tC=$(cat C_sha) &&\n+\tB=$(cat B_sha) &&\n+\techo \"$C\" | git -C graft-test pack-objects --revs --stdout >test-no-ktp.pack &&\n+\tgit init unpack-test &&\n+\tgit -C unpack-test index-pack --stdin <test-no-ktp.pack &&\n+\tgit -C unpack-test cat-file -p \"$C\" >/dev/null &&\n+\t! git -C unpack-test cat-file -p \"$B\" >/dev/null 2>&1\n+'\n+\n+test_expect_success 'pack-objects --keep-true-parents ignores graft (exposes real parent)' '\n+\tC=$(cat C_sha) &&\n+\tB=$(cat B_sha) &&\n+\techo \"$C\" | git -C graft-test pack-objects --keep-true-parents --revs --stdout >test-ktp.pack &&\n+\tgit init unpack-test-ktp &&\n+\tgit -C unpack-test-ktp index-pack --stdin <test-ktp.pack &&\n+\tgit -C unpack-test-ktp cat-file -p \"$C\" >/dev/null &&\n+\tgit -C unpack-test-ktp cat-file -p \"$B\" >/dev/null\n+'\n+\n+test_expect_success 'pack-objects --keep-true-parents is safe with shallow commits' '\n+\tgit init shallow-src &&\n+\t(\n+\t\tcd shallow-src &&\n+\t\tgit commit --allow-empty -m \"commit_A\" &&\n+\t\tgit commit --allow-empty -m \"commit_B\" &&\n+\t\tgit commit --allow-empty -m \"commit_C\"\n+\t) &&\n+\tgit clone --no-local --depth=1 shallow-src shallow-clone &&\n+\tSHALLOW_TIP=$(git -C shallow-clone rev-parse HEAD) &&\n+\techo \"$SHALLOW_TIP\" | git -C shallow-clone pack-objects --keep-true-parents --revs --stdout >shallow-ktp.pack &&\n+\tgit init shallow-unpack &&\n+\tgit -C shallow-unpack index-pack --stdin <shallow-ktp.pack &&\n+\tgit -C shallow-unpack cat-file -p \"$SHALLOW_TIP\" >/dev/null\n+'\n+\n test_done\n-- \n2.43.0\n"}]}