git-graphable 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- git_graphable-0.2.0/.gemini/GEMINI.md +8 -0
- git_graphable-0.2.0/.gemini/code-ordering.md +86 -0
- git_graphable-0.2.0/.github/dependabot.yml +23 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/.github/workflows/ci.yml +8 -3
- {git_graphable-0.1.0 → git_graphable-0.2.0}/.github/workflows/publish.yml +3 -2
- {git_graphable-0.1.0 → git_graphable-0.2.0}/.gitignore +7 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/Justfile +24 -2
- git_graphable-0.2.0/PKG-INFO +166 -0
- git_graphable-0.2.0/README.md +150 -0
- git_graphable-0.2.0/SECURITY.md +14 -0
- git_graphable-0.2.0/USAGE.md +52 -0
- git_graphable-0.2.0/examples/EXAMPLES.md +221 -0
- git_graphable-0.2.0/examples/generate_demos.py +198 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/pyproject.toml +6 -2
- git_graphable-0.2.0/src/git_graphable/cli.py +658 -0
- git_graphable-0.2.0/src/git_graphable/commands.py +100 -0
- git_graphable-0.2.0/src/git_graphable/core.py +229 -0
- git_graphable-0.2.0/src/git_graphable/github.py +77 -0
- git_graphable-0.2.0/src/git_graphable/highlighter.py +475 -0
- git_graphable-0.2.0/src/git_graphable/hygiene.py +139 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/src/git_graphable/models.py +15 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/src/git_graphable/styler.py +120 -11
- {git_graphable-0.1.0 → git_graphable-0.2.0}/tests/test_cli.py +1 -0
- git_graphable-0.2.0/tests/test_config.py +105 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/tests/test_core.py +29 -3
- git_graphable-0.2.0/tests/test_github.py +56 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/tests/test_highlighter.py +57 -3
- git_graphable-0.2.0/tests/test_hygiene.py +284 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/tests/test_styler.py +1 -1
- {git_graphable-0.1.0 → git_graphable-0.2.0}/uv.lock +1 -1
- git_graphable-0.1.0/PKG-INFO +0 -108
- git_graphable-0.1.0/README.md +0 -92
- git_graphable-0.1.0/USAGE.md +0 -35
- git_graphable-0.1.0/src/git_graphable/cli.py +0 -398
- git_graphable-0.1.0/src/git_graphable/core.py +0 -127
- git_graphable-0.1.0/src/git_graphable/highlighter.py +0 -203
- {git_graphable-0.1.0 → git_graphable-0.2.0}/.python-version +0 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/src/git_graphable/__init__.py +0 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/src/git_graphable/parser.py +0 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/tests/test_models.py +0 -0
- {git_graphable-0.1.0 → git_graphable-0.2.0}/tests/test_parser.py +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Gemini Instructions
|
|
2
|
+
- Always execute `just test` instead of `pytest` for running tests. Any arguments you specify will be passed through to the wrapped `pytest` command. For example, you may wish to pass `-n 0 -p no:sugar` to disable the xdist and sugar plugins.
|
|
3
|
+
- Always execute `just coverage` instead of `pytest` for coverage.
|
|
4
|
+
- When adding, removing, or modifying code, adhere to the code ordering guidelines in @./code-ordering.md
|
|
5
|
+
- Always execute `just check` before committing any changes to ensure linting, typing, and coverage standards are met.
|
|
6
|
+
- Always execute `just lint` after finishing code changes and address any issues flagged.
|
|
7
|
+
- Do not use `pip` or `venv` directly; use `uv` for all environment management.
|
|
8
|
+
- Do not stage or commit any changes unless explicitly instructed. When instructed to commit or push changes, you MUST first create a new feature branch and then execute `just pr <title> [body]` to prepare the pull request. If a pull request already exists for the current feature branch, push your updates to the same branch instead of creating a new pull request.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Python Code Ordering Guidelines
|
|
2
|
+
|
|
3
|
+
Please ensure all Python files adhere to the following structure and ordering conventions:
|
|
4
|
+
|
|
5
|
+
## Module-Level Ordering
|
|
6
|
+
|
|
7
|
+
The sequence of elements at the top level of a Python module should be:
|
|
8
|
+
|
|
9
|
+
1. **Module-level Docstrings:** A concise description of the file's purpose.
|
|
10
|
+
```python
|
|
11
|
+
"""
|
|
12
|
+
This module provides utility functions for path manipulation.
|
|
13
|
+
"""
|
|
14
|
+
```
|
|
15
|
+
2. **Imports:** Grouped in a specific order:
|
|
16
|
+
* **Standard Library Imports:** (e.g., `os`, `sys`, `datetime`)
|
|
17
|
+
```python
|
|
18
|
+
import os
|
|
19
|
+
import sys
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
```
|
|
22
|
+
* **Third-Party Library Imports:** (e.g., `requests`, `numpy`)
|
|
23
|
+
```python
|
|
24
|
+
import requests
|
|
25
|
+
import numpy as np
|
|
26
|
+
```
|
|
27
|
+
* **Local Application Imports:** Imports from your project's own modules.
|
|
28
|
+
```python
|
|
29
|
+
from . import utils
|
|
30
|
+
from ..core import models
|
|
31
|
+
```
|
|
32
|
+
3. **Module-level Globals/Constants:** Variables declared at the module level, typically in `ALL_CAPS`.
|
|
33
|
+
```python
|
|
34
|
+
DEFAULT_TIMEOUT = 30
|
|
35
|
+
CONFIG_PATH = "/etc/myapp/config.ini"
|
|
36
|
+
```
|
|
37
|
+
4. **Classes and Functions:**
|
|
38
|
+
* Higher-level definitions should usually precede lower-level helper functions or classes.
|
|
39
|
+
* For classes, follow the "Class Internal Ordering" below.
|
|
40
|
+
* For functions, utility functions often come before main operational functions.
|
|
41
|
+
5. **Main Entry Point:** The `if __name__ == "__main__":` block, placed at the very bottom.
|
|
42
|
+
|
|
43
|
+
## Class Internal Ordering
|
|
44
|
+
|
|
45
|
+
Within a class, elements should be ordered logically and by visibility:
|
|
46
|
+
|
|
47
|
+
1. **Class Attributes:** Constants or shared state variables belonging to the class.
|
|
48
|
+
```python
|
|
49
|
+
class MyClass:
|
|
50
|
+
CLASS_CONSTANT = 100
|
|
51
|
+
```
|
|
52
|
+
2. **`__init__` Method:** The constructor.
|
|
53
|
+
```python
|
|
54
|
+
def __init__(self, value):
|
|
55
|
+
self.value = value
|
|
56
|
+
```
|
|
57
|
+
3. **Magic Methods:** Other dunder methods (e.g., `__str__`, `__repr__`, `__eq__`).
|
|
58
|
+
```python
|
|
59
|
+
def __str__(self):
|
|
60
|
+
return f"MyClass({self.value})"
|
|
61
|
+
```
|
|
62
|
+
4. **Public Methods:** The primary ways other code interacts with your class.
|
|
63
|
+
```python
|
|
64
|
+
def public_method(self):
|
|
65
|
+
# ...
|
|
66
|
+
```
|
|
67
|
+
5. **Protected and Private Methods:** Implementation details prefixed with `_` or `__` (that aren't magic methods).
|
|
68
|
+
```python
|
|
69
|
+
def _helper_method(self):
|
|
70
|
+
# ...
|
|
71
|
+
```
|
|
72
|
+
6. **Static and Class Methods:** Often placed at the end, or grouped near related public methods if they act as factory methods.
|
|
73
|
+
```python
|
|
74
|
+
@staticmethod
|
|
75
|
+
def static_method():
|
|
76
|
+
# ...
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def class_method(cls):
|
|
80
|
+
# ...
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## General Layout Principles
|
|
84
|
+
|
|
85
|
+
* **Vertical Distance:** Keep related methods close together. Use two blank lines between top-level definitions (module docstring, imports, classes, functions) and one blank line between methods within a class.
|
|
86
|
+
* **Step-Down Rule:** Place a "caller" method immediately above the "callee" method it uses. (This is more of a guideline for readability than a strict ordering rule.)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Maintain dependencies for GitHub Actions
|
|
4
|
+
- package-ecosystem: "github-actions"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
groups:
|
|
9
|
+
actions:
|
|
10
|
+
patterns:
|
|
11
|
+
- "*"
|
|
12
|
+
|
|
13
|
+
# Maintain Python dependencies
|
|
14
|
+
- package-ecosystem: "pip"
|
|
15
|
+
directory: "/"
|
|
16
|
+
schedule:
|
|
17
|
+
interval: "weekly"
|
|
18
|
+
# Since we use uv, Dependabot will look at pyproject.toml
|
|
19
|
+
open-pull-requests-limit: 5
|
|
20
|
+
groups:
|
|
21
|
+
dependencies:
|
|
22
|
+
patterns:
|
|
23
|
+
- "*"
|
|
@@ -6,15 +6,20 @@ on:
|
|
|
6
6
|
pull_request:
|
|
7
7
|
branches: [ main ]
|
|
8
8
|
|
|
9
|
+
# Grant minimal permissions by default
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
9
13
|
jobs:
|
|
10
14
|
check:
|
|
11
15
|
name: Check and Test
|
|
12
16
|
runs-on: ubuntu-latest
|
|
13
17
|
steps:
|
|
14
|
-
-
|
|
18
|
+
- name: Checkout repository
|
|
19
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
15
20
|
|
|
16
21
|
- name: Install uv
|
|
17
|
-
uses: astral-sh/setup-uv@
|
|
22
|
+
uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
|
|
18
23
|
with:
|
|
19
24
|
enable-cache: true
|
|
20
25
|
|
|
@@ -22,7 +27,7 @@ jobs:
|
|
|
22
27
|
run: uv python install 3.13
|
|
23
28
|
|
|
24
29
|
- name: Install just
|
|
25
|
-
uses: extractions/setup-just@
|
|
30
|
+
uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b # v3.1.0
|
|
26
31
|
|
|
27
32
|
- name: Run checks
|
|
28
33
|
run: just check
|
|
@@ -13,10 +13,11 @@ jobs:
|
|
|
13
13
|
id-token: write # Mandatory for trusted publishing
|
|
14
14
|
contents: read
|
|
15
15
|
steps:
|
|
16
|
-
-
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
17
18
|
|
|
18
19
|
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@
|
|
20
|
+
uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
|
|
20
21
|
with:
|
|
21
22
|
enable-cache: true
|
|
22
23
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
set dotenv-load
|
|
2
2
|
|
|
3
|
-
GIT_BRANCH:=`git branch --show-current`
|
|
4
|
-
GIT_COMMIT:=`git rev-parse HEAD`
|
|
3
|
+
GIT_BRANCH:=`git branch --show-current | xargs echo -n | grep . || echo "unknown"`
|
|
4
|
+
GIT_COMMIT:=`git rev-parse HEAD | xargs echo -n | grep . || echo "unknown"`
|
|
5
5
|
|
|
6
6
|
@_:
|
|
7
7
|
just --list
|
|
@@ -58,6 +58,7 @@ publish: build
|
|
|
58
58
|
|
|
59
59
|
[group('qa')]
|
|
60
60
|
check: lint typing coverage
|
|
61
|
+
uv run git-graphable . --check --min-score 80 --bare --highlight-wip --highlight-direct-pushes
|
|
61
62
|
|
|
62
63
|
[group('qa')]
|
|
63
64
|
@coverage *args:
|
|
@@ -87,6 +88,27 @@ testrep:
|
|
|
87
88
|
typing:
|
|
88
89
|
uv run ty check
|
|
89
90
|
|
|
91
|
+
[group('run')]
|
|
92
|
+
pr title body="":
|
|
93
|
+
#!/usr/bin/env bash
|
|
94
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
95
|
+
if [ "$CURRENT_BRANCH" == "main" ]; then
|
|
96
|
+
echo "Error: You are on the 'main' branch. Please create a feature branch first!"
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
just check
|
|
100
|
+
git push -u origin "$CURRENT_BRANCH"
|
|
101
|
+
gh pr create --repo TheTrueSCU/git-graphable --head "$CURRENT_BRANCH" --title "{{ title }}" --body "{{ body }}"
|
|
102
|
+
|
|
90
103
|
[group('run')]
|
|
91
104
|
@run *args:
|
|
92
105
|
uv run git-graphable {{ args }}
|
|
106
|
+
|
|
107
|
+
[group('demo')]
|
|
108
|
+
generate-examples:
|
|
109
|
+
uv run python examples/generate_demos.py
|
|
110
|
+
uv run git-graphable examples/repos/repo-pristine --engine mermaid -o examples/assets/pristine.mmd --highlight-critical --critical-branch main --highlight-authors --bare
|
|
111
|
+
uv run git-graphable examples/repos/repo-messy --engine mermaid -o examples/assets/messy.mmd --highlight-wip --highlight-direct-pushes --highlight-stale --bare
|
|
112
|
+
uv run git-graphable examples/repos/repo-features --engine mermaid -o examples/assets/features.mmd --highlight-orphans --highlight-diverging-from main --bare
|
|
113
|
+
uv run git-graphable examples/repos/repo-risk-silo --engine mermaid -o examples/assets/silo.mmd --highlight-silos --silo-threshold 20 --bare
|
|
114
|
+
uv run git-graphable examples/repos/repo-complex-hygiene --engine mermaid -o examples/assets/complex.mmd --highlight-back-merges --bare
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: git-graphable
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A powerful Git history visualizer and hygiene linter with CI gating.
|
|
5
|
+
Project-URL: Homepage, https://github.com/TheTrueSCU/git-graphable
|
|
6
|
+
Project-URL: Issues, https://github.com/TheTrueSCU/git-graphable/issues
|
|
7
|
+
Project-URL: Repository, https://github.com/TheTrueSCU/git-graphable
|
|
8
|
+
Author-email: Richard West <dopplereffect.us@gmail.com>
|
|
9
|
+
Keywords: analysis,ci,d2,git,git-flow,github,graph,hygiene,lint,mermaid,topology,visualization
|
|
10
|
+
Requires-Python: >=3.13
|
|
11
|
+
Requires-Dist: graphable>=0.6.0
|
|
12
|
+
Provides-Extra: cli
|
|
13
|
+
Requires-Dist: rich>=13.0.0; extra == 'cli'
|
|
14
|
+
Requires-Dist: typer>=0.12.0; extra == 'cli'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Git Graphable
|
|
18
|
+
|
|
19
|
+
A powerful Python tool to convert Git commit history into beautiful, interactive flowcharts using the `graphable` library. Supporting Mermaid, D2, Graphviz, and PlantUML.
|
|
20
|
+
|
|
21
|
+
## Git Plugin Support
|
|
22
|
+
When installed in your PATH, you can use this as a native Git plugin:
|
|
23
|
+
```bash
|
|
24
|
+
git graphable .
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- **Multi-Engine Support**: Export to Mermaid (.mmd), D2 (.d2), Graphviz (.dot), or PlantUML (.puml).
|
|
30
|
+
- **Automatic Visualization**: Generates and opens an image (SVG/PNG) automatically if no output is specified.
|
|
31
|
+
- **Advanced Highlighting**: Visualize author patterns, topological distance, and specific merge paths.
|
|
32
|
+
- **GitHub Integration**: Highlight commits based on pull request status (Merged, Open, Closed, Draft) using the `gh` CLI.
|
|
33
|
+
- **Hygiene Analysis**: Automatically detect WIP commits, direct pushes to protected branches, squashed PRs, back-merges, and contributor silos.
|
|
34
|
+
- **Health Scoring**: Get a numeric "Hygiene Score" (0-100%) with a color-coded grade and detailed breakdown of workflow anti-patterns.
|
|
35
|
+
- **CI Gating**: Use the `--check` flag to return a non-zero exit code if the hygiene score falls below a threshold (configurable via `--min-score`).
|
|
36
|
+
- **Flexible Input**: Works with local repository paths or remote Git URLs.
|
|
37
|
+
- **Dual CLI**: Modern Rich/Typer interface with a robust argparse fallback for bare environments.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Using uv (recommended)
|
|
43
|
+
uv sync --all-extras
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
For a complete reference of all command-line options, see the [USAGE.md](USAGE.md) file. For visual demonstrations of all features, see [examples/EXAMPLES.md](examples/EXAMPLES.md).
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Basic usage (opens a Mermaid image)
|
|
52
|
+
uv run git-graphable .
|
|
53
|
+
|
|
54
|
+
# Highlight PR status (requires gh CLI)
|
|
55
|
+
uv run git-graphable . --highlight-pr-status
|
|
56
|
+
|
|
57
|
+
# Specify an engine and output file
|
|
58
|
+
uv run git-graphable https://github.com/TheTrueSCU/graphable/ --engine d2 -o graph.svg
|
|
59
|
+
|
|
60
|
+
# Simplify the graph (only show branches/tags)
|
|
61
|
+
uv run git-graphable . --simplify
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Highlighting Options
|
|
65
|
+
|
|
66
|
+
Git Graphable provides several ways to highlight commits and relationships. Multiple options can be combined to layer information.
|
|
67
|
+
|
|
68
|
+
| Option | Target | Effect | Conflicts With |
|
|
69
|
+
| :--- | :--- | :--- | :--- |
|
|
70
|
+
| `--highlight-authors` | **Fill** | Unique color per author | PR Status, Distance, Stale, WIP |
|
|
71
|
+
| `--highlight-pr-status` | **Fill/Stroke**| Color by PR state (Merged=Purple, Open=Green) | Authors, Distance, Stale, WIP |
|
|
72
|
+
| `--highlight-distance-from` | **Fill** | Blue gradient fading by distance | Authors, PR Status, Stale, WIP |
|
|
73
|
+
| `--highlight-stale` | **Fill** | Gradient white to red by age | Authors, PR Status, Distance, WIP |
|
|
74
|
+
| `--highlight-wip` | **Fill** | Yellow fill for WIP/TODO commits | Authors, PR Status, Distance, Stale |
|
|
75
|
+
| `--highlight-path` | **Edge** | Thick Orange edge connecting nodes | None |
|
|
76
|
+
| `--highlight-critical` | **Stroke** | Thick Red Solid outline | None |
|
|
77
|
+
| `--highlight-diverging-from` | **Stroke** | Orange Dashed outline | None |
|
|
78
|
+
| `--highlight-orphans` | **Stroke** | Grey Dashed outline | None |
|
|
79
|
+
| `--highlight-long-running` | **Stroke/Edge** | Purple outline and thick Purple edge | None |
|
|
80
|
+
| `--highlight-direct-pushes` | **Stroke** | Thick Red Dashed outline | None |
|
|
81
|
+
| `--highlight-squashed` | **Stroke/Edge** | Grey Solid outline and dashed Grey logical merge edge | None |
|
|
82
|
+
| `--highlight-back-merges` | **Stroke** | Orange Dashed outline | None |
|
|
83
|
+
| `--highlight-silos` | **Stroke** | Blue Solid outline | None |
|
|
84
|
+
|
|
85
|
+
### Highlighting Priorities
|
|
86
|
+
- **Fill**: `--highlight-authors`, `--highlight-pr-status`, `--highlight-distance-from`, `--highlight-stale`, and `--highlight-wip` are mutually exclusive.
|
|
87
|
+
- **Edge**: Path highlighting (Thick Orange) takes priority over Long-Running highlighting (Thick Purple), which takes priority over Logical Squashed Merges (Dashed Grey).
|
|
88
|
+
- **Stroke**: Critical outlines (Thick Red Solid) take priority over Direct Pushes (Thick Red Dashed), which take priority over PR Conflicts (Thick Red Solid), which take priority over Back-Merges (Orange Dashed), which take priority over Squash Commits (Grey Solid), which take priority over Contributor Silos (Blue Solid), which take priority over all other outlines (Divergence, Orphan, Long-Running).
|
|
89
|
+
|
|
90
|
+
## Advanced Examples
|
|
91
|
+
|
|
92
|
+
### Hygiene Analysis
|
|
93
|
+
Identify problematic patterns like direct pushes to `main`, messy WIP commits, back-merges from `main`, or contributor silos:
|
|
94
|
+
```bash
|
|
95
|
+
uv run git-graphable . --highlight-direct-pushes --highlight-wip --highlight-squashed --highlight-back-merges --highlight-silos
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### PR Status Highlighting
|
|
99
|
+
View the current state of all PRs in your repository graph:
|
|
100
|
+
```bash
|
|
101
|
+
uv run git-graphable . --highlight-pr-status
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Divergence Analysis (Hygiene)
|
|
105
|
+
Highlight commits that exist in `main` but are missing from your feature branches:
|
|
106
|
+
```bash
|
|
107
|
+
uv run git-graphable . --highlight-diverging-from main
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Large Repositories
|
|
111
|
+
For repositories with long histories, use the `--limit` flag to keep the graph readable and avoid engine rendering limits:
|
|
112
|
+
```bash
|
|
113
|
+
uv run git-graphable . --limit 100 --highlight-authors
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
Git Graphable can be configured via a TOML file (`.git-graphable.toml` or `pyproject.toml`). CLI flags always take precedence over configuration file settings.
|
|
119
|
+
|
|
120
|
+
### Configuration Locations
|
|
121
|
+
The tool searches for configuration in the following order:
|
|
122
|
+
1. File specified via `--config <path>`
|
|
123
|
+
2. `.git-graphable.toml` in the repository root
|
|
124
|
+
3. `pyproject.toml` in the repository root (under `[tool.git-graphable]`)
|
|
125
|
+
|
|
126
|
+
### Example `.git-graphable.toml`
|
|
127
|
+
```toml
|
|
128
|
+
[git-graphable]
|
|
129
|
+
production_branch = "main"
|
|
130
|
+
development_branch = "develop"
|
|
131
|
+
simplify = true
|
|
132
|
+
limit = 100
|
|
133
|
+
date_format = "%Y-%m-%d"
|
|
134
|
+
highlight_critical = true
|
|
135
|
+
critical_branches = ["main", "prod"]
|
|
136
|
+
highlight_pr_status = true
|
|
137
|
+
highlight_wip = true
|
|
138
|
+
wip_keywords = ["wip", "todo", "fixme", "temp"]
|
|
139
|
+
highlight_direct_pushes = true
|
|
140
|
+
highlight_squashed = true
|
|
141
|
+
highlight_back_merges = true
|
|
142
|
+
highlight_silos = true
|
|
143
|
+
silo_commit_threshold = 20
|
|
144
|
+
silo_author_count = 1
|
|
145
|
+
min_hygiene_score = 80
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Example `pyproject.toml`
|
|
149
|
+
```toml
|
|
150
|
+
[tool.git-graphable]
|
|
151
|
+
development_branch = "main"
|
|
152
|
+
simplify = true
|
|
153
|
+
highlight_authors = true
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
Run tests and linting:
|
|
159
|
+
```bash
|
|
160
|
+
just check
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### CI/CD
|
|
164
|
+
This project uses GitHub Actions for continuous integration and automated publishing:
|
|
165
|
+
- **CI**: Runs `just check` on all pushes and PRs to `main`.
|
|
166
|
+
- **Publish**: Automatically builds and publishes to PyPI when a version tag (`v*`) is pushed.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Git Graphable
|
|
2
|
+
|
|
3
|
+
A powerful Python tool to convert Git commit history into beautiful, interactive flowcharts using the `graphable` library. Supporting Mermaid, D2, Graphviz, and PlantUML.
|
|
4
|
+
|
|
5
|
+
## Git Plugin Support
|
|
6
|
+
When installed in your PATH, you can use this as a native Git plugin:
|
|
7
|
+
```bash
|
|
8
|
+
git graphable .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Multi-Engine Support**: Export to Mermaid (.mmd), D2 (.d2), Graphviz (.dot), or PlantUML (.puml).
|
|
14
|
+
- **Automatic Visualization**: Generates and opens an image (SVG/PNG) automatically if no output is specified.
|
|
15
|
+
- **Advanced Highlighting**: Visualize author patterns, topological distance, and specific merge paths.
|
|
16
|
+
- **GitHub Integration**: Highlight commits based on pull request status (Merged, Open, Closed, Draft) using the `gh` CLI.
|
|
17
|
+
- **Hygiene Analysis**: Automatically detect WIP commits, direct pushes to protected branches, squashed PRs, back-merges, and contributor silos.
|
|
18
|
+
- **Health Scoring**: Get a numeric "Hygiene Score" (0-100%) with a color-coded grade and detailed breakdown of workflow anti-patterns.
|
|
19
|
+
- **CI Gating**: Use the `--check` flag to return a non-zero exit code if the hygiene score falls below a threshold (configurable via `--min-score`).
|
|
20
|
+
- **Flexible Input**: Works with local repository paths or remote Git URLs.
|
|
21
|
+
- **Dual CLI**: Modern Rich/Typer interface with a robust argparse fallback for bare environments.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Using uv (recommended)
|
|
27
|
+
uv sync --all-extras
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
For a complete reference of all command-line options, see the [USAGE.md](USAGE.md) file. For visual demonstrations of all features, see [examples/EXAMPLES.md](examples/EXAMPLES.md).
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Basic usage (opens a Mermaid image)
|
|
36
|
+
uv run git-graphable .
|
|
37
|
+
|
|
38
|
+
# Highlight PR status (requires gh CLI)
|
|
39
|
+
uv run git-graphable . --highlight-pr-status
|
|
40
|
+
|
|
41
|
+
# Specify an engine and output file
|
|
42
|
+
uv run git-graphable https://github.com/TheTrueSCU/graphable/ --engine d2 -o graph.svg
|
|
43
|
+
|
|
44
|
+
# Simplify the graph (only show branches/tags)
|
|
45
|
+
uv run git-graphable . --simplify
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Highlighting Options
|
|
49
|
+
|
|
50
|
+
Git Graphable provides several ways to highlight commits and relationships. Multiple options can be combined to layer information.
|
|
51
|
+
|
|
52
|
+
| Option | Target | Effect | Conflicts With |
|
|
53
|
+
| :--- | :--- | :--- | :--- |
|
|
54
|
+
| `--highlight-authors` | **Fill** | Unique color per author | PR Status, Distance, Stale, WIP |
|
|
55
|
+
| `--highlight-pr-status` | **Fill/Stroke**| Color by PR state (Merged=Purple, Open=Green) | Authors, Distance, Stale, WIP |
|
|
56
|
+
| `--highlight-distance-from` | **Fill** | Blue gradient fading by distance | Authors, PR Status, Stale, WIP |
|
|
57
|
+
| `--highlight-stale` | **Fill** | Gradient white to red by age | Authors, PR Status, Distance, WIP |
|
|
58
|
+
| `--highlight-wip` | **Fill** | Yellow fill for WIP/TODO commits | Authors, PR Status, Distance, Stale |
|
|
59
|
+
| `--highlight-path` | **Edge** | Thick Orange edge connecting nodes | None |
|
|
60
|
+
| `--highlight-critical` | **Stroke** | Thick Red Solid outline | None |
|
|
61
|
+
| `--highlight-diverging-from` | **Stroke** | Orange Dashed outline | None |
|
|
62
|
+
| `--highlight-orphans` | **Stroke** | Grey Dashed outline | None |
|
|
63
|
+
| `--highlight-long-running` | **Stroke/Edge** | Purple outline and thick Purple edge | None |
|
|
64
|
+
| `--highlight-direct-pushes` | **Stroke** | Thick Red Dashed outline | None |
|
|
65
|
+
| `--highlight-squashed` | **Stroke/Edge** | Grey Solid outline and dashed Grey logical merge edge | None |
|
|
66
|
+
| `--highlight-back-merges` | **Stroke** | Orange Dashed outline | None |
|
|
67
|
+
| `--highlight-silos` | **Stroke** | Blue Solid outline | None |
|
|
68
|
+
|
|
69
|
+
### Highlighting Priorities
|
|
70
|
+
- **Fill**: `--highlight-authors`, `--highlight-pr-status`, `--highlight-distance-from`, `--highlight-stale`, and `--highlight-wip` are mutually exclusive.
|
|
71
|
+
- **Edge**: Path highlighting (Thick Orange) takes priority over Long-Running highlighting (Thick Purple), which takes priority over Logical Squashed Merges (Dashed Grey).
|
|
72
|
+
- **Stroke**: Critical outlines (Thick Red Solid) take priority over Direct Pushes (Thick Red Dashed), which take priority over PR Conflicts (Thick Red Solid), which take priority over Back-Merges (Orange Dashed), which take priority over Squash Commits (Grey Solid), which take priority over Contributor Silos (Blue Solid), which take priority over all other outlines (Divergence, Orphan, Long-Running).
|
|
73
|
+
|
|
74
|
+
## Advanced Examples
|
|
75
|
+
|
|
76
|
+
### Hygiene Analysis
|
|
77
|
+
Identify problematic patterns like direct pushes to `main`, messy WIP commits, back-merges from `main`, or contributor silos:
|
|
78
|
+
```bash
|
|
79
|
+
uv run git-graphable . --highlight-direct-pushes --highlight-wip --highlight-squashed --highlight-back-merges --highlight-silos
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### PR Status Highlighting
|
|
83
|
+
View the current state of all PRs in your repository graph:
|
|
84
|
+
```bash
|
|
85
|
+
uv run git-graphable . --highlight-pr-status
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Divergence Analysis (Hygiene)
|
|
89
|
+
Highlight commits that exist in `main` but are missing from your feature branches:
|
|
90
|
+
```bash
|
|
91
|
+
uv run git-graphable . --highlight-diverging-from main
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Large Repositories
|
|
95
|
+
For repositories with long histories, use the `--limit` flag to keep the graph readable and avoid engine rendering limits:
|
|
96
|
+
```bash
|
|
97
|
+
uv run git-graphable . --limit 100 --highlight-authors
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Configuration
|
|
101
|
+
|
|
102
|
+
Git Graphable can be configured via a TOML file (`.git-graphable.toml` or `pyproject.toml`). CLI flags always take precedence over configuration file settings.
|
|
103
|
+
|
|
104
|
+
### Configuration Locations
|
|
105
|
+
The tool searches for configuration in the following order:
|
|
106
|
+
1. File specified via `--config <path>`
|
|
107
|
+
2. `.git-graphable.toml` in the repository root
|
|
108
|
+
3. `pyproject.toml` in the repository root (under `[tool.git-graphable]`)
|
|
109
|
+
|
|
110
|
+
### Example `.git-graphable.toml`
|
|
111
|
+
```toml
|
|
112
|
+
[git-graphable]
|
|
113
|
+
production_branch = "main"
|
|
114
|
+
development_branch = "develop"
|
|
115
|
+
simplify = true
|
|
116
|
+
limit = 100
|
|
117
|
+
date_format = "%Y-%m-%d"
|
|
118
|
+
highlight_critical = true
|
|
119
|
+
critical_branches = ["main", "prod"]
|
|
120
|
+
highlight_pr_status = true
|
|
121
|
+
highlight_wip = true
|
|
122
|
+
wip_keywords = ["wip", "todo", "fixme", "temp"]
|
|
123
|
+
highlight_direct_pushes = true
|
|
124
|
+
highlight_squashed = true
|
|
125
|
+
highlight_back_merges = true
|
|
126
|
+
highlight_silos = true
|
|
127
|
+
silo_commit_threshold = 20
|
|
128
|
+
silo_author_count = 1
|
|
129
|
+
min_hygiene_score = 80
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Example `pyproject.toml`
|
|
133
|
+
```toml
|
|
134
|
+
[tool.git-graphable]
|
|
135
|
+
development_branch = "main"
|
|
136
|
+
simplify = true
|
|
137
|
+
highlight_authors = true
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
Run tests and linting:
|
|
143
|
+
```bash
|
|
144
|
+
just check
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### CI/CD
|
|
148
|
+
This project uses GitHub Actions for continuous integration and automated publishing:
|
|
149
|
+
- **CI**: Runs `just check` on all pushes and PRs to `main`.
|
|
150
|
+
- **Publish**: Automatically builds and publishes to PyPI when a version tag (`v*`) is pushed.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
We take the security of this project seriously. If you believe you have found a security vulnerability, please do not report it via a public issue. Instead, please report it through GitHub's private vulnerability reporting feature or contact the maintainer directly at [dopplereffect.us@gmail.com].
|
|
6
|
+
|
|
7
|
+
## Supported Versions
|
|
8
|
+
|
|
9
|
+
Only the latest version of `git-graphable` is currently supported for security updates.
|
|
10
|
+
|
|
11
|
+
| Version | Supported |
|
|
12
|
+
| ------- | ------------------ |
|
|
13
|
+
| 0.1.x | :white_check_mark: |
|
|
14
|
+
| < 0.1.0 | :x: |
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# `git-graphable`
|
|
2
|
+
|
|
3
|
+
Git graph to Mermaid/Graphviz/D2/PlantUML converter.
|
|
4
|
+
|
|
5
|
+
**Usage**:
|
|
6
|
+
|
|
7
|
+
```console
|
|
8
|
+
$ git-graphable [OPTIONS] PATH
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Arguments**:
|
|
12
|
+
|
|
13
|
+
* `PATH`: Path to local directory or git URL [required]
|
|
14
|
+
|
|
15
|
+
**Options**:
|
|
16
|
+
|
|
17
|
+
* `--config TEXT`: Path to TOML configuration file
|
|
18
|
+
* `--production-branch TEXT`: Production branch name (e.g. main, master)
|
|
19
|
+
* `--development-branch TEXT`: Development branch name (e.g. develop, main)
|
|
20
|
+
* `--date-format TEXT`: Date format for commit labels [default: %Y%m%d%H%M%S]
|
|
21
|
+
* `--engine [mermaid|graphviz|d2|plantuml]`: Visualization engine [default: mermaid]
|
|
22
|
+
* `-o, --output TEXT`: Output file path
|
|
23
|
+
* `--image`: Export as image even when output path is provided
|
|
24
|
+
* `--simplify`: Pass --simplify-by-decoration to git log
|
|
25
|
+
* `--limit INTEGER`: Limit the number of commits to process
|
|
26
|
+
* `--highlight-critical`: Highlight critical branches
|
|
27
|
+
* `--critical-branch TEXT`: Branch name to treat as critical
|
|
28
|
+
* `--highlight-authors`: Assign colors to different authors
|
|
29
|
+
* `--highlight-distance-from TEXT`: Base branch/hash for distance highlighting
|
|
30
|
+
* `--highlight-path TEXT`: Highlight path between two SHAs (START..END)
|
|
31
|
+
* `--highlight-diverging-from TEXT`: Base branch/hash for divergence/behind analysis
|
|
32
|
+
* `--highlight-orphans`: Highlight dangling/orphan commits
|
|
33
|
+
* `--highlight-stale`: Highlight stale branch tips
|
|
34
|
+
* `--stale-days INTEGER`: Threshold in days for stale branches
|
|
35
|
+
* `--highlight-long-running`: Highlight long-running branches
|
|
36
|
+
* `--long-running-days INTEGER`: Threshold in days for long-running branches
|
|
37
|
+
* `--long-running-base TEXT`: Base branch for long-running analysis
|
|
38
|
+
* `--highlight-pr-status`: Highlight commits based on GitHub PR status
|
|
39
|
+
* `--highlight-wip`: Highlight WIP/TODO commits
|
|
40
|
+
* `--wip-keyword TEXT`: Additional keyword to trigger WIP highlighting
|
|
41
|
+
* `--highlight-direct-pushes`: Highlight non-merge commits on protected branches
|
|
42
|
+
* `--highlight-squashed`: Highlight squashed PRs and logically link them
|
|
43
|
+
* `--highlight-back-merges`: Highlight redundant back-merges from base branch
|
|
44
|
+
* `--highlight-silos`: Highlight branches dominated by too few authors
|
|
45
|
+
* `--silo-threshold INTEGER`: Commit count threshold for silo detection
|
|
46
|
+
* `--silo-author-count INTEGER`: Author count threshold for silo detection
|
|
47
|
+
* `--check`: Exit with non-zero if hygiene score is below threshold
|
|
48
|
+
* `--min-score INTEGER`: Minimum hygiene score required for --check
|
|
49
|
+
* `--bare`: Force bare mode (no rich output)
|
|
50
|
+
* `--install-completion`: Install completion for the current shell.
|
|
51
|
+
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
|
|
52
|
+
* `--help`: Show this message and exit.
|