git log

built-in
0.0% Savings
0 Commands
0 Tokens saved
4 Tests

Install

tokf install bd27dd63f672a49d40e0a567b7eaab632b52897208000246c001348ae1c956c1
Safety checks passed

Filter definition

# git-log.toml — reduce full `git log` to one line per commit
#
# Raw: multi-line commit entries with full metadata and message bodies
# Filtered: `<short-sha> <subject>`, capped at 20 commits
#
# This filter used to `run = "git log --oneline --no-decorate -n 20 {args}"`.
# That destroyed the history before tokf ever saw it: `tokf raw <id>` returned
# 20 one-line summaries and there was no way to recover the rest (issue #430).
# The reduction now happens here, over the real `git log` output, so the full
# history is captured and recoverable.
#
# Empty-output handling: when git log returns no commits (e.g. for an
# untracked pathspec, an empty branch range, or a search that matched
# nothing), the model previously got back nothing — indistinguishable
# from "tokf filtered everything out". Observed retry pattern: agents
# would burn 10–40 calls cycling through flag variations
# (`--all`, `--diff-filter=A`, `--grep=…`, `--source`, `--follow`,
# `-- 'path'`) before realising the answer was "the file is untracked".
# `on_empty` makes the empty-result case unambiguous and actionable.

command = "git log"
description = "Show one-line-per-commit format, last 20 entries"

# Skip the filter when the user asks for an output shape this reduction would
# misrepresent. These flags change the structure of the output, so the chunk
# splitter below either can't parse it (`--oneline`, `--format`, `--graph`) or
# would silently discard the extra content the user explicitly asked for
# (`-p`, `--stat`).
passthrough_args = [
  "-p",            # patch (full diff content per commit)
  "--patch",
  "--oneline",     # already one line per commit — nothing to reduce
  "--format",      # custom output format
  "--pretty",
  "--graph",       # ASCII graph
  "--stat",        # diffstat per commit
  "--shortstat",   # one-line diffstat per commit
  "--dirstat",     # per-directory change stats
  "-L",            # line-history (-L 1,10:file or -L:funcName:file) — patch output
]

# When git returns no commits, give the model a one-line hint about the
# most likely causes instead of empty output.
on_empty = "(no matching commits — if querying a path, verify it's tracked: `git ls-files -- <path>`; for cross-branch history, add `--all`; for renamed-file history, add `--follow`)"

# Cap at 20 commits. Applied after rendering, so the full log is still
# captured in history and recoverable via `tokf raw`.
#
# Must stay above the [[chunk]] tables below: TOML array-of-tables sections
# capture every subsequent key, so a top-level field written after them is
# silently absorbed into the table instead.
max_lines = 20

# Guard: only render the reduction when the output actually looks like the
# default `git log` format.
#
# `on_empty` fires whenever the rendered output is empty, and the chunk
# splitter renders nothing for output it can't parse. Without this section, a
# user with `format.pretty = oneline` in their gitconfig — which is invisible
# to `passthrough_args`, since it isn't a CLI flag — would be told "no matching
# commits" about a log full of commits.
#
# When no section collects, the branch falls back to the raw output, so
# unparseable-but-real output is passed through and `on_empty` is left to mean
# what it says.
[[section]]
name = "commit-headers"
match = '^commit [0-9a-f]{7,}'
collect_as = "commit_header_lines"

# One chunk per commit. `Merge:`, `Author:` and `Date:` lines are dropped by
# not being extracted; the message body is dropped by taking only the first
# indented line (the subject).
[[chunk]]
split_on = '^commit [0-9a-f]{7,}'
collect_as = "commits"

[chunk.extract]
pattern = '^commit ([0-9a-f]{7})'
as = "sha"

# First indented non-blank line of the message is the subject; later body
# lines match too, but body_extract keeps the first match only.
[[chunk.body_extract]]
pattern = '^    (\S.*)$'
as = "subject"

[on_success]
output = """{commits | each: "{sha} {subject}" | join: "\n"}"""

# Route --name-only / --name-status to a tree-structured child filter
# instead of passing through unfiltered.
[[variant]]
name = "name-list"
detect.args_pattern = '--(name-only|name-status)'
filter = "git/log-name-list"

Examples

output is capped at 20 commits ~1123 tokens → ~263 tokens (77% saved)
Raw output
commit 4c2887241fcf61116ee1e1a965838e2d9b1214d4
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 20 10:10:00 2026 +0200

    feat(filter): add chunk-based git log reduction
    
    A longer explanation of the change spanning
    several lines of body text.
    
    Refs #430

commit 04dd4b1f7b9653ccc8d6743155607fed7cb2544d
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 19 10:11:00 2026 +0200

    fix(config): handle missing optional fields
    
    Co-Authored-By: Grace Hopper <grace@example.com>

