{"thread":{"id":"65491","subject":"[PATCH 0/3] Backfill fixes and edges","startedAt":"2026-04-15T23:58:04Z","lastAt":"2026-04-16T14:18:07Z","messageCount":8,"participants":["Elijah Newren via GitGitGadget","Derrick Stolee"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"541701","messageId":"pull.2088.git.1776297482.gitgitgadget@gmail.com","threadId":"65491","inReplyTo":null,"subject":"[PATCH 0/3] Backfill fixes and edges","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-04-15T23:57:59Z","receivedAt":"2026-04-15T23:58:04Z","isPatch":true,"body":"This topic fixes a few minor issues in git backfill (from ds/backfill-revs\nthis cycle), although some might see the third patch as more feature than\nfix, and the first two patches are pretty minor and probably do not merit\nconsideration before the release this late in the cycle.\n\nOverview:\n\n * Patch 1: As a wise man once said, \"Sending arbitrary command-line\n   arguments to setup_revisions() creates an opportunity for behavior you\n   are not expecting. For instance, can users...supply --first-parent? What\n   happens if they add an --author filter?\" ;-) I think these particular\n   cases might work, but other rev-list options don't make sense, so let's\n   error on ones that don't.\n * Patch 2: Making documentation more consistent with other commands\n * Patch 3: Tweak the ranges so we actually prevent on-demand blob\n   downloading better with a new --[no-]include-edges flag.\n\nElijah Newren (3):\n  backfill: reject rev-list arguments that do not make sense\n  backfill: document acceptance of revision-range in more standard\n    manner\n  backfill: default to grabbing edge blobs too\n\n Documentation/git-backfill.adoc |  22 ++++++-\n builtin/backfill.c              |  31 ++++++++-\n t/t5620-backfill.sh             | 110 ++++++++++++++++++++++++++++++--\n 3 files changed, 153 insertions(+), 10 deletions(-)\n\n\nbase-commit: 9f223ef1c026d91c7ac68cc0211bde255dda6199\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2088%2Fnewren%2Fbackfill-fixes-and-edges-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2088/newren/backfill-fixes-and-edges-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/2088\n-- \ngitgitgadget\n"},{"id":"541702","messageId":"6c76f1e862790858297ff9b1debc1a38756b1913.1776297482.git.gitgitgadget@gmail.com","threadId":"65491","inReplyTo":"pull.2088.git.1776297482.gitgitgadget@gmail.com","subject":"[PATCH 1/3] backfill: reject rev-list arguments that do not make sense","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-04-15T23:58:00Z","receivedAt":"2026-04-15T23:58:05Z","isPatch":true,"body":"From: Elijah Newren <newren@gmail.com>\n\nSome rev-list options accepted by setup_revisions() are silently\nignored or actively counterproductive when used with 'git backfill',\nbecause the path-walk API has its own tree-walking logic that bypasses\nthe mechanisms these options rely on:\n\n  * -S/-G (pickaxe) and --diff-filter work by computing per-commit\n    diffs in get_revision_1() and filtering commits whose diffs don't\n    match.  Since backfill's goal is to download all blobs reachable\n    from commits in the range, filtering out commits based on diff\n    content would silently skip blobs -- the opposite of what users\n    want.\n\n  * --follow disables path pruning (revs->prune) and only makes\n    sense for tracking a single file through renames in log output.\n    It has no useful interaction with backfill.\n\n  * -L (line-log) computes line-level diffs to track the evolution\n    of a function or line range.  Like pickaxe, it filters commits\n    based on diff content, which would cause blobs to be silently\n    skipped.\n\n  * --diff-merges controls how merge commit diffs are displayed.\n    The path-walk API walks trees directly and never computes\n    per-commit diffs, so this option would be silently ignored.\n\n  * --filter (object filtering, e.g. --filter=blob:none) is used by\n    the list-objects traversal but is completely ignored by the\n    path-walk API, so it would silently do nothing.\n\nRather than letting users think these options are being honored,\nreject them with a clear error message.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n builtin/backfill.c | 23 +++++++++++++++++++++++\n 1 file changed, 23 insertions(+)\n\ndiff --git a/builtin/backfill.c b/builtin/backfill.c\nindex d794dd842f..a9edddcb7e 100644\n--- a/builtin/backfill.c\n+++ b/builtin/backfill.c\n@@ -78,6 +78,28 @@ static int fill_missing_blobs(const char *path UNUSED,\n \treturn 0;\n }\n \n+static void reject_unsupported_rev_list_options(struct rev_info *revs)\n+{\n+\tif (revs->diffopt.pickaxe)\n+\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n+\t\t    (revs->diffopt.pickaxe_opts & DIFF_PICKAXE_REGEX) ? \"-G\" : \"-S\");\n+\tif (revs->diffopt.filter || revs->diffopt.filter_not)\n+\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n+\t\t    \"--diff-filter\");\n+\tif (revs->diffopt.flags.follow_renames)\n+\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n+\t\t    \"--follow\");\n+\tif (revs->line_level_traverse)\n+\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n+\t\t    \"-L\");\n+\tif (revs->explicit_diff_merges)\n+\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n+\t\t    \"--diff-merges\");\n+\tif (revs->filter.choice)\n+\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n+\t\t    \"--filter\");\n+}\n+\n static int do_backfill(struct backfill_context *ctx)\n {\n \tstruct path_walk_info info = PATH_WALK_INFO_INIT;\n@@ -144,6 +166,7 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit\n \n \tif (argc > 1)\n \t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n+\treject_unsupported_rev_list_options(&ctx.revs);\n \n \trepo_config(repo, git_default_config, NULL);\n \n-- \ngitgitgadget\n\n"},{"id":"541703","messageId":"173831ec92ea712a72f790f3a8eea6643ef7488b.1776297482.git.gitgitgadget@gmail.com","threadId":"65491","inReplyTo":"pull.2088.git.1776297482.gitgitgadget@gmail.com","subject":"[PATCH 2/3] backfill: document acceptance of revision-range in more standard manner","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-04-15T23:58:01Z","receivedAt":"2026-04-15T23:58:07Z","isPatch":true,"body":"From: Elijah Newren <newren@gmail.com>\n\n302aff09223f (backfill: accept revision arguments, 2026-03-26) added\nsupport for passing revision arguments to 'git backfill' but documented\nthem only with a prose sentence:\n\n    You may also specify the commit limiting options from\n    git-rev-list(1).\n\nNo other command that accepts revision arguments documents them this\nway.  Commands like log, shortlog, and replay define a formal\n<revision-range> entry and include rev-list-options.adoc.  Commands like\nbundle, fast-export, and filter-branch, which pass arguments through to\nthe revision machinery without including the full options file, still\ndefine a formal <git-rev-list-args> entry explaining what is accepted.\n\nAdd a formal <revision-range> entry in the synopsis and OPTIONS section,\nfollowing the convention used by other commands, and mention that\ncommit-limiting options from git-rev-list(1) are also accepted.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n Documentation/git-backfill.adoc | 15 ++++++++++++---\n builtin/backfill.c              |  2 +-\n 2 files changed, 13 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-backfill.adoc b/Documentation/git-backfill.adoc\nindex 246ab417c2..bf26d7694f 100644\n--- a/Documentation/git-backfill.adoc\n+++ b/Documentation/git-backfill.adoc\n@@ -9,7 +9,7 @@ git-backfill - Download missing objects in a partial clone\n SYNOPSIS\n --------\n [synopsis]\n-git backfill [--min-batch-size=<n>] [--[no-]sparse]\n+git backfill [--min-batch-size=<n>] [--[no-]sparse] [<revision-range>]\n \n DESCRIPTION\n -----------\n@@ -43,7 +43,7 @@ smaller network calls than downloading the entire repository at clone\n time.\n \n By default, `git backfill` downloads all blobs reachable from the `HEAD`\n-commit. This set can be restricted or expanded using various options.\n+commit. This set can be restricted or expanded using various options below.\n \n THIS COMMAND IS EXPERIMENTAL. ITS BEHAVIOR MAY CHANGE IN THE FUTURE.\n \n@@ -63,7 +63,16 @@ OPTIONS\n \tcurrent sparse-checkout. If the sparse-checkout feature is enabled,\n \tthen `--sparse` is assumed and can be disabled with `--no-sparse`.\n \n-You may also specify the commit limiting options from linkgit:git-rev-list[1].\n+`<revision-range>`::\n+\tBackfill only blobs reachable from commits in the specified\n+\trevision range.  When no _<revision-range>_ is specified, it\n+\tdefaults to `HEAD` (i.e. the whole history leading to the\n+\tcurrent commit).  For a complete list of ways to spell\n+\t_<revision-range>_, see the \"Specifying Ranges\" section of\n+\tlinkgit:gitrevisions[7].\n++\n+You may also use commit-limiting options understood by\n+linkgit:git-rev-list[1] such as `--first-parent`, `--since`, or pathspecs.\n \n SEE ALSO\n --------\ndiff --git a/builtin/backfill.c b/builtin/backfill.c\nindex a9edddcb7e..e934d360fd 100644\n--- a/builtin/backfill.c\n+++ b/builtin/backfill.c\n@@ -26,7 +26,7 @@\n #include \"path-walk.h\"\n \n static const char * const builtin_backfill_usage[] = {\n-\tN_(\"git backfill [--min-batch-size=<n>] [--[no-]sparse]\"),\n+\tN_(\"git backfill [--min-batch-size=<n>] [--[no-]sparse] [<revision-range>]\"),\n \tNULL\n };\n \n-- \ngitgitgadget\n\n"},{"id":"541704","messageId":"607ed38e2a8ae94266b4a3d51610e604cca8df4f.1776297482.git.gitgitgadget@gmail.com","threadId":"65491","inReplyTo":"pull.2088.git.1776297482.gitgitgadget@gmail.com","subject":"[PATCH 3/3] backfill: default to grabbing edge blobs too","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-04-15T23:58:02Z","receivedAt":"2026-04-15T23:58:08Z","isPatch":true,"body":"From: Elijah Newren <newren@gmail.com>\n\nCommit 302aff09223f (backfill: accept revision arguments, 2026-03-26) added\nsupport for accepting revision arguments to backfill.  This allows users\nto do things like\n\n   git backfill --remotes ^v2.3.0\n\nand then run many commands without triggering on-demand downloads of\nblobs.  However, if they have topics based on v2.3.0, they will likely\nstill trigger on-demand downloads.  Consider, for example, the command\n\n   git log -p v2.3.0..topic\n\nThis would still trigger on-demand blob loadings after the backfill\ncommand above, because the commit(s) with A as a parent will need to\ndiff against the blobs in A.  In fact, multiple commands need blobs from\nthe lower boundary of the revision range:\n\n   * git log -p A..B                # After backfill A..B\n   * git replay --onto TARGET A..B  # After backfill TARGET^! A..B\n   * git checkout A && git merge B  # After backfill A...B\n\nAdd an extra --[no-]include-edges flag to allow grabbing blobs from\nedge commits.  Since the point of backfill is to prevent on-demand blob\nloading and these are common commands, default to --include-edges.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n Documentation/git-backfill.adoc |   9 ++-\n builtin/backfill.c              |   8 ++-\n t/t5620-backfill.sh             | 110 ++++++++++++++++++++++++++++++--\n 3 files changed, 119 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-backfill.adoc b/Documentation/git-backfill.adoc\nindex bf26d7694f..c0a3b80615 100644\n--- a/Documentation/git-backfill.adoc\n+++ b/Documentation/git-backfill.adoc\n@@ -9,7 +9,7 @@ git-backfill - Download missing objects in a partial clone\n SYNOPSIS\n --------\n [synopsis]\n-git backfill [--min-batch-size=<n>] [--[no-]sparse] [<revision-range>]\n+git backfill [--min-batch-size=<n>] [--[no-]sparse] [--[no-]include-edges] [<revision-range>]\n \n DESCRIPTION\n -----------\n@@ -63,6 +63,13 @@ OPTIONS\n \tcurrent sparse-checkout. If the sparse-checkout feature is enabled,\n \tthen `--sparse` is assumed and can be disabled with `--no-sparse`.\n \n+`--include-edges`::\n+`--no-include-edges`::\n+\tInclude blobs from boundary commits in the backfill.  Useful in\n+\tpreparation for commands like `git log -p A..B` or `git replay\n+\t--onto TARGET A..B`, where A..B normally excludes A but you need\n+\tthe blobs from A as well.  `--include-edges` is the default.\n+\n `<revision-range>`::\n \tBackfill only blobs reachable from commits in the specified\n \trevision range.  When no _<revision-range>_ is specified, it\ndiff --git a/builtin/backfill.c b/builtin/backfill.c\nindex e934d360fd..7ffab2ea74 100644\n--- a/builtin/backfill.c\n+++ b/builtin/backfill.c\n@@ -26,7 +26,7 @@\n #include \"path-walk.h\"\n \n static const char * const builtin_backfill_usage[] = {\n-\tN_(\"git backfill [--min-batch-size=<n>] [--[no-]sparse] [<revision-range>]\"),\n+\tN_(\"git backfill [--min-batch-size=<n>] [--[no-]sparse] [--[no-]include-edges] [<revision-range>]\"),\n \tNULL\n };\n \n@@ -35,6 +35,7 @@ struct backfill_context {\n \tstruct oid_array current_batch;\n \tsize_t min_batch_size;\n \tint sparse;\n+\tint include_edges;\n \tstruct rev_info revs;\n };\n \n@@ -116,6 +117,8 @@ static int do_backfill(struct backfill_context *ctx)\n \t/* Walk from HEAD if otherwise unspecified. */\n \tif (!ctx->revs.pending.nr)\n \t\tadd_head_to_pending(&ctx->revs);\n+\tif (ctx->include_edges)\n+\t\tctx->revs.edge_hint = 1;\n \n \tinfo.blobs = 1;\n \tinfo.tags = info.commits = info.trees = 0;\n@@ -143,12 +146,15 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit\n \t\t.min_batch_size = 50000,\n \t\t.sparse = -1,\n \t\t.revs = REV_INFO_INIT,\n+\t\t.include_edges = 1,\n \t};\n \tstruct option options[] = {\n \t\tOPT_UNSIGNED(0, \"min-batch-size\", &ctx.min_batch_size,\n \t\t\t     N_(\"Minimum number of objects to request at a time\")),\n \t\tOPT_BOOL(0, \"sparse\", &ctx.sparse,\n \t\t\t N_(\"Restrict the missing objects to the current sparse-checkout\")),\n+\t\tOPT_BOOL(0, \"include-edges\", &ctx.include_edges,\n+\t\t\t N_(\"Include blobs from boundary commits in the backfill\")),\n \t\tOPT_END(),\n \t};\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\ndiff --git a/t/t5620-backfill.sh b/t/t5620-backfill.sh\nindex f3b5e39493..94f35ce190 100755\n--- a/t/t5620-backfill.sh\n+++ b/t/t5620-backfill.sh\n@@ -257,11 +257,12 @@ test_expect_success 'backfill with revision range' '\n \tgit -C backfill-revs rev-list --quiet --objects --missing=print HEAD >missing &&\n \ttest_line_count = 48 missing &&\n \n-\tgit -C backfill-revs backfill HEAD~2..HEAD &&\n+\tGIT_TRACE2_EVENT=\"$(pwd)/backfill-trace\" git -C backfill-revs backfill HEAD~2..HEAD &&\n \n-\t# 30 objects downloaded.\n+\t# 36 objects downloaded, 12 still missing\n+\ttest_trace2_data promisor fetch_count 36 <backfill-trace &&\n \tgit -C backfill-revs rev-list --quiet --objects --missing=print HEAD >missing &&\n-\ttest_line_count = 18 missing\n+\ttest_line_count = 12 missing\n '\n \n test_expect_success 'backfill with revisions over stdin' '\n@@ -279,11 +280,12 @@ test_expect_success 'backfill with revisions over stdin' '\n \t^HEAD~2\n \tEOF\n \n-\tgit -C backfill-revs backfill --stdin <in &&\n+\tGIT_TRACE2_EVENT=\"$(pwd)/backfill-trace\" git -C backfill-revs backfill --stdin <in &&\n \n-\t# 30 objects downloaded.\n+\t# 36 objects downloaded, 12 still missing\n+\ttest_trace2_data promisor fetch_count 36 <backfill-trace &&\n \tgit -C backfill-revs rev-list --quiet --objects --missing=print HEAD >missing &&\n-\ttest_line_count = 18 missing\n+\ttest_line_count = 12 missing\n '\n \n test_expect_success 'backfill with prefix pathspec' '\n@@ -398,6 +400,102 @@ test_expect_success 'backfill with --since' '\n \ttest_line_count = 6 missing\n '\n \n+test_expect_success 'backfill range with include-edges enables fetch-free git-log' '\n+\tgit clone --no-checkout --filter=blob:none\t\\\n+\t\t--single-branch --branch=main\t\t\\\n+\t\t\"file://$(pwd)/srv.bare\" backfill-log &&\n+\n+\t# Backfill the range with default include edges.\n+\tgit -C backfill-log backfill HEAD~2..HEAD &&\n+\n+\t# git log -p needs edge blobs for the \"before\" side of\n+\t# diffs.  With edge inclusion, all needed blobs are local.\n+\tGIT_TRACE2_EVENT=\"$(pwd)/log-trace\" git \\\n+\t\t-C backfill-log log -p HEAD~2..HEAD >log-output &&\n+\n+\t# No promisor fetches should have been needed.\n+\t! grep \"fetch_count\" log-trace\n+'\n+\n+test_expect_success 'backfill range without include edges causes on-demand fetches in git-log' '\n+\tgit clone --no-checkout --filter=blob:none\t\\\n+\t\t--single-branch --branch=main\t\t\\\n+\t\t\"file://$(pwd)/srv.bare\" backfill-log-no-bdy &&\n+\n+\t# Backfill WITHOUT include edges -- file.3 v1 blobs are missing.\n+\tgit -C backfill-log-no-bdy backfill --no-include-edges HEAD~2..HEAD &&\n+\n+\t# git log -p HEAD~2..HEAD computes diff of commit 7 against\n+\t# commit 6.  It needs file.3 v1 (the \"before\" side), which was\n+\t# not backfilled.  This triggers on-demand promisor fetches.\n+\tGIT_TRACE2_EVENT=\"$(pwd)/log-no-bdy-trace\" git \\\n+\t\t-C backfill-log-no-bdy log -p HEAD~2..HEAD >log-output &&\n+\n+\tgrep \"fetch_count\" log-no-bdy-trace\n+'\n+\n+test_expect_success 'backfill range enables fetch-free replay' '\n+\t# Create a repo with a branch to replay.\n+\tgit init replay-src &&\n+\t(\n+\t\tcd replay-src &&\n+\t\tgit config uploadpack.allowfilter 1 &&\n+\t\tgit config uploadpack.allowanysha1inwant 1 &&\n+\t\ttest_commit base &&\n+\t\tgit checkout -b topic &&\n+\t\ttest_commit topic-change &&\n+\t\tgit checkout main &&\n+\t\ttest_commit main-change\n+\t) &&\n+\tgit clone --bare --filter=blob:none \\\n+\t\t\"file://$(pwd)/replay-src\" replay-dest.git &&\n+\n+\t# Backfill the replay range: --onto main, replaying topic~1..topic.\n+\t# For replay, we need TARGET^! plus the range.\n+\tmain_oid=$(git -C replay-dest.git rev-parse main) &&\n+\ttopic_oid=$(git -C replay-dest.git rev-parse topic) &&\n+\tbase_oid=$(git -C replay-dest.git rev-parse topic~1) &&\n+\tgit -C replay-dest.git backfill \\\n+\t\t\"$main_oid^!\" \"$base_oid..$topic_oid\" &&\n+\n+\t# Now replay should complete without any promisor fetches.\n+\tGIT_TRACE2_EVENT=\"$(pwd)/replay-trace\" git -C replay-dest.git \\\n+\t\treplay --onto main topic~1..topic >replay-out &&\n+\n+\t! grep \"fetch_count\" replay-trace\n+'\n+\n+test_expect_success 'backfill enables fetch-free merge' '\n+\t# Create a repo with two branches to merge.\n+\tgit init merge-src &&\n+\t(\n+\t\tcd merge-src &&\n+\t\tgit config uploadpack.allowfilter 1 &&\n+\t\tgit config uploadpack.allowanysha1inwant 1 &&\n+\t\ttest_commit merge-base &&\n+\t\tgit checkout -b side &&\n+\t\ttest_commit side-change &&\n+\t\tgit checkout main &&\n+\t\ttest_commit main-side-change\n+\t) &&\n+\tgit clone --filter=blob:none \\\n+\t\t\"file://$(pwd)/merge-src\" merge-dest &&\n+\n+\t# The clone checked out main, fetching its blobs.\n+\t# Backfill the three endpoint commits needed for merge.\n+\tmain_oid=$(git -C merge-dest rev-parse origin/main) &&\n+\tside_oid=$(git -C merge-dest rev-parse origin/side) &&\n+\tmbase=$(git -C merge-dest merge-base origin/main origin/side) &&\n+\tgit -C merge-dest backfill --no-include-edges \\\n+\t\t\"$main_oid^!\" \"$side_oid^!\" \"$mbase^!\" &&\n+\n+\t# Merge should complete without promisor fetches.\n+\tGIT_TRACE2_EVENT=\"$(pwd)/merge-trace\" git -C merge-dest \\\n+\t\tmerge origin/side -m \"test merge\" &&\n+\n+\t! grep \"fetch_count\" merge-trace\n+'\n+\n . \"$TEST_DIRECTORY\"/lib-httpd.sh\n start_httpd\n \n-- \ngitgitgadget\n"},{"id":"541739","messageId":"9885d0e1-2d0f-4cde-b4ed-671a3ba173e5@gmail.com","threadId":"65491","inReplyTo":"6c76f1e862790858297ff9b1debc1a38756b1913.1776297482.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/3] backfill: reject rev-list arguments that do not make sense","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-04-16T14:11:26Z","receivedAt":"2026-04-16T14:11:31Z","isPatch":true,"body":"On 4/15/2026 7:58 PM, Elijah Newren via GitGitGadget wrote:\n> From: Elijah Newren <newren@gmail.com>\n> \n> Some rev-list options accepted by setup_revisions() are silently\n> ignored or actively counterproductive when used with 'git backfill',\n> because the path-walk API has its own tree-walking logic that bypasses\n> the mechanisms these options rely on:\n> \n>   * -S/-G (pickaxe) and --diff-filter work by computing per-commit\n>     diffs in get_revision_1() and filtering commits whose diffs don't\n>     match.  Since backfill's goal is to download all blobs reachable\n>     from commits in the range, filtering out commits based on diff\n>     content would silently skip blobs -- the opposite of what users\n>     want.\n> \n>   * --follow disables path pruning (revs->prune) and only makes\n>     sense for tracking a single file through renames in log output.\n>     It has no useful interaction with backfill.\n> \n>   * -L (line-log) computes line-level diffs to track the evolution\n>     of a function or line range.  Like pickaxe, it filters commits\n>     based on diff content, which would cause blobs to be silently\n>     skipped.\n\nI think these make a lot of sense, especially because these\ncomputations require downloading missing blobs in order to find\nthe diffs that justify some of the choices of commit filtering.\n \n>   * --diff-merges controls how merge commit diffs are displayed.\n>     The path-walk API walks trees directly and never computes\n>     per-commit diffs, so this option would be silently ignored.\n\nI think there are a few other \"format\" based options that were\nsilently ignored on purpose, because there's no output. Perhaps\nwe should change the use of options like this to a warning instead\nof a failure?\n\n>   * --filter (object filtering, e.g. --filter=blob:none) is used by\n>     the list-objects traversal but is completely ignored by the\n>     path-walk API, so it would silently do nothing.\n\nThis is correct to remove because while it doesn't work with\npath-walk right now, it might in the future. We don't want the\nfilter to mess with the functionality of 'git backfill' that sets\nits own scope for which blobs to download.\n\n> Rather than letting users think these options are being honored,\n> reject them with a clear error message.\n\nI agree that the majority of these should be hard failures. As\nmentioned, some could be soft warnings. That could be an\nadjustment to make in the future, so is not blocking for this\npatch.\n\n> +static void reject_unsupported_rev_list_options(struct rev_info *revs)\n> +{\n> +\tif (revs->diffopt.pickaxe)\n> +\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n> +\t\t    (revs->diffopt.pickaxe_opts & DIFF_PICKAXE_REGEX) ? \"-G\" : \"-S\");\n> +\tif (revs->diffopt.filter || revs->diffopt.filter_not)\n> +\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n> +\t\t    \"--diff-filter\");\n> +\tif (revs->diffopt.flags.follow_renames)\n> +\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n> +\t\t    \"--follow\");\n> +\tif (revs->line_level_traverse)\n> +\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n> +\t\t    \"-L\");\n> +\tif (revs->explicit_diff_merges)\n> +\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n> +\t\t    \"--diff-merges\");\n> +\tif (revs->filter.choice)\n> +\t\tdie(_(\"'%s' cannot be used with 'git backfill'\"),\n> +\t\t    \"--filter\");\n> +}\n> +\n\nMy only nit-pick suggestion is to make the translated string a\nmacro so it can be more obvious that it is repeated exactly.\n\nThanks,\n-Stolee\n\n"},{"id":"541740","messageId":"3c9df807-90b5-49c7-92b7-cb5cf6f4f0df@gmail.com","threadId":"65491","inReplyTo":"173831ec92ea712a72f790f3a8eea6643ef7488b.1776297482.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/3] backfill: document acceptance of revision-range in more standard manner","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-04-16T14:12:14Z","receivedAt":"2026-04-16T14:12:19Z","isPatch":true,"body":"On 4/15/2026 7:58 PM, Elijah Newren via GitGitGadget wrote:\n> From: Elijah Newren <newren@gmail.com>\n> \n> 302aff09223f (backfill: accept revision arguments, 2026-03-26) added\n> support for passing revision arguments to 'git backfill' but documented\n> them only with a prose sentence:\n> \n>     You may also specify the commit limiting options from\n>     git-rev-list(1).\n> \n> No other command that accepts revision arguments documents them this\n> way.  Commands like log, shortlog, and replay define a formal\n> <revision-range> entry and include rev-list-options.adoc.  Commands like\n> bundle, fast-export, and filter-branch, which pass arguments through to\n> the revision machinery without including the full options file, still\n> define a formal <git-rev-list-args> entry explaining what is accepted.\n> \n> Add a formal <revision-range> entry in the synopsis and OPTIONS section,\n> following the convention used by other commands, and mention that\n> commit-limiting options from git-rev-list(1) are also accepted.\n\nThanks for your attention to detail here. I like this version.\n\n-Stolee\n"},{"id":"541741","messageId":"74af0a09-4c1b-4c0a-b5b3-e5044fcd0aaa@gmail.com","threadId":"65491","inReplyTo":"607ed38e2a8ae94266b4a3d51610e604cca8df4f.1776297482.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 3/3] backfill: default to grabbing edge blobs too","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-04-16T14:15:36Z","receivedAt":"2026-04-16T14:15:39Z","isPatch":true,"body":"On 4/15/2026 7:58 PM, Elijah Newren via GitGitGadget wrote:\n> From: Elijah Newren <newren@gmail.com>\n\n> Add an extra --[no-]include-edges flag to allow grabbing blobs from\n> edge commits.  Since the point of backfill is to prevent on-demand blob\n> loading and these are common commands, default to --include-edges.\n\nI like this option and your motivation for including it.\n\n> @@ -116,6 +117,8 @@ static int do_backfill(struct backfill_context *ctx)\n>  \t/* Walk from HEAD if otherwise unspecified. */\n>  \tif (!ctx->revs.pending.nr)\n>  \t\tadd_head_to_pending(&ctx->revs);\n> +\tif (ctx->include_edges)\n> +\t\tctx->revs.edge_hint = 1;\n\nThis would still work if...\n\n>  \t\t.revs = REV_INFO_INIT,\n> +\t\t.include_edges = 1,\n\n...this was initialized to -1 to allow for \"no user option\".\n\nWe don't need this change unless we were deciding to make a\nconfig option that specified a different default. That seems\nlike overkill right now, so this doesn't need a change. Just\nsomething that I like to think about.\n\nI also like how your tests don't just verify the backfill\nbehavior but the ultimate behavior of 'git log' and friends\nafter the fact.\n\nThanks,\n-Stolee\n\n"},{"id":"541742","messageId":"98503549-00ca-46f9-9f48-2a48131cd29c@gmail.com","threadId":"65491","inReplyTo":"pull.2088.git.1776297482.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/3] Backfill fixes and edges","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-04-16T14:18:03Z","receivedAt":"2026-04-16T14:18:07Z","isPatch":true,"body":"On 4/15/2026 7:57 PM, Elijah Newren via GitGitGadget wrote:\n> This topic fixes a few minor issues in git backfill (from ds/backfill-revs\n> this cycle), although some might see the third patch as more feature than\n> fix, and the first two patches are pretty minor and probably do not merit\n> consideration before the release this late in the cycle.\n> \n> Overview:\n> \n>  * Patch 1: As a wise man once said, \"Sending arbitrary command-line\n>    arguments to setup_revisions() creates an opportunity for behavior you\n>    are not expecting. For instance, can users...supply --first-parent? What\n>    happens if they add an --author filter?\" ;-) I think these particular\n>    cases might work, but other rev-list options don't make sense, so let's\n>    error on ones that don't.\n\nI know that --first-parent was one of the options I _did_ want to\ninclude as a potential option (it helps focus the set to a \"core\" of\ncommits and we can get more on-demand off the core if needed). Yes,\n--author is a little silly, but it didn't seem necessary to block it.\n\nI agree with the reasons you gave to block _most_ of the options you\nblocked. The output-formatting options don't need to be a hard failure,\nbut that could be a later improvement. For now, I think your change is\nentirely positive so doesn't need change.\n\n>  * Patch 2: Making documentation more consistent with other commands\n>  * Patch 3: Tweak the ranges so we actually prevent on-demand blob\n>    downloading better with a new --[no-]include-edges flag.\n\nI gave notes on every patch, but no meaningful changes are required.\n\nThanks for helping to polish this feature!\n-Stolee\n\n"}]}