Note
GitHub users - this project is maintained over on GitLab.
Lost work due to a corrupted drive or dead SSD/HDD? Cry no more - the data is gone, but you've learned your lesson about not pushing for days on end. Now you need a daily local git repository audit tool.
On each login it scans every git repository under ~/git/ (or your preferred
location) and reports anything that could be lost in a storage failure:
uncommitted changes, untracked files, stashes, unpushed branches, unpushed
tags, and repositories with no remote configured. Results are written as a
dated report to ~/git/reports/ by default (configurable via export_path).
If nothing is wrong, no report is created. Old reports are pruned
automatically once they exceed the configured retention period.
Please note these are production requirements, that is to say requirements for the end user system. For the developer requirements please refer to Dev environment section, in the CONTRIBUTING.md.
- Any Windows, and Linux desktop (X11 or Wayland)
gitinPATH
No Python, no system packages. The binary is self-contained.
Download the latest binary from the Releases page and run it:
./git-sentinelOn the first run the binary detects it is not yet installed and sets itself up:
- Copies itself to
~/.local/bin/git-sentinel - Seeds
~/.config/git-sentinel/with a defaultsettings.ini - Registers an XDG autostart entry so it runs on every login
- Adds an app launcher entry so it can be opened from your app menu
Then exits. From that point git-sentinel is on your PATH and will run at
every login automatically.
To reinstall or upgrade - download the new binary and run it with --install:
./git-sentinel --installAfter installation, the next login opens a small desktop window:
- A status bar and progress bar show the current scan stage.
- A log pane shows real-time output as each repository is checked.
- For SSH remotes, a prompt appears asking whether to approve an SSH
connection to that host. Approving once per host is enough for the session -
subsequent remotes on the same host reuse an SSH ControlMaster socket so you
are not prompted (or asked to authenticate) again. (Linux only - see the
[ssh]note below.)
When the scan finishes:
| Result | Status message | Button |
|---|---|---|
| Issues found | Acknowledge & Close + Open Report | |
| All clear | ✔️ All clear - no issues found. | Close |
On a clean run, no new report is written - only the "All clear" status message
is shown. Reports already in export_path older than retention_days are
still pruned automatically, regardless of whether today's run found issues.
If once_per_day is enabled (the default), subsequent logins on the same
calendar day exit silently without opening a window.
The active config lives at ~/.config/git-sentinel/settings.ini. A commented
reference copy is kept at ~/.config/git-sentinel/settings.example.ini.
Edit the active file with any text editor; changes take effect on the next run.
All path values are relative to your home directory unless they begin with /.
| Key | Default | Description |
|---|---|---|
git_root |
git |
Root directory scanned recursively for git repositories (~/git/) |
export_path |
git/reports |
Directory where reports are written. Comment out or empty this key to fall back to XDG_DESKTOP_DIR (or ~/Desktop) instead. (Replaces deprecated desktop_override) |
reports_archive |
- | Deprecated - no longer used. Carry any custom value over to export_path. |
| Key | Default | Description |
|---|---|---|
retention_days |
14 |
Number of days to keep report files locally before they are removed. (Replaces deprecated desktop_retention_days) |
report_extension |
log |
File extension for report files (.log opens well in most editors) |
| Key | Default | Description |
|---|---|---|
stale_threshold_days |
90 |
A repo with no commits newer than this many days is flagged as stale |
| Key | Default | Description |
|---|---|---|
once_per_day |
true |
When true, only one scan runs per calendar day; use --force to bypass |
| Key | Default | Description |
|---|---|---|
use_control_master |
true |
Multiplex SSH so each host needs only one authentication per session |
control_persist_seconds |
300 |
How long (seconds) to keep an idle ControlMaster socket alive |
Note
SSH ControlMaster multiplexing is a Linux-only feature as Windows doesn't support it yet. On Windows both keys above have no effect and every remote check authenticates separately.
Finds all directories containing a .git folder under git_root, sorted
alphabetically.
For each repository:
- Checks for uncommitted changes and untracked files via
git status --porcelain - Lists stashes via
git stash list - Checks staleness via
git log --all - For each remote, calls
git ls-remote --heads --tagsand compares the results against local branches and tags
SSH remotes prompt for approval in the GUI (once per host per session). HTTP remotes that fail offer a one-time retry prompt.
Compares today's findings against the previous report to split issues into
[persistent_issues] (seen before) and [new_issues] (first occurrence).
Writes the report to export_path if any issues are found; otherwise nothing
is written. Either way, reports in export_path older than retention_days
are pruned.
For repositories with both origin and upstream remotes (e.g. a FOSS fork
where origin is your personal fork), work is considered safe as long as it is
present in origin. Missing from upstream alone does not raise a flag.
Reports are plain-text INI-style files. A typical report looks like:
[report]
date = 2026-06-11
time = 08:30:15
generated_by = git-sentinel v1.1.0
total_repos = 8
repos_with_issues = 2
repos_passed = 5
stale_repos = 1
[new_issues]
; Issues not present in the previous report
~/git/work-project|uncommitted|M src/auth.py
~/git/work-project|branch|fix/login|origin|not_in_origin
[persistent_issues]
; Issues from the previous report still unresolved today
~/git/work-project|untracked|scratch.py
[uncommitted]
; Staged or modified tracked files not yet committed
~/git/work-project
M src/auth.py
[untracked]
; Non-ignored files not yet added and committed
~/git/work-project
scratch.py
[unpushed_branches]
~/git/work-project
fix/login → not in origin (2 commit(s))
[stale]
; Repositories with no commits in the last 90 day(s)
~/git/old-experiment (last commit: 2025-12-01, 192 day(s) ago)
[passed]
; Repositories with no issues detected this run
~/git/main-project
~/git/dotfiles
~/git/scripts
~/git/notes
~/git/personal-siteAlongside the .log file a .issues sidecar is written containing the raw
issue keys used to classify findings as new or persistent on the next run.
- Reports are written to
export_pathand kept forretention_days(default 14) days, after which they are removed.
| Path | Purpose |
|---|---|
~/.local/bin/git-sentinel |
Binary |
~/.config/git-sentinel/settings.ini |
Active configuration |
~/.config/git-sentinel/settings.example.ini |
Reference copy (do not edit) |
~/.config/autostart/git-sentinel.desktop |
XDG autostart entry |
~/.local/share/applications/git-sentinel.desktop |
App launcher entry |
~/.local/share/icons/hicolor/scalable/apps/git-sentinel.svg |
App icon |
~/.local/share/git-sentinel/ |
State directory (daily lock file) |
~/git/reports/*-git-status-report.log |
Reports (default export_path) |
~/git/reports/*-git-status-report.issues |
Issue key sidecars |
git-sentinel --uninstallYou will be asked whether to also remove ~/.config/git-sentinel/ and the
state directory. Reports in export_path are always left in place.
See CONTRIBUTING.md for the dev setup, commit conventions, test suite, and release process.