commit fa26181ec60eb2ae8b41c45748514afbd4d67045
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 18 10:12:00 2026 +0200

    test(filter): add fixtures for cargo-test failure case

commit c538c297ccf1fd1db448e73334ae3fc29f5f076a
Merge: 1a2b3c4 5d6e7f8
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 17 10:13:00 2026 +0200

    docs: document the run override rule

commit c4a3b8e248580111a7c2c2a97201b301be4b60cb
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 16 10:14:00 2026 +0200

    refactor(runner): extract expand_run_command

commit ae283850259575235f0a5a30bedbb1066be8445a
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 15 10:15:00 2026 +0200

    chore(deps): bump serde to 1.0.219

commit 147d207fb81ab920f0d092c3dd503e7daa989a6d
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 14 10:16:00 2026 +0200

    ci: add clippy to the workflow

commit d8ecacc50b189c8b5a01349d85678638fbf5c750
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 13 10:17:00 2026 +0200

    perf(filter): avoid cloning chunk items

commit 19a0bf77bc93890771088801d56c94ed814d6aa0
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 12 10:18:00 2026 +0200

    fix(history): record executed command

commit 8b22a8fd6f319c50b419a3cf519b4fc445d984ad
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 11 10:19:00 2026 +0200

    feat(cli): add tokf raw subcommand

commit cbb1ab571e114f24abe381ac6e51c01fac522ce1
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 10 10:10:00 2026 +0200

    test(history): cover schema migration

commit f1741767ece4681587b6c012ca1133266c4982fb
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 09 10:11:00 2026 +0200

    docs(readme): regenerate from docs/

commit 68a97b570f38e67a7f1a14a4917ccf419a9795a0
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 08 10:12:00 2026 +0200

    fix(hook): stop swallowing stderr

commit 8449705ed01476411190f9c29d4a5a88c0cb3efa
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 07 10:13:00 2026 +0200

    refactor(config): split types module

commit d8a09c97cba3eda464519408b0ff8f46b6a08124
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 06 10:14:00 2026 +0200

    feat(output): annotate with history id

commit aef47ff065244575998aeb59faaa95c3c7c233ca
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 05 10:15:00 2026 +0200

    chore: release main

commit a621bb4a6a353950da76cd0a1670c466d5fffc20
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 04 10:16:00 2026 +0200

    fix(tracking): guard against zero retention

commit 2419eac713021ba0831eae3bab01f8dd5e3e0c1e
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 03 10:17:00 2026 +0200

    test(cli): end-to-end passthrough case

commit ad387a02c3d507e61973885766ba18faacb59347
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 02 10:18:00 2026 +0200

    feat(gh): add pr checks filter

commit 850951619c7aec7a85ee6dd5255a26ed07a49692
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 20 10:19:00 2026 +0200

    fix(docker): correct ps format string

commit df5c8089aebee76c5a34e551fc467ed17a1105ba
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 19 10:10:00 2026 +0200

    docs(filters): explain passthrough semantics

commit 9f89b43d64cbc659c11c1d52d6cdb640b41cec07
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 18 10:11:00 2026 +0200

    chore(deps): update rust to 1.96.1
Filtered output
4c28872 feat(filter): add chunk-based git log reduction
04dd4b1 fix(config): handle missing optional fields
fa26181 test(filter): add fixtures for cargo-test failure case
c538c29 docs: document the run override rule
c4a3b8e refactor(runner): extract expand_run_command
ae28385 chore(deps): bump serde to 1.0.219
147d207 ci: add clippy to the workflow
d8ecacc perf(filter): avoid cloning chunk items
19a0bf7 fix(history): record executed command
8b22a8f feat(cli): add tokf raw subcommand
cbb1ab5 test(history): cover schema migration
f174176 docs(readme): regenerate from docs/
68a97b5 fix(hook): stop swallowing stderr
8449705 refactor(config): split types module
d8a09c9 feat(output): annotate with history id
aef47ff chore: release main
a621bb4 fix(tracking): guard against zero retention
2419eac test(cli): end-to-end passthrough case
ad387a0 feat(gh): add pr checks filter
8509516 fix(docker): correct ps format string
empty git log emits actionable hint instead of nothing ~0 tokens → ~49 tokens
Raw output
 
