git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/5] Change git-last-modified(1) default behavior and add documentation

From
Toon Claes <toon@iotcl.com>
Date
Jan 16, 2026, 13:22 UTC
Message-ID
<20260116-toon-last-modified-zzzz-v2-0-79e44f2806fe@iotcl.com>
In-Reply-To
<20251126-toon-last-modified-zzzz-v1-0-608350df0caa@iotcl.com>

We have had several reports[1][2] from users that have been thoroughly confused by the default behaviour of git-last-modified(1). Most importantly, when using the command on trees other than the root tree the requests are seemingly ignoring that request and instead blame the top-level subtree. For example:

    $ git last-modified t/lib-bash.sh
    acdfea4394db8e8b42f48e36f7726d64a909a89d t

This result is completely unexpected and feels buggy to anybody who is not deeply familiar with git-last-modified(1). Furthermore, users typically have a hard time to figure out the correct parameters.

This series changes the behavior to something that intuitively makes more sense.

The change of the default behavior is done in the last commit, in the lead-up commits changes in the documentation are made.

[1]: <f0c508cc-5c6b-4c4b-a3f3-0cdd8d1071e5@app.fastmail.com> [2]: <03f96860-29fc-42a7-a220-c3ec65eb8516@codeberg.org>

---
Changes in v2:
- Change the default --max-depth.
- Split up commits in smaller pieces.
- Add more testss
- Link to v1: https://patch.msgid.link/20251126-toon-last-modified-zzzz-v1-0-608350df0caa@iotcl.com
Cc: "Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com>
Cc: Gusted <gusted@codeberg.org>
---
Toon Claes (5):
      last-modified: document NUL termination
      last-modified: add option '-z' to help output
      last-modified: document option --max-depth
      last-modified: add option '--max-depth' to help output
      last-modified: change default max-depth to 0
 Documentation/git-last-modified.adoc | 29 ++++++++++++++++++++++++++++-
 builtin/last-modified.c              | 20 ++++++++++++++------
 t/t8020-last-modified.sh             | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 7 deletions(-)
