Skip to content

Commit 7533549

Browse files
locchhclaude
andcommitted
Add cex shorthand command and CLAUDE.md
- Add `cex` as an alias entry point alongside `commit-explorer` in pyproject.toml - Add CLAUDE.md with project guidance for Claude Code Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b80b698 commit 7533549

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Commands
6+
7+
```bash
8+
# Install dependencies
9+
uv sync
10+
11+
# Run the application
12+
uv run commit-explorer [owner/repo] [--depth N] [--export]
13+
14+
# Examples
15+
uv run commit-explorer # Interactive mode
16+
uv run commit-explorer torvalds/linux --depth 100
17+
uv run commit-explorer owner/repo --export # Print graph to stdout
18+
```
19+
20+
## Architecture
21+
22+
The entire application lives in a single file: `app.py` (~890 lines).
23+
24+
### Layers
25+
26+
1. **Git Providers** (`GitHubProvider`, `GitLabProvider`, `AzureDevOpsProvider`) — subclasses of `GitProvider` ABC. Each builds authenticated clone URLs and browser commit URLs from environment tokens.
27+
28+
2. **`_GitBackend`** — manages git operations via Dulwich (pure-Python git):
29+
- `load(url, depth)` — bare-clones with `filter=blob:none` (no blobs, just commits+trees) into a temp dir
30+
- `_extract_commits()` — walks the DAG, returns `CommitInfo` namedtuples
31+
- `get_detail(sha)` — on-demand: computes file diffs using `tree_changes()` + `difflib.unified_diff()`
32+
- Pagination: 30 commits per page
33+
34+
3. **`_build_graph_from_git()`** — renders the commit graph by running `git log --graph --color=always` as a subprocess. Uses `\x01`/`\x00` markers to parse commit lines vs. graph decoration lines without regex. Converts ANSI colors to Rich `Text` objects.
35+
36+
4. **Textual UI**`CommitExplorer(App)` is the root. Key widgets:
37+
- `CommitItem(ListItem)` — one row per commit (graph line + metadata)
38+
- `Splitter` / `GraphSplitter` — draggable dividers for resizing panels
39+
- Background work via Textual's `@work` decorator; spinner shown during clone/fetch
40+
41+
### Data Flow
42+
43+
```
44+
User input (owner/repo + provider)
45+
→ _fetch_commits() [@work, async]
46+
→ GitProvider builds URL
47+
→ _GitBackend.load() clones repo
48+
→ _build_graph_from_git() renders graph
49+
→ ListView populated (30 at a time)
50+
→ User selects commit
51+
→ _fetch_detail() [@work, async]
52+
→ _GitBackend.get_detail(sha)
53+
→ Detail panel updates
54+
```
55+
56+
### Core Types (NamedTuples)
57+
58+
- `CommitInfo` — sha, short_sha, message, author, author_email, date, parents
59+
- `FileChange` — filename, status, additions, deletions
60+
- `CommitDetail` — info, stats, files, refs, linked_prs
61+
- `RepoInfo` — description, default_branch, language, stars, forks, branches, total_commits
62+
63+
## Environment Variables
64+
65+
Copy `.env.example` to `.env` for provider authentication:
66+
67+
```bash
68+
GITHUB_TOKEN=...
69+
GITLAB_TOKEN=...
70+
GITLAB_URL=https://gitlab.com # or custom self-hosted
71+
AZURE_DEVOPS_TOKEN=...
72+
AZURE_DEVOPS_ORG=...
73+
GIT_SSL_NO_VERIFY=1 # bypass SSL cert verification (corporate proxies)
74+
```
75+
76+
## Key Behaviors
77+
78+
- **Shallow clone optimization**: Uses `filter=blob:none` — file content is never fetched, only commits and trees. This makes large repos fast to load.
79+
- **SSL bypass**: When `GIT_SSL_NO_VERIFY=1` is set, a custom `urllib3.PoolManager` with `cert_reqs=ssl.CERT_NONE` is passed to Dulwich's `porcelain.clone()`.
80+
- **Graph rendering**: Avoids custom graph.c port — delegates entirely to subprocess `git log --graph`. NUL-delimited markers extract structured fields without regex parsing.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dependencies = [
1212

1313
[project.scripts]
1414
commit-explorer = "app:main"
15+
cex = "app:main"
1516

1617
[build-system]
1718
requires = ["hatchling"]

0 commit comments

Comments
 (0)