{"thread":{"id":"64550","subject":"[PATCH] last-modified: support sparse checkouts","startedAt":"2025-11-29T13:43:49Z","lastAt":"2025-12-03T11:12:01Z","messageCount":3,"participants":["Johannes Schindelin via GitGitGadget","Derrick Stolee","Toon Claes"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"531430","messageId":"pull.2013.git.1764423826908.gitgitgadget@gmail.com","threadId":"64550","inReplyTo":null,"subject":"[PATCH] last-modified: support sparse checkouts","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-29T13:43:46Z","receivedAt":"2025-11-29T13:43:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIn a sparse checkout, a user might want to run `last-modified` on a\ndirectory outside the worktree.\n\nAnd even in non-sparse checkouts, a user might need to run that command\non a directory that does not exist in the worktree.\n\nThese use cases should be supported via the `--` separator between\nrevision and file arguments, which is even advertised in the\ndocumentation. This patch fixes a tiny bug that prevents that from\nworking.\n\nThis fixes https://github.com/git-for-windows/git/issues/5978\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n    last-modified: support sparse checkouts\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2013%2Fdscho%2Flast-modified-vs-sparse-checkouts-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2013/dscho/last-modified-vs-sparse-checkouts-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/2013\n\n builtin/last-modified.c  | 3 ++-\n t/t8020-last-modified.sh | 8 ++++++++\n 2 files changed, 10 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/last-modified.c b/builtin/last-modified.c\nindex b0ecbdc540..dc1e229f4d 100644\n--- a/builtin/last-modified.c\n+++ b/builtin/last-modified.c\n@@ -525,7 +525,8 @@ int cmd_last_modified(int argc, const char **argv, const char *prefix,\n \n \targc = parse_options(argc, argv, prefix, last_modified_options,\n \t\t\t     last_modified_usage,\n-\t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);\n+\t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |\n+\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n \n \trepo_config(repo, git_default_config, NULL);\n \ndiff --git a/t/t8020-last-modified.sh b/t/t8020-last-modified.sh\nindex a4c1114ee2..50f4312f71 100755\n--- a/t/t8020-last-modified.sh\n+++ b/t/t8020-last-modified.sh\n@@ -78,6 +78,14 @@ test_expect_success 'last-modified subdir' '\n \tEOF\n '\n \n+test_expect_success 'last-modified in sparse checkout' '\n+\ttest_when_finished \"git sparse-checkout disable\" &&\n+\tgit sparse-checkout set b &&\n+\tcheck_last_modified -- a <<-\\EOF\n+\t3 a\n+\tEOF\n+'\n+\n test_expect_success 'last-modified subdir recursive' '\n \tcheck_last_modified -r a <<-\\EOF\n \t3 a/b/file\n\nbase-commit: 9a2fb147f2c61d0cab52c883e7e26f5b7948e3ed\n-- \ngitgitgadget\n"},{"id":"531478","messageId":"75f862a5-2663-4211-b96c-d2c5d1c6f91e@gmail.com","threadId":"64550","inReplyTo":"pull.2013.git.1764423826908.gitgitgadget@gmail.com","subject":"Re: [PATCH] last-modified: support sparse checkouts","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2025-11-30T20:00:30Z","receivedAt":"2025-11-30T20:00:33Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 11/29/2025 8:43 AM, Johannes Schindelin via GitGitGadget wrote:\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> \n> In a sparse checkout, a user might want to run `last-modified` on a\n> directory outside the worktree.\n> \n> And even in non-sparse checkouts, a user might need to run that command\n> on a directory that does not exist in the worktree.\n> \n> These use cases should be supported via the `--` separator between\n> revision and file arguments, which is even advertised in the\n> documentation. This patch fixes a tiny bug that prevents that from\n> working.\n\n>  \targc = parse_options(argc, argv, prefix, last_modified_options,\n>  \t\t\t     last_modified_usage,\n> -\t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);\n> +\t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |\n> +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n\nI'm intrigued that this is the only fix that was required.\n\n> +test_expect_success 'last-modified in sparse checkout' '\n> +\ttest_when_finished \"git sparse-checkout disable\" &&\n> +\tgit sparse-checkout set b &&\n> +\tcheck_last_modified -- a <<-\\EOF\n\nWould we expect this to work without the '--'? Should it\nfail for a directory that exists at HEAD but is outside of\nthe sparse-checkout?\n\nThanks,\n-Stolee\n\n"},{"id":"531621","messageId":"87qztbx1jd.fsf@iotcl.com","threadId":"64550","inReplyTo":"75f862a5-2663-4211-b96c-d2c5d1c6f91e@gmail.com","subject":"Re: [PATCH] last-modified: support sparse checkouts","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2025-12-03T11:11:50Z","receivedAt":"2025-12-03T11:12:01Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Derrick Stolee <stolee@gmail.com> writes:\n\n> On 11/29/2025 8:43 AM, Johannes Schindelin via GitGitGadget wrote:\n>> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>> \n>> In a sparse checkout, a user might want to run `last-modified` on a\n>> directory outside the worktree.\n>> \n>> And even in non-sparse checkouts, a user might need to run that command\n>> on a directory that does not exist in the worktree.\n>> \n>> These use cases should be supported via the `--` separator between\n>> revision and file arguments, which is even advertised in the\n>> documentation. This patch fixes a tiny bug that prevents that from\n>> working.\n>\n>>  \targc = parse_options(argc, argv, prefix, last_modified_options,\n>>  \t\t\t     last_modified_usage,\n>> -\t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);\n>> +\t\t\t     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |\n>> +\t\t\t     PARSE_OPT_KEEP_DASHDASH);\n>\n> I'm intrigued that this is the only fix that was required.\n\nI like it!\n\n>> +test_expect_success 'last-modified in sparse checkout' '\n>> +\ttest_when_finished \"git sparse-checkout disable\" &&\n>> +\tgit sparse-checkout set b &&\n>> +\tcheck_last_modified -- a <<-\\EOF\n>\n> Would we expect this to work without the '--'? Should it\n> fail for a directory that exists at HEAD but is outside of\n> the sparse-checkout?\n\nI don't think we need to complicate things that much. Arguments after\nthe '--' are handled as pathspecs. If no paths match that pathspec, the\noutput is simply nothing.\n\nJust to demonstrate:\n\nOn 'master':\n\n    $ git last-modified a\n    fatal: ambiguous argument 'a': unknown revision or path not in the working tree.\n    Use '--' to separate paths from revisions, like this:\n    'git <command> [<revision>...] -- [<file>...]'\n\n    $ git last-modified -- a\n    fatal: ambiguous argument 'a': unknown revision or path not in the working tree.\n    Use '--' to separate paths from revisions, like this:\n    'git <command> [<revision>...] -- [<file>...]'\n\nWith this patch applied:\n\n    $ git last-modified a\n    fatal: ambiguous argument 'a': unknown revision or path not in the working tree.\n    Use '--' to separate paths from revisions, like this:\n    'git <command> [<revision>...] -- [<file>...]'\n\n    $ git last-modified -- a\n\n    $ echo $?\n    0\n\nI agree this behavior is better. Thanks for this fix. I approve.\n\n-- \nCheers,\nToon\n"}]}