Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ Issues are grouped into Milestones for organizational purposes.
| [`ghqc auth status`](docs/auth.md) | Display stored tokens and auth source resolution for the selected host |
| [`ghqc auth token`](docs/auth.md) | Print the resolved token for the selected host |

### Cache

`ghqc` keeps a small on-disk cache (per-commit file changes, issue comments/events, repo users and labels) under `~/.cache/ghqc/<owner>/<repo>/`.

| Command | Description |
|---|---|
| [`ghqc cache status`](docs/cache.md) | Show cache root, total size, TTL, and per-element sizes for the current repo |
| [`ghqc cache dir`](docs/cache.md) | Print the cache directory for the current repo (or `--global` for the root) |
| [`ghqc cache remove`](docs/cache.md) | Remove cached data for the current repo, a single element, or globally |

### Diagnostics

| Command | Description |
Expand Down
112 changes: 112 additions & 0 deletions docs/cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Cache

`ghqc` keeps a small on-disk cache of GitHub data and per-commit file-change records to speed up repeated operations. The cache lives under the system cache directory (typically `~/.cache/ghqc` on Linux/macOS via XDG; honors `XDG_CACHE_HOME`) and is namespaced per repository as `<root>/<owner>/<repo>/`.

Within a repository's cache directory, data is grouped by **element**:

| Element | Contents |
|---|---|
| `commits` | Per-commit file-change records (drives the "commits that changed file X" list) |
| `issues` | Issue comments and events |
| `users` | Repo assignees and user details |
| `labels` | Repo labels |

TTL defaults to 1 hour (3600s). Override with the `GHQC_CACHE_TIMEOUT` environment variable (in seconds). Some entries (issue comments/events, user details) are stored without a TTL and refresh based on GitHub-side timestamps instead.

## Status

```shell
ghqc cache status
```

Show the cache root, total size, configured TTL, and a per-element table for the current repo.

### Example output

```
── Cache ─────────────────────────────────────
root: /home/user/.cache/ghqc
size: 1.4 MB (87 files)
ttl: 3600s (default; override with GHQC_CACHE_TIMEOUT)
── Repository ────────────────────────────────
repo: A2-ai/ghqctoolkit
path: /home/user/.cache/ghqc/A2-ai/ghqctoolkit

element size files
------- ---- -----
commits 612.4 KB 12
issues 780.2 KB 64
users 3.1 KB 2
labels — —
```

When run outside a git repository, only the global section is shown.

## Dir

```shell
ghqc cache dir [--global]
```

Print the cache directory for the current repo (default) or the cache root (`--global`). Useful for piping into other tools, e.g. `du -sh "$(ghqc cache dir)"`.

Aliases: `ghqc cache directory`.

### Examples

```shell
# Per-repo cache directory
ghqc cache dir
# /home/user/.cache/ghqc/A2-ai/ghqctoolkit

# Cache root
ghqc cache dir --global
# /home/user/.cache/ghqc
```

When run outside a git repository, the per-repo form errors; pass `--global` instead.

## Remove

```shell
ghqc cache remove [ELEMENT] [--global]
```

Remove cached data from disk. The cache is reconstructible — entries will be re-fetched on next use — so deletion is safe. The command prints what was removed and exits 0 even if no matching entries existed.

Aliases: `ghqc cache rm`.

### Behavior

| Invocation | Effect |
|---|---|
| `ghqc cache remove` | Remove the entire per-repo cache for the current repo |
| `ghqc cache remove <element>` | Remove just `<element>` for the current repo |
| `ghqc cache remove --global` | Wipe the entire `ghqc` cache directory (all repos, all elements) |
| `ghqc cache remove <element> --global` | Remove `<element>` for **every** repo under the cache root |

When run outside a git repository, the repo-scoped forms error; use `--global` instead.

### Examples

```shell
# Drop just the commits cache for this repo (e.g. after a force-push or rebase)
ghqc cache remove commits

# Drop everything cached for this repo
ghqc cache remove

# Drop the labels cache for every repo on this machine
ghqc cache remove labels --global

# Wipe the entire ghqc cache
ghqc cache remove --global
```

### When to clear

In normal use the cache refreshes itself on TTL expiry or when GitHub-side timestamps change. You typically only need to clear it when:

- A `ghqc` upgrade changes how something is cached and you want the new logic applied immediately to already-cached commits/issues.
- A force-push or rebase rewrote history and the per-commit cache no longer reflects the branch.
- You're debugging unexpected behavior and want to rule out a stale cache.
9 changes: 7 additions & 2 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ impl DiskCache {

/// Create a new DiskCache instance using the system cache directory
pub fn new(owner: String, repo: String) -> Result<Self, Box<dyn std::error::Error>> {
let strategy = etcetera::choose_base_strategy()?;
let root = strategy.cache_dir().join("ghqc");
let root = cache_root()?;
let ttl = default_ttl();

Ok(Self {
Expand Down Expand Up @@ -191,6 +190,12 @@ impl DiskCache {
}
}

/// Path of the on-disk cache root (`<system-cache-dir>/ghqc`).
pub fn cache_root() -> Result<PathBuf, Box<dyn std::error::Error>> {
let strategy = etcetera::choose_base_strategy()?;
Ok(strategy.cache_dir().join("ghqc"))
}

/// Get the default cache TTL from environment or use 1 hour default
fn default_ttl() -> Duration {
let ttl_seconds = std::env::var("GHQC_CACHE_TIMEOUT")
Expand Down
Loading
Loading