Git-integrated time tracking for developers. No timers. No manual input. Just code.
Hourgit tracks your working time automatically by hooking into git's checkout events. When you switch branches, Hourgit starts attributing time to the new branch. Your configured working hours act as the boundary — so overnight gaps, weekends, and days off are handled automatically without any extra input from you.
Each unit of logged time is called a log entry, identified by a short hash (similar to git commits). The data model is intentionally flat: a log entry is a time range + optional description + optional metadata (branch, project, task label). There is no hierarchy beyond project — grouping is derived at report time, not stored structurally.
Manual logging is supported for non-code work (research, analysis, meetings) via explicit commands.
- Installation
- Quick Start
- Commands
- Time Tracking — init, log, edit, remove, sync, report, history, status
- Project Management — project add/assign/edit/list/remove
- Schedule Configuration — project schedule get/set/reset/report
- Default Schedule — defaults schedule get/set/reset/report
- Shell Completions — completion install/generate
- Other — version, watch
- Precise Mode
- Configuration
- Data Storage
- Roadmap
- Sponsor
- License
curl -fsSL https://hourgit.com/install.sh | bashThis downloads the latest release, verifies the checksum, and installs to ~/.hourgit/bin/ with a symlink in ~/.local/bin/. No sudo required.
Download the latest binary for your platform from the Releases page.
# Apple Silicon (M1/M2/M3/M4)
chmod +x hourgit-darwin-arm64-*
sudo mv hourgit-darwin-arm64-* /usr/local/bin/hourgit
# Intel
chmod +x hourgit-darwin-amd64-*
sudo mv hourgit-darwin-amd64-* /usr/local/bin/hourgit# x86_64
chmod +x hourgit-linux-amd64-*
sudo mv hourgit-linux-amd64-* /usr/local/bin/hourgit
# ARM64
chmod +x hourgit-linux-arm64-*
sudo mv hourgit-linux-arm64-* /usr/local/bin/hourgitMove hourgit-windows-amd64-*.exe to a directory in your PATH and rename it to hourgit.exe.
hourgit version-
Install the hook in your git repository:
hourgit init
-
Work normally — time tracks automatically on every
git checkout. -
Log non-git work manually:
hourgit log add --duration 1h30m "standup" hourgit log add --from 9am --to 10:30am "standup"
-
View the interactive report:
hourgit report
Navigate with arrow keys, press
eto edit entries,ato add new ones. Checkout-derived time appears automatically (marked with*). Presssto submit the period — this persists all generated entries and marks the period as complete. -
Export a PDF for sharing:
hourgit report --export pdf
Core commands for recording, viewing, and managing your time entries.
Commands: init · log add · log edit · log remove · sync · report · history · status
Initialize Hourgit in the current git repository by installing a post-checkout hook.
hourgit init [--project <name>] [--mode <mode>] [--force] [--append] [--yes]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Assign repository to a project by name or ID (creates if needed) |
-m, --mode |
standard |
Tracking mode: standard or precise (enables filesystem watcher for idle detection) |
-f, --force |
false |
Overwrite existing post-checkout hook |
-a, --append |
false |
Append to existing post-checkout hook |
-y, --yes |
false |
Skip confirmation prompt |
Manually log time for a project. Uses a hybrid mode: provide any combination of flags and you'll be prompted only for the missing pieces.
hourgit log add [MESSAGE] [--duration <dur>] [--from <time>] [--to <time>] [--date <date>] [--task <label>] [--project <name>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
-d, --duration |
— | Duration to log (e.g. 30m, 3h, 1d3h30m) |
-F, --from |
— | Start time (e.g. 9am, 14:00) |
-T, --to |
— | End time (e.g. 5pm, 17:00) |
-D, --date |
today | Date to log for (YYYY-MM-DD) |
-t, --task |
— | Task label for this entry |
--durationand--from/--toare mutually exclusive. A message is always required (prompted if not provided).
Examples
# Fully specified — no prompts
hourgit log add --duration 3h "did some work"
hourgit log add --from 9am --to 12pm "morning work"
hourgit log add --duration 3h --date 2025-01-10 "forgot to log"
# Partial flags — prompted for the rest
hourgit log add --duration 3h # prompted for message
hourgit log add --from 9am # prompted for --to and message
hourgit log add "meeting notes" # prompted for time mode and inputs
# Fully interactive
hourgit log addEdit an existing log entry by its hash. When edit flags are provided, only those changes are applied directly. Without flags, an interactive editor opens with current values pre-filled.
hourgit log edit <hash> [--duration <dur>] [--from <time>] [--to <time>] [--date <date>] [--task <label>] [-m <msg>] [--project <name>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
-d, --duration |
— | New duration (e.g. 30m, 3h, 3h30m) |
-F, --from |
— | New start time (e.g. 9am, 14:00) |
-T, --to |
— | New end time (e.g. 5pm, 17:00) |
-D, --date |
— | New date (YYYY-MM-DD) |
-t, --task |
— | New task label (empty string clears it) |
-m, --message |
— | New message |
-y, --yes |
false |
Skip confirmation prompt |
Any combination of
--duration,--from, and--tois allowed. With two flags, the third is computed. With all three, they must be consistent (to - from = duration).--fromonly: keeps duration, shifts the time window.--toonly: keeps start, recalculates duration.--durationonly: keeps start, shifts end. Entry ID and creation timestamp are preserved. If the entry is not found in the current repo's project, all projects are searched.
Examples
hourgit log edit abc1234 --duration 3h
hourgit log edit abc1234 --from 9am --to 12pm
hourgit log edit abc1234 --task "reviews"
hourgit log edit abc1234 -m "updated message"
hourgit log edit abc1234 # interactive modeRemove a log or checkout entry by its hash.
hourgit log remove <hash> [--project <name>] [--yes]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
-y, --yes |
false |
Skip confirmation prompt |
Works with both log and checkout entries (unlike
log edit, which only supports log entries). Shows entry details and asks for confirmation before deleting. If the entry is not found in the current repo's project, all projects are searched.
Sync branch checkouts and commits from git reflog. Called automatically by the post-checkout hook, or run manually to backfill history. Commits are used to split checkout sessions into finer time blocks with commit messages.
hourgit sync [--project <name>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
Interactive time report with inline editing. Shows tasks (rows) × days (columns) with time attributed from branch checkouts, commits, and manual log entries. Checkout sessions are automatically split by commits, showing commit messages in a detail panel below the table.
hourgit report [--month <1-12>] [--week <1-53>] [--year <YYYY>] [--project <name>] [--export <format>] [--detail <level>]| Flag | Default | Description |
|---|---|---|
-m, --month |
current month | Month number 1-12 |
-w, --week |
— | ISO week number 1-53 |
-y, --year |
current year | Year (complementary to --month or --week) |
-p, --project |
auto-detect | Project name or ID |
-e, --export |
— | Export format (pdf); auto-generates filename based on period |
-d, --detail |
summary |
Export detail level: summary (one row per task) or full (individual entries with commit messages) |
--monthand--weekcannot be used together.--yearalone is not valid — it must be paired with--monthor--week. Neither flag defaults to the current month.
Interactive table keybindings:
| Key | Action |
|---|---|
←/→/↑/↓ or h/l/k/j |
Navigate cells |
Tab or ] / Shift+Tab or [ |
Cycle through entries in selected cell |
e |
Edit selected cell entry |
a |
Add a new entry to selected cell |
r or Del |
Remove entry from selected cell |
s |
Submit period (persists all generated entries) |
q or Esc |
Quit |
In-memory generated entries (from checkout attribution) are marked with * in the table. Editing a generated entry persists it immediately. Submitting persists all remaining generated entries and creates a submit marker.
Previously submitted periods show a warning banner and can be re-edited and re-submitted. In non-interactive environments (piped output), a static table is printed instead.
Examples
hourgit report # current month, interactive
hourgit report --week 8 # ISO week 8
hourgit report --export pdf # export PDF (<project>-<YYYY>-month-<MM>.pdf)
hourgit report --export pdf --week 8 # export PDF (<project>-<YYYY>-week-<WW>.pdf)
hourgit report --export pdf --month 1 --year 2025Show a chronological feed of all recorded activity (log entries and checkout events), newest first.
hourgit history [--project <name>] [--limit <N>]| Flag | Default | Description |
|---|---|---|
-p, --project |
all projects | Filter by project name or ID |
-l, --limit |
50 |
Maximum number of entries to show (use 0 for all) |
Each line shows the entry hash, timestamp, type (log or checkout), project name, and details. Log entries display duration + task label (if set) + message. Checkout entries display previous branch → next branch.
Show current tracking status — project, branch, time logged today, and schedule state.
hourgit status [--project <name>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
Output includes:
- Current project and branch
- Time since last checkout
- Time logged today and remaining scheduled hours
- Today's schedule windows
- Tracking state (active/inactive based on current time vs schedule)
- Watcher state (when precise mode is enabled: active/stopped)
Group repositories into projects for organized time tracking.
Commands: project add · project assign · project edit · project list · project remove
Create a new project.
hourgit project add <name> [--mode <mode>]| Flag | Default | Description |
|---|---|---|
-m, --mode |
standard |
Tracking mode: standard or precise (enables filesystem watcher for idle detection) |
Assign the current repository to a project. The project name is optional — if omitted, the project is auto-detected from the current repository.
hourgit project assign [PROJECT] [--project <name>] [--force] [--yes]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID (alternative to positional argument) |
-f, --force |
false |
Reassign repository to a different project |
-y, --yes |
false |
Skip confirmation prompt |
Edit an existing project's name or tracking mode. When edit flags are provided, only those changes are applied directly. Without flags, an interactive editor prompts for both name and mode.
hourgit project edit [PROJECT] [--name <new_name>] [--mode <mode>] [--idle-threshold <minutes>] [--project <name>] [--yes]| Flag | Default | Description |
|---|---|---|
-n, --name |
— | New project name |
-m, --mode |
— | New tracking mode: standard or precise |
-t, --idle-threshold |
— | Idle threshold in minutes (precise mode only) |
-p, --project |
auto-detect | Project name or ID (alternative to positional argument) |
-y, --yes |
false |
Skip confirmation prompt |
PROJECTis an optional positional argument (project name or ID). Falls back to--projectflag or the current repository's project.
Examples
hourgit project edit myproject --name newname
hourgit project edit myproject --mode precise
hourgit project edit myproject --idle-threshold 15
hourgit project edit --name newname --project myproject
hourgit project edit myproject # interactive modeList all projects and their repositories.
hourgit project listNo flags.
Remove a project and clean up its repository assignments. The project name is optional — if omitted, the project is auto-detected from the current repository.
hourgit project remove [PROJECT] [--project <name>] [--yes]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID (alternative to positional argument) |
-y, --yes |
false |
Skip confirmation prompt |
Manage per-project schedule configuration. If --project is omitted, the project is auto-detected from the current repository.
Commands: project schedule get · project schedule set · project schedule reset · project schedule report
Show the schedule configuration for a project.
hourgit project schedule get [--project <name>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
Interactively edit a project's schedule using a guided schedule builder.
hourgit project schedule set [--project <name>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
Reset a project's schedule to the defaults.
hourgit project schedule reset [--project <name>] [--yes]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
-y, --yes |
false |
Skip confirmation prompt |
Show expanded working hours for a given month (resolves schedule rules into concrete days and time ranges).
hourgit project schedule report [--project <name>] [--month <1-12>] [--year <YYYY>]| Flag | Default | Description |
|---|---|---|
-p, --project |
auto-detect | Project name or ID |
-m, --month |
current month | Month number 1-12 |
-y, --year |
current year | Year |
Manage the default schedule applied to new projects.
Commands: defaults schedule get · defaults schedule set · defaults schedule reset · defaults schedule report
Show the default schedule for new projects.
hourgit defaults schedule getNo flags.
Interactively edit the default schedule for new projects.
hourgit defaults schedule setNo flags.
Reset the default schedule to factory settings (Mon-Fri, 9 AM - 5 PM).
hourgit defaults schedule reset [--yes]| Flag | Default | Description |
|---|---|---|
-y, --yes |
false |
Skip confirmation prompt |
Show expanded default working hours for a given month.
hourgit defaults schedule report [--month <1-12>] [--year <YYYY>]| Flag | Default | Description |
|---|---|---|
-m, --month |
current month | Month number 1-12 |
-y, --year |
current year | Year |
Set up tab completions for your shell. Supported shells: bash, zsh, fish, powershell.
Commands: completion install · completion generate
Install shell completions into your shell config file. Auto-detects your shell if not specified.
hourgit completion install [SHELL] [--yes]| Flag | Default | Description |
|---|---|---|
-y, --yes |
false |
Skip confirmation prompt |
Generate a shell completion script. If no shell is specified, Hourgit auto-detects it from the $SHELL environment variable.
hourgit completion generate [SHELL]No flags.
Shell completions are also offered automatically during hourgit init.
Examples
# zsh (~/.zshrc)
eval "$(hourgit completion generate zsh)"
# bash (~/.bashrc)
eval "$(hourgit completion generate bash)"
# fish (~/.config/fish/config.fish)
hourgit completion generate fish | sourceCommands: version · update · watch
Print version information.
hourgit versionNo flags.
Check for and install updates. Always checks the latest version from GitHub, bypassing the cache TTL used by the automatic update check.
hourgit updateNo flags.
Run the filesystem watcher daemon in the foreground. The daemon monitors file changes in repositories with precise mode enabled and writes activity entries to detect idle gaps. Normally managed automatically as an OS service — use this command for debugging or manual operation.
hourgit watchNo flags.
These flags are available on all commands.
| Flag | Description |
|---|---|
--skip-updates |
Skip the automatic update check |
--skip-watcher |
Skip the file watcher health check |
By default, Hourgit attributes all time between branch checkouts (within your schedule) as work. Precise mode adds filesystem-level idle detection: a background daemon watches your repository for file changes and records when you stop and resume working.
- A background daemon watches file changes in your repository (excluding
.git/and.gitignorepatterns). - After a configurable idle threshold (default: 10 minutes) with no file changes, the daemon records an
activity_stopentry. - When file changes resume, the daemon records an
activity_startentry. - At report time, these idle gaps are trimmed from checkout sessions, giving you more accurate time attribution.
# During init
hourgit init --mode precise
# When adding a project
hourgit project add myproject --mode preciseWhen precise mode is enabled, Hourgit automatically installs a user-level OS service (launchd on macOS, systemd on Linux, Task Scheduler on Windows) to run the watcher daemon. No sudo required.
Hourgit checks whether the watcher daemon is running on every command. If it's stopped, you'll be prompted to restart it. The status command shows the current watcher state when precise mode is enabled.
Hourgit uses a schedule system to define working hours. The factory default is Monday-Friday, 9 AM - 5 PM.
The interactive schedule editor (project schedule set / defaults schedule set) supports three schedule types:
- Recurring — repeats on a regular pattern (e.g., every weekday, every Monday/Wednesday/Friday)
- One-off — applies to a single specific date (e.g., a holiday or overtime day)
- Date range — applies to a contiguous range of dates (e.g., a week with different hours)
Each schedule entry defines one or more time ranges for the days it covers. Multiple entries can be combined to build complex schedules.
Every project starts with a copy of the defaults. You can then customize a project's schedule independently using hourgit project schedule set --project NAME. To revert a project back to the current defaults, use hourgit project schedule reset --project NAME.
| Path | Purpose |
|---|---|
~/.hourgit/config.json |
Global config — defaults, projects (id, name, slug, repos, schedules) |
REPO/.git/.hourgit |
Per-repo project assignment (project name + project ID) |
~/.hourgit/<slug>/<hash> |
Per-project entries (one JSON file per entry — log, checkout, commit, submit, activity_stop, activity_start) |
~/.hourgit/watch.pid |
PID file for the filesystem watcher daemon (precise mode) |
~/.hourgit/watch.state |
Watcher state file — last activity timestamps per repo (precise mode) |
Planned features:
- Exporters — export time data to platforms like Jira, Toggl, Clockify, and Harvest
- Web app — browser-based interface for viewing and managing time entries
- GUI — potentially add a graphical interface on macOS, Linux, and Windows
Have an idea? Open an issue.
Hourgit is free and open-source software. Sponsorship funds continued development and maintenance, cross-platform testing and releases, and helps keep the project free for everyone.
| Tier | Amount | Description |
|---|---|---|
| Base | $5/mo | Support continued development |
| Pro | $25/mo | Fund cross-platform testing and releases |
| Enterprise | $100/mo | Help shape the roadmap and keep Hourgit free |
This project is licensed under the GNU General Public License v3.0.