Skip to content

Repository files navigation

logr

CI npm Homebrew License: MIT

Search the commit history of every git repository under a directory.

Built for workspaces made of many independent repositories, where "which repos did that ticket touch?" means running git log --grep in each one.

$ logr PROJ-142 ~/work
api
  3f9c2a1  2026-09-23  PROJ-142: validate redirect URL (#212)  (Ann Lee, main, #212)
  b71e0d4  2026-09-22  PROJ-142: add failing test  (Ann Lee, origin/fix/PROJ-142)

web
  c02a9f7  2026-09-24  Merge branch 'fix/PROJ-142' into 'main'  (Bob Stone, origin/main, !88)
  5d1e6b2  2026-09-23  PROJ-142: keep the return URL  (Bob Stone, fix/PROJ-142, !88)

4 commits in 2 of 14 repositories

Install

# Homebrew
brew install kova1max/tap/logr

# npm
npm install -g @kova1/logr

To try it without installing anything:

npx @kova1/logr PROJ-142 ~/work

Every release is also mirrored to GitHub Packages as @kova1max/logr (GitHub requires the repo owner as scope). Installing from there needs a GitHub token, so the npm registry above is the easier choice.

What it will never do

logr only reads. It will never:

  • Fetch, pull or touch the network. It searches what is already on disk, so it is instant and works offline. To include your colleagues' latest commits, fetch first (for example with pullr).
  • Change a repository - no checkouts, no writes to .git, no changes to the working tree.
  • Enter a nested repository, unless it is a submodule and you ask for submodules with --submodules.
  • Follow symlinked directories.

Usage

logr [options] [PATTERN] [DIR]

PATTERN is literal text, matched against the whole commit message. Lowercase text matches any case; text with a capital letter matches exactly (smart case), so logr login finds "Login" while logr PROJ-142 does not find "proj-142".

Every local and remote-tracking branch is searched, and each commit is listed once, with the branch it was found on. Options can go before or after PATTERN and DIR.

Short options can be combined: -ic is -i -c, and -m5 or -im 5 set the count.

Option                               Default Meaning
DIR, -C DIR current directory Where to look for repositories
-E, --regex Treat PATTERN as an extended regular expression
-i, --ignore-case smart case Always ignore case
--case-sensitive smart case Never ignore case
-c, --code Search the changes instead of the messages: list the commits that add or remove PATTERN (git log -S, or -G with --regex). Slower on large histories.
--author WHO Only commits by an author whose name or email matches WHO
--since DATE Only commits after DATE, e.g. 2026-09-01 or 2.weeks
--until DATE Only commits before DATE
--current Only search the checked-out branch of each repository
-m, --max-count N Show at most N commits per repository
-j, --jobs N 8 Search up to N repositories in parallel. Output is printed in discovery order, so it reads the same as a sequential run.
--max-depth N 2 How many directory levels below DIR to search. 0 = only DIR itself, 1 = DIR and its direct children, ...
-s, --submodules off Also search each checked-out submodule
--no-color Disable colored output. Also disabled when the NO_COLOR environment variable is set, or when output is not a terminal.
-V, --version Print the version
-h, --help Show help

PATTERN can be left out when searching only by --author, --since or --until; pass '' in its place when also giving DIR.

Examples

# every commit that mentions a ticket
logr PROJ-142 ~/work

# what Ann committed in the last week
logr '' ~/work --author ann --since 1.week

# recent reverts, searching from the current directory
logr -E 'revert|rollback' --since 1.month

# the commits that added or removed a call
logr -c getUserInfo ~/work

# the latest release commit on each checked-out branch
logr -m 1 --current release

Output

On a terminal, commits are grouped under each repository, newest first, as in the example at the top. When the output is piped, each commit is one tab-separated line - repository, commit, date, author, branch, pull request (empty if none), subject - so it works with cut, sort and awk:

$ logr PROJ-142 ~/work | awk -F'\t' '$6 != "" { print $1, $6 }' | sort -u
api #212
web !88

The summary line and any errors go to stderr, so piped output stays pure data.

Pull requests

Each commit shows the pull request it came in with, worked out from the history on disk - no API calls, no tokens:

  • a merge or squash commit that names one: Merge pull request #12 and Fix login (#12) on GitHub, See merge request group/project!12 on GitLab (shown as !12), (pull request #12) on Bitbucket and Merged PR 12: on Azure DevOps;
  • any other commit gets the pull request of the merge that brought it into a branch - the oldest one that names a pull request, if it was merged more than once.

A commit that never came in through a pull request - made directly on the branch it is on, or on a branch not merged yet - has none. Fetch first to see pull requests merged since your last fetch.

Exit codes

Exits 0 if any commit matched, 1 if none did, and 2 on invalid arguments or if a repository could not be searched, like grep.

License

MIT

About

Search the commit history of every git repository under a directory

Topics

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages