A Kotlin CLI tool that runs git blame when given a file path with line number.
# Using -fl (file:line) - recommended
./gittrace -fl="src/main/kotlin/dev/gittrace/Main.kt:20"
./gittrace --file-line="src/Main.kt:42"
# Using separate -f and -l options
./gittrace -f="src/Main.kt" -l=42
./gittrace --file="src/Main.kt" --line=42
# Positional argument also works
gittrace src/Main.kt:42
# With context: show 5 lines before/after
./gittrace -fl="src/Main.kt:42" -n 5
./gittrace -f="src/Main.kt" -l=42 -n 5
# JSON output (for scripting/editor integration)
./gittrace -fl="src/Main.kt:42" --json
./gittrace -f="src/Main.kt" -l=42 --json
# Profile scan duration (ms)
./gittrace -fl="src/Main.kt:42" -pf
# Skip scope for speed in large repos (e.g. Rails, Linux kernel)
./gittrace -fl="src/Main.kt:42" -S
# Single-line output: "You, 20 mins ago * commit message"
./gittrace -fl="src/Main.kt:42" -ol
# Full file blame
./gittrace -fl="src/Main.kt:1" --full
./gittrace -f="src/Main.kt" -l=1 --fullShows commit details for the target line (no raw blame table):
─── src/main/kotlin/dev/gittrace/Main.kt : Commit f2fe7845 (covers lines 18, 20–22) ───
Status: committed
Scope: 5 files, 77 lines changed
Author: Akash Paudel
Email: akash.chhetri1@gmail.com
Message: java version fixed and warning removed
When: 1 hours ago (2026-01-31 18:48)
SHA: f2fe7845b7065628e3d10bf060470298c4e527f1
Commit: https://github.com/owner/repo/commit/f2fe7845...
PR: https://github.com/owner/repo/pull/123 (if commit message references #123)
Supports GitHub, GitLab, and Bitbucket URLs (from remote.origin.url).
For uncommitted lines: shows last committed state, committed vs current content (with whitespace markers), and diff.
Errors: Distinct messages for "Not in a git repository", "File is untracked (not in HEAD)", and "Git command failed". With --json, errors include errorKind: outside_repo, untracked, or git_failed.
# Build (use Java 17–24 if you have multiple JDKs, or use asdf)
./gradlew build
# Reclaim disk: remove build output (~6MB)
./gradlew clean
# Run from project directory
./gittrace -fl="src/main/kotlin/dev/gittrace/Main.kt:20"
# Install globally (use from any directory)
./install.sh
# or: ./gradlew install
# Then add to PATH if needed (add to ~/.zshrc):
export PATH="$HOME/.local/bin:$PATH"
# Run from anywhere
gittrace -fl="src/main/kotlin/dev/gittrace/Main.kt:20"
# Large repos (Rails, Linux, etc.): add -S for faster output (~40% faster)
gittrace -fl="activerecord/lib/active_record.rb:17" -S# Run all tests
./gradlew test
# Run end-to-end test
./gradlew test --tests "*EndToEndTest.end-to-end test with -fl option"
# Generate test coverage report
./gradlew jacocoTestReport
# View report at: build/reports/jacoco/test/html/index.html- JDK 17–24 (Java 25 has Kotlin compiler compatibility issues)
- Git
asdf (recommended): The project includes .tool-versions for asdf. Install Java via:
asdf plugin add java # if not already added
asdf install # installs version from .tool-versionsIf the build fails with Java 25, gradlew auto-switches to Java 17–24 when available. If it still fails, run ./gradlew --stop to clear cached daemons, or set JAVA_HOME to Java 24 (e.g. export JAVA_HOME=$(/usr/libexec/java_home -v 24)).
gittrace/
├── .tool-versions # asdf: Java version for this project
├── gittrace # Wrapper script: ./gittrace -fl="file:line"
├── install.sh # Install globally: ./install.sh
├── build.gradle.kts
├── settings.gradle.kts
├── LICENSE # MIT License
├── CONTRIBUTING.md # Contribution guidelines
├── CODE_OF_CONDUCT.md # Code of Conduct
└── src/main/kotlin/dev/gittrace/
├── Main.kt # CLI entry point, Clikt command
├── LocationParser.kt # Parses "file:line" format
├── GitBlame.kt # Runs git blame, error handling
├── GitParallel.kt # Parallel git commands for perf
├── PorcelainParser.kt# Parses git blame --porcelain output
├── CommitFormatter.kt# Orchestrates formatting
├── HumanFormatter.kt # Human-readable output
├── JsonFormatter.kt # JSON output (aligned schema)
├── FormatterUtils.kt # Shared time/range formatting
├── Constants.kt # UNCOMMITTED_HASH, etc.
├── FormatOptions.kt # JSON output options
├── GitLinks.kt # Git ops, commit/PR URLs
└── BlameEntry.kt # Data model for blame lines
We welcome contributions from the community! Whether it's bug fixes, new features, documentation improvements, or other enhancements, your help makes gittrace better for everyone.
- Fork the repository and clone your fork
- Create a branch for your changes (
git checkout -b feature/your-feature-name) - Make your changes following our coding guidelines
- Test your changes (
./gradlew clean build) - Commit with clear messages
- Push to your fork and open a Pull Request
For detailed guidelines, please see CONTRIBUTING.md.
- 🐛 Bug fixes and issue resolution
- ✨ New features and enhancements
- 📚 Documentation improvements
- 🧪 Test coverage
- 🚀 Performance optimizations
- 🌐 Platform compatibility (Windows, macOS, Linux)
Please read our Code of Conduct before contributing. We are committed to providing a welcoming and inclusive environment for all contributors.
If you discover a security vulnerability, please follow our Security Policy for responsible disclosure.
This project is licensed under the MIT License - see the LICENSE file for details.