Filtered output
(no matching commits — if querying a path, verify it's tracked: `git ls-files -- <path>`; for cross-branch history, add `--all`; for renamed-file history, add `--follow`)
full git log reduces to one line per commit ~1123 tokens → ~263 tokens (77% saved)
Raw output
commit 4c2887241fcf61116ee1e1a965838e2d9b1214d4
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 20 10:10:00 2026 +0200

    feat(filter): add chunk-based git log reduction
    
    A longer explanation of the change spanning
    several lines of body text.
    
    Refs #430

commit 04dd4b1f7b9653ccc8d6743155607fed7cb2544d
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 19 10:11:00 2026 +0200

    fix(config): handle missing optional fields
    
    Co-Authored-By: Grace Hopper <grace@example.com>

commit fa26181ec60eb2ae8b41c45748514afbd4d67045
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 18 10:12:00 2026 +0200

    test(filter): add fixtures for cargo-test failure case

commit c538c297ccf1fd1db448e73334ae3fc29f5f076a
Merge: 1a2b3c4 5d6e7f8
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 17 10:13:00 2026 +0200

    docs: document the run override rule

commit c4a3b8e248580111a7c2c2a97201b301be4b60cb
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 16 10:14:00 2026 +0200

    refactor(runner): extract expand_run_command

commit ae283850259575235f0a5a30bedbb1066be8445a
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 15 10:15:00 2026 +0200

    chore(deps): bump serde to 1.0.219

commit 147d207fb81ab920f0d092c3dd503e7daa989a6d
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 14 10:16:00 2026 +0200

    ci: add clippy to the workflow

commit d8ecacc50b189c8b5a01349d85678638fbf5c750
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 13 10:17:00 2026 +0200

    perf(filter): avoid cloning chunk items

commit 19a0bf77bc93890771088801d56c94ed814d6aa0
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 12 10:18:00 2026 +0200

    fix(history): record executed command

commit 8b22a8fd6f319c50b419a3cf519b4fc445d984ad
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 11 10:19:00 2026 +0200

    feat(cli): add tokf raw subcommand

commit cbb1ab571e114f24abe381ac6e51c01fac522ce1
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 10 10:10:00 2026 +0200

    test(history): cover schema migration

commit f1741767ece4681587b6c012ca1133266c4982fb
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 09 10:11:00 2026 +0200

    docs(readme): regenerate from docs/

commit 68a97b570f38e67a7f1a14a4917ccf419a9795a0
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 08 10:12:00 2026 +0200

    fix(hook): stop swallowing stderr

commit 8449705ed01476411190f9c29d4a5a88c0cb3efa
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 07 10:13:00 2026 +0200

    refactor(config): split types module

commit d8a09c97cba3eda464519408b0ff8f46b6a08124
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 06 10:14:00 2026 +0200

    feat(output): annotate with history id

commit aef47ff065244575998aeb59faaa95c3c7c233ca
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 05 10:15:00 2026 +0200

    chore: release main

commit a621bb4a6a353950da76cd0a1670c466d5fffc20
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 04 10:16:00 2026 +0200

    fix(tracking): guard against zero retention

commit 2419eac713021ba0831eae3bab01f8dd5e3e0c1e
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 03 10:17:00 2026 +0200

    test(cli): end-to-end passthrough case

commit ad387a02c3d507e61973885766ba18faacb59347
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 02 10:18:00 2026 +0200

    feat(gh): add pr checks filter

commit 850951619c7aec7a85ee6dd5255a26ed07a49692
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 20 10:19:00 2026 +0200

    fix(docker): correct ps format string

commit df5c8089aebee76c5a34e551fc467ed17a1105ba
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 19 10:10:00 2026 +0200

    docs(filters): explain passthrough semantics

commit 9f89b43d64cbc659c11c1d52d6cdb640b41cec07
Author: Ada Lovelace <ada@example.com>
Date:   Mon Jul 18 10:11:00 2026 +0200

    chore(deps): update rust to 1.96.1
Filtered output
4c28872 feat(filter): add chunk-based git log reduction
04dd4b1 fix(config): handle missing optional fields
fa26181 test(filter): add fixtures for cargo-test failure case
c538c29 docs: document the run override rule
c4a3b8e refactor(runner): extract expand_run_command
ae28385 chore(deps): bump serde to 1.0.219
147d207 ci: add clippy to the workflow
d8ecacc perf(filter): avoid cloning chunk items
19a0bf7 fix(history): record executed command
8b22a8f feat(cli): add tokf raw subcommand
cbb1ab5 test(history): cover schema migration
f174176 docs(readme): regenerate from docs/
68a97b5 fix(hook): stop swallowing stderr
8449705 refactor(config): split types module
d8a09c9 feat(output): annotate with history id
aef47ff chore: release main
a621bb4 fix(tracking): guard against zero retention
2419eac test(cli): end-to-end passthrough case
ad387a0 feat(gh): add pr checks filter
8509516 fix(docker): correct ps format string
output the splitter can't parse is passed through, not called empty ~12 tokens → ~12 tokens
Raw output
abc1234 some subject
def5678 another subject
Filtered output
abc1234 some subject
def5678 another subject
Warning: Community filters are third-party code. Review the filter definition above before installing it in production environments.
Browse all filters