Range-diff versus v1:
1:  7f599cf0d1 ! 1:  4a9b8170c3 last-modified: handle and document NUL termination
    @@ Metadata
     Author: Toon Claes <toon@iotcl.com>
     
      ## Commit message ##
    -    last-modified: handle and document NUL termination
    +    last-modified: document NUL termination
     
    -    When option `-z` is provided to git-last-modified(1), each line is
    -    separated with a NUL instead of a newline. Document this properly and
    -    handle parsing of the option in the builtin itself.
    +    The command git-last-modified(1) already recognizes the option '-z', and
    +    similar to many other commands this will make the output NUL-terminated
    +    instead of using newlines. Although, this option is missing from the
    +    documentation, so add it.
     
         Signed-off-by: Toon Claes <toon@iotcl.com>
     
    @@ Documentation/git-last-modified.adoc: git-last-modified - EXPERIMENTAL: Show whe
      --------
      [synopsis]
     -git last-modified [--recursive] [--show-trees] [<revision-range>] [[--] <path>...]
    -+git last-modified [--recursive] [--show-trees] [-z] [<revision-range>] [[--] <path>...]
    ++git last-modified [--recursive] [--show-trees] [-z]
    ++		  [<revision-range>] [[--] <path>...]
      
      DESCRIPTION
      -----------
    @@ Documentation/git-last-modified.adoc: OPTIONS
      	without `--recursive`.
      
     +`-z`::
    -+	Terminate each line with a _NUL_ rather than a newline.
    ++	Terminate each line with a _NUL_ character rather than a newline.
     +
      `<revision-range>`::
      	Only traverse commits in the specified revision range. When no
    @@ Documentation/git-last-modified.adoc: OPTIONS
      linkgit:git-blame[1],
     
      ## builtin/last-modified.c ##
    -@@
    - #define PARENT1 (1u<<16) /* used instead of SEEN */
    - #define PARENT2 (1u<<17) /* used instead of BOTTOM, BOUNDARY */
    - 
    -+#define LAST_MODIFIED_INIT { \
    -+	.line_termination = '\n', \
    -+}
    -+
    - struct last_modified_entry {
    - 	struct hashmap_entry hashent;
    - 	struct object_id oid;
    -@@ builtin/last-modified.c: struct last_modified {
    - 	struct rev_info rev;
    - 	bool recursive;
    - 	bool show_trees;
    -+	int line_termination;
    - 
    - 	const char **all_paths;
    - 	size_t all_paths_nr;
    -@@ builtin/last-modified.c: static void last_modified_emit(struct last_modified *lm,
    - 		putchar('^');
    - 	printf("%s\t", oid_to_hex(&commit->object.oid));
    - 
    --	if (lm->rev.diffopt.line_termination)
    -+	if (lm->line_termination)
    - 		write_name_quoted(path, stdout, '\n');
    - 	else
    - 		printf("%s%c", path, '\0');
     @@ builtin/last-modified.c: int cmd_last_modified(int argc, const char **argv, const char *prefix,
    - 		      struct repository *repo)
    - {
    - 	int ret;
    --	struct last_modified lm = { 0 };
    -+	struct last_modified lm = LAST_MODIFIED_INIT;
    + 	struct last_modified lm = { 0 };
      
      	const char * const last_modified_usage[] = {
     -		N_("git last-modified [--recursive] [--show-trees] "
    -+		N_("git last-modified [--recursive] [--show-trees] [-z] "
    - 		   "[<revision-range>] [[--] <path>...]"),
    +-		   "[<revision-range>] [[--] <path>...]"),
    ++		N_("git last-modified [--recursive] [--show-trees] [-z]\n"
    ++		   "                  [<revision-range>] [[--] <path>...]"),
      		NULL
      	};
    -@@ builtin/last-modified.c: int cmd_last_modified(int argc, const char **argv, const char *prefix,
    - 			 N_("recurse into subtrees")),
    - 		OPT_BOOL('t', "show-trees", &lm.show_trees,
    - 			 N_("show tree entries when recursing into subtrees")),
    -+		OPT_SET_INT('z', NULL, &lm.line_termination,
    -+			N_("lines are separated with NUL character"), '\0'),
    - 		OPT_END()
    - 	};
      
-:  ---------- > 2:  94efeb29b1 last-modified: add option '-z' to help output
-:  ---------- > 3:  5669ab25e8 last-modified: document option --max-depth
2:  f193241248 ! 4:  b3060f8b38 last-modified: document option --max-depth
    @@ Metadata
     Author: Toon Claes <toon@iotcl.com>
     
      ## Commit message ##
    -    last-modified: document option --max-depth
    +    last-modified: add option '--max-depth' to help output
     
    -    Option --max-depth is supported by git-last-modified(1), because it was
    -    added to the diff machinery in a1dfa5448d (diff: teach tree-diff a
    -    max-depth parameter, 2025-08-07).
    +    In previous commit option '--max-depth' was added to the documentation.
    +    To have it also appear in the help output of `git last-modified -h`,
    +    move the handling of '--max-depth' to parse_options() in
    +    builtin/last-modified.c itself.
     
    -    This option is useful for everyday use of the git-last-modified(1)
    -    command, so document it's existence in the man page and `-h` output.
    +    It enables us to change default behavior in a subsequent commit.
     
         Signed-off-by: Toon Claes <toon@iotcl.com>
     
    - ## Documentation/git-last-modified.adoc ##
    -@@ Documentation/git-last-modified.adoc: git-last-modified - EXPERIMENTAL: Show when files were last modified
    - SYNOPSIS
    - --------
    - [synopsis]
    --git last-modified [--recursive] [--show-trees] [-z] [<revision-range>] [[--] <path>...]
    -+git last-modified [--recursive] [--show-trees] [--max-depth=<depth>] [-z]
    -+	[<revision-range>] [[--] <path>...]
    - 
    - DESCRIPTION
    - -----------
    -@@ Documentation/git-last-modified.adoc: OPTIONS
    - 	Show tree entries even when recursing into them. It has no effect
    - 	without `--recursive`.
    - 
    -+`--max-depth=<depth>`::
    -+	For each pathspec given on the command line, descend at most `<depth>`
    -+	levels of directories. A negative value means no limit.
    -+	Setting a positive value implies `--recursive`.
    -+	Cannot be combined with wildcards in the pathspec.
    -+
    - `-z`::
    - 	Terminate each line with a _NUL_ rather than a newline.
    - 
    -
      ## builtin/last-modified.c ##
    -@@
    - 
    - #define LAST_MODIFIED_INIT { \
    - 	.line_termination = '\n', \
    -+	.max_depth = -1, \
    - }
    - 
    - struct last_modified_entry {
     @@ builtin/last-modified.c: struct last_modified {
      	bool recursive;
      	bool show_trees;
    - 	int line_termination;
    + 	bool null_termination;
     +	int max_depth;
      
      	const char **all_paths;
    @@ builtin/last-modified.c: static int last_modified_init(struct last_modified *lm,
      	argc = setup_revisions(argc, argv, &lm->rev, NULL);
      	if (argc > 1) {
      		error(_("unknown last-modified argument: %s"), argv[1]);
    -@@ builtin/last-modified.c: int cmd_last_modified(int argc, const char **argv, const char *prefix,
    - 	struct last_modified lm = LAST_MODIFIED_INIT;
    - 
    - 	const char * const last_modified_usage[] = {
    --		N_("git last-modified [--recursive] [--show-trees] [-z] "
    -+		N_("git last-modified [--recursive] [--show-trees] [--max-depth=<depth>] [-z] "
    - 		   "[<revision-range>] [[--] <path>...]"),
    - 		NULL
    - 	};
     @@ builtin/last-modified.c: int cmd_last_modified(int argc, const char **argv, const char *prefix,
      			 N_("recurse into subtrees")),
      		OPT_BOOL('t', "show-trees", &lm.show_trees,
      			 N_("show tree entries when recursing into subtrees")),
     +		OPT_INTEGER_F(0, "max-depth", &lm.max_depth,
     +			N_("maximum tree depth to recurse"), PARSE_OPT_NONEG),
    - 		OPT_SET_INT('z', NULL, &lm.line_termination,
    - 			N_("lines are separated with NUL character"), '\0'),
    + 		OPT_BOOL('z', NULL, &lm.null_termination,
    + 			N_("lines are separated with NUL character")),
      		OPT_END()
    + 	};
    + 
    ++	/*
    ++	 * Set the default of a max-depth to "unset". This will change in a
    ++	 * subsequent commit.
    ++	 */
    ++	lm.max_depth = -1;
    ++
    + 	argc = parse_options(argc, argv, prefix, last_modified_options,
    + 			     last_modified_usage,
    + 			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |
3:  6773f073d6 < -:  ---------- last-modified: better document how depth in handled
-:  ---------- > 5:  41819f8732 last-modified: change default max-depth to 0

--- base-commit: 7264e61d87e58b9d0f5e6424c47c11e9657dfb75 change-id: 20251114-toon-last-modified-zzzz-af9c1be74fc4

Previous: Patrick SteinhardtNext: Toon Claes
Message 17 of 36 in “Expand and enhance git-last-modified(1) documentation”
  1. 0/3 Expand and enhance git-last-modified(1) documentationToon Claes, Nov 26, 2025
  2. 1/3 last-modified: handle and document NUL terminationToon Claes, Nov 26, 2025
  3. Karthik NayakNov 26, 2025
  4. Junio C HamanoNov 26, 2025
  5. Toon ClaesNov 28, 2025
  6. Patrick SteinhardtDec 1, 2025
  7. 2/3 last-modified: document option --max-depthToon Claes, Nov 26, 2025
  8. Karthik NayakNov 26, 2025
  9. Toon ClaesJan 16, 2026
  10. Junio C HamanoNov 26, 2025
  11. Toon ClaesNov 28, 2025
  12. 3/3 last-modified: better document how depth in handledToon Claes, Nov 26, 2025
  13. Eric SunshineNov 26, 2025
  14. Patrick SteinhardtDec 1, 2025
  15. Toon ClaesDec 2, 2025
  16. Patrick SteinhardtDec 2, 2025
  17. 0/5 Change git-last-modified(1) default behavior and add documentationToon Claes, Jan 16, 2026
  18. 1/5 last-modified: document NUL terminationToon Claes, Jan 16, 2026
  19. 2/5 last-modified: add option '-z' to help outputToon Claes, Jan 16, 2026
  20. Junio C HamanoJan 16, 2026
  21. 3/5 last-modified: document option --max-depthToon Claes, Jan 16, 2026
  22. 4/5 last-modified: add option '--max-depth' to help outputToon Claes, Jan 16, 2026
  23. Junio C HamanoJan 16, 2026
  24. 5/5 last-modified: change default max-depth to 0Toon Claes, Jan 16, 2026
  25. Junio C HamanoJan 16, 2026
  26. Kristoffer HaugsbakkJan 16, 2026
  27. Toon ClaesJan 20, 2026
  28. 0/4 Change git-last-modified(1) default behavior and add documentationToon Claes, Jan 20, 2026
  29. 1/4 last-modified: clarify in the docs the command takes a pathspecToon Claes, Jan 20, 2026
  30. 2/4 last-modified: document option '-z'Toon Claes, Jan 20, 2026
  31. 3/4 last-modified: document option '--max-depth'Toon Claes, Jan 20, 2026
  32. 4/4 last-modified: change default max-depth to 0Toon Claes, Jan 20, 2026
  33. Kristoffer HaugsbakkJan 25, 2026
  34. Junio C HamanoJan 21, 2026
  35. Karthik NayakFeb 3, 2026
  36. Junio C HamanoFeb 3, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.