git-contrib-tree 0.1.0__tar.gz → 0.2.1__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_contrib_tree-0.2.1/.gitlab-ci.yml +15 -0
- {git_contrib_tree-0.1.0 → git_contrib_tree-0.2.1}/PKG-INFO +77 -51
- {git_contrib_tree-0.1.0 → git_contrib_tree-0.2.1}/README.md +76 -50
- git_contrib_tree-0.1.0/git-contrib-tree → git_contrib_tree-0.2.1/git-contrib-tree.py +52 -21
- {git_contrib_tree-0.1.0 → git_contrib_tree-0.2.1}/pyproject.toml +4 -4
- git_contrib_tree-0.1.0/wrapper.py +0 -40
- {git_contrib_tree-0.1.0 → git_contrib_tree-0.2.1}/.gitignore +0 -0
- {git_contrib_tree-0.1.0 → git_contrib_tree-0.2.1}/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: git-contrib-tree
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Analyze and visualize git repository contributions with a file tree showing top contributors.
|
|
5
5
|
Project-URL: Repository, https://gitlab.com/wykwit/git-contrib-tree
|
|
6
6
|
Project-URL: Issues, https://gitlab.com/wykwit/git-contrib-tree/issues
|
|
@@ -36,11 +36,30 @@ A Python tool to analyze and visualize git repository contributions by displayin
|
|
|
36
36
|
- Display repository file tree with top contributors per file
|
|
37
37
|
- Show top 3 contributors for directories (aggregated from all files within)
|
|
38
38
|
- Show commit counts alongside contributor names
|
|
39
|
-
-
|
|
39
|
+
- Default time filter: analyzes last 3 months of contributions
|
|
40
|
+
- Filter by custom date range (--since/--until) or use `-1` for all history
|
|
40
41
|
- Filter by contributor email(s)
|
|
41
42
|
- List all contributor emails
|
|
42
43
|
- Control tree depth (useful for large repositories)
|
|
43
|
-
-
|
|
44
|
+
- Simple path argument: accepts absolute repo paths or relative paths within repo
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Analyze current directory (defaults to last 3 months)
|
|
50
|
+
git contrib-tree
|
|
51
|
+
|
|
52
|
+
# Show project-level overview
|
|
53
|
+
git contrib-tree --depth 0
|
|
54
|
+
|
|
55
|
+
# See who worked on what in the last 6 months
|
|
56
|
+
git contrib-tree --since "6 months ago"
|
|
57
|
+
|
|
58
|
+
# List all contributors
|
|
59
|
+
git contrib-tree --list-emails
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
See [Usage](#usage) section for more detailed examples and options.
|
|
44
63
|
|
|
45
64
|
## Requirements
|
|
46
65
|
|
|
@@ -54,6 +73,17 @@ No external dependencies required - uses only Python standard library and git.
|
|
|
54
73
|
|
|
55
74
|
### Using uv (Recommended)
|
|
56
75
|
|
|
76
|
+
**Run without installing:**
|
|
77
|
+
```bash
|
|
78
|
+
uvx git-contrib-tree
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Install as a tool:**
|
|
82
|
+
```bash
|
|
83
|
+
uv tool install git-contrib-tree
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Install in a virtual environment:**
|
|
57
87
|
```bash
|
|
58
88
|
uv pip install git-contrib-tree
|
|
59
89
|
```
|
|
@@ -64,7 +94,7 @@ uv pip install git-contrib-tree
|
|
|
64
94
|
pip install git-contrib-tree
|
|
65
95
|
```
|
|
66
96
|
|
|
67
|
-
### Arch Linux
|
|
97
|
+
### From AUR (Recommended on Arch Linux)
|
|
68
98
|
|
|
69
99
|
```bash
|
|
70
100
|
# Using an AUR helper
|
|
@@ -75,30 +105,17 @@ This installs the `git-contrib-tree` command, making it available as both:
|
|
|
75
105
|
- A standalone command: `git-contrib-tree`
|
|
76
106
|
- A git subcommand: `git contrib-tree`
|
|
77
107
|
|
|
78
|
-
### Development Installation
|
|
79
|
-
|
|
80
|
-
For development, clone the repository and install in editable mode:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
git clone https://gitlab.com/wykwit/git-contrib-tree.git
|
|
84
|
-
cd git-contrib-tree
|
|
85
|
-
uv pip install -e .
|
|
86
|
-
```
|
|
87
|
-
|
|
88
108
|
### Standalone Script
|
|
89
109
|
|
|
90
110
|
The `git-contrib-tree` script is a self-contained Python file with no external dependencies. You can use it directly without installing the package:
|
|
91
111
|
|
|
92
112
|
```bash
|
|
93
113
|
# Download the script
|
|
94
|
-
curl -
|
|
114
|
+
curl -o git-contrib-tree https://gitlab.com/wykwit/git-contrib-tree/-/raw/main/git-contrib-tree.py
|
|
95
115
|
chmod +x git-contrib-tree
|
|
96
116
|
|
|
97
117
|
# Run it directly
|
|
98
118
|
./git-contrib-tree --help
|
|
99
|
-
|
|
100
|
-
# Or with Python
|
|
101
|
-
python3 git-contrib-tree --help
|
|
102
119
|
```
|
|
103
120
|
|
|
104
121
|
This is useful for:
|
|
@@ -106,20 +123,14 @@ This is useful for:
|
|
|
106
123
|
- Including in other projects or scripts
|
|
107
124
|
- Running on systems where you can't install packages
|
|
108
125
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
# Analyze current directory
|
|
113
|
-
git contrib-tree
|
|
114
|
-
|
|
115
|
-
# Show project-level overview
|
|
116
|
-
git contrib-tree --depth 0
|
|
126
|
+
### Development Installation
|
|
117
127
|
|
|
118
|
-
|
|
119
|
-
git contrib-tree --since "3 months ago"
|
|
128
|
+
For development, clone the repository and install in editable mode:
|
|
120
129
|
|
|
121
|
-
|
|
122
|
-
git contrib-tree
|
|
130
|
+
```bash
|
|
131
|
+
git clone https://gitlab.com/wykwit/git-contrib-tree.git
|
|
132
|
+
cd git-contrib-tree
|
|
133
|
+
uv pip install -e .
|
|
123
134
|
```
|
|
124
135
|
|
|
125
136
|
## Usage
|
|
@@ -127,11 +138,17 @@ git contrib-tree --list-emails
|
|
|
127
138
|
### Basic Usage
|
|
128
139
|
|
|
129
140
|
```bash
|
|
130
|
-
# Analyze current directory
|
|
141
|
+
# Analyze current directory (default: last 3 months)
|
|
131
142
|
git contrib-tree
|
|
132
143
|
|
|
133
|
-
# Analyze specific
|
|
134
|
-
git contrib-tree
|
|
144
|
+
# Analyze specific directory (relative to current location)
|
|
145
|
+
git contrib-tree src
|
|
146
|
+
|
|
147
|
+
# Analyze different repository (absolute path)
|
|
148
|
+
git contrib-tree /path/to/repo
|
|
149
|
+
|
|
150
|
+
# Analyze specific file
|
|
151
|
+
git contrib-tree README.md
|
|
135
152
|
```
|
|
136
153
|
|
|
137
154
|
### Depth Control
|
|
@@ -152,26 +169,35 @@ git contrib-tree --depth -1
|
|
|
152
169
|
|
|
153
170
|
**Note:** Depth controls what is *displayed*, not what is analyzed. Directory summaries always include all files within them, even if those files are not shown due to depth limits.
|
|
154
171
|
|
|
155
|
-
### Analyze Specific
|
|
172
|
+
### Analyze Specific Paths
|
|
156
173
|
|
|
157
174
|
```bash
|
|
158
|
-
# Analyze
|
|
159
|
-
git contrib-tree
|
|
175
|
+
# Analyze the src directory (relative to current location)
|
|
176
|
+
git contrib-tree src
|
|
160
177
|
|
|
161
|
-
# Analyze
|
|
162
|
-
git contrib-tree
|
|
178
|
+
# Analyze src/models with depth 1
|
|
179
|
+
git contrib-tree src/models --depth 1
|
|
163
180
|
|
|
164
|
-
# Analyze specific file
|
|
165
|
-
git contrib-tree
|
|
181
|
+
# Analyze specific file with project-level view
|
|
182
|
+
git contrib-tree README.md --depth 0
|
|
183
|
+
|
|
184
|
+
# Analyze different repository
|
|
185
|
+
git contrib-tree /absolute/path/to/other/repo
|
|
186
|
+
|
|
187
|
+
# Combine with date filter
|
|
188
|
+
git contrib-tree src --since "6 months ago"
|
|
166
189
|
```
|
|
167
190
|
|
|
168
191
|
### Date Filtering
|
|
169
192
|
|
|
170
193
|
```bash
|
|
194
|
+
# Analyze all history
|
|
195
|
+
git contrib-tree --since -1
|
|
196
|
+
|
|
171
197
|
# Analyze contributions from specific date
|
|
172
198
|
git contrib-tree --since "2024-01-01"
|
|
173
199
|
|
|
174
|
-
# Analyze last 6 months
|
|
200
|
+
# Analyze last 6 months (default is 3 months)
|
|
175
201
|
git contrib-tree --since "6 months ago"
|
|
176
202
|
|
|
177
203
|
# Analyze until specific date
|
|
@@ -208,14 +234,14 @@ git contrib-tree --email user@example.com --since "6 months ago" --depth 2
|
|
|
208
234
|
# Analyze last year with depth 2
|
|
209
235
|
git contrib-tree --since "1 year ago" --depth 2
|
|
210
236
|
|
|
211
|
-
# Analyze
|
|
212
|
-
git contrib-tree
|
|
237
|
+
# Analyze different repository and time period
|
|
238
|
+
git contrib-tree ~/projects/myapp --since "2024-01-01" --depth 3
|
|
213
239
|
|
|
214
240
|
# Analyze src directory from last 6 months
|
|
215
|
-
git contrib-tree
|
|
241
|
+
git contrib-tree src --since "6 months ago" --depth 2
|
|
216
242
|
|
|
217
243
|
# See specific author's contributions in a directory
|
|
218
|
-
git contrib-tree
|
|
244
|
+
git contrib-tree src --email user@example.com
|
|
219
245
|
```
|
|
220
246
|
|
|
221
247
|
## Output Examples
|
|
@@ -266,10 +292,9 @@ Contributors:
|
|
|
266
292
|
|
|
267
293
|
| Option | Default | Description |
|
|
268
294
|
|--------|---------|-------------|
|
|
269
|
-
|
|
|
295
|
+
| `path` | `.` | Path to analyze (absolute repo path or relative path within repo) |
|
|
270
296
|
| `--depth N` | `-1` | Maximum tree depth to display (0=project only, -1=unlimited) |
|
|
271
|
-
| `--
|
|
272
|
-
| `--since DATE` | None | Show commits after this date |
|
|
297
|
+
| `--since DATE` | `3 months ago` | Show commits after this date (use `-1` for all history) |
|
|
273
298
|
| `--until DATE` | None | Show commits before this date |
|
|
274
299
|
| `--email EMAILS` | None | Filter by author email(s), comma-separated |
|
|
275
300
|
| `--list-emails` | False | List all contributor emails and exit |
|
|
@@ -298,13 +323,14 @@ The tool analyzes git history efficiently using batch operations:
|
|
|
298
323
|
## Troubleshooting
|
|
299
324
|
|
|
300
325
|
**"Not a git repository" error:**
|
|
301
|
-
- Ensure you
|
|
326
|
+
- Ensure the path you specified is inside a git repository
|
|
302
327
|
- Run `git status` to verify the directory is a git repository
|
|
328
|
+
- If using a relative path, make sure you're starting from a location within the git repo
|
|
303
329
|
|
|
304
330
|
**No commits shown:**
|
|
305
|
-
- Check your date filters (`--since`, `--until`) -
|
|
331
|
+
- Check your date filters (`--since`, `--until`) - by default, only the last 3 months are shown
|
|
306
332
|
- Verify files exist in git: `git ls-files`
|
|
307
|
-
- Ensure the specified
|
|
333
|
+
- Ensure the specified path exists in the repository
|
|
308
334
|
- Check that the `--email` filter matches actual contributor emails (use `--list-emails`)
|
|
309
335
|
|
|
310
336
|
**Unexpected contributor names:**
|
|
@@ -9,11 +9,30 @@ A Python tool to analyze and visualize git repository contributions by displayin
|
|
|
9
9
|
- Display repository file tree with top contributors per file
|
|
10
10
|
- Show top 3 contributors for directories (aggregated from all files within)
|
|
11
11
|
- Show commit counts alongside contributor names
|
|
12
|
-
-
|
|
12
|
+
- Default time filter: analyzes last 3 months of contributions
|
|
13
|
+
- Filter by custom date range (--since/--until) or use `-1` for all history
|
|
13
14
|
- Filter by contributor email(s)
|
|
14
15
|
- List all contributor emails
|
|
15
16
|
- Control tree depth (useful for large repositories)
|
|
16
|
-
-
|
|
17
|
+
- Simple path argument: accepts absolute repo paths or relative paths within repo
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Analyze current directory (defaults to last 3 months)
|
|
23
|
+
git contrib-tree
|
|
24
|
+
|
|
25
|
+
# Show project-level overview
|
|
26
|
+
git contrib-tree --depth 0
|
|
27
|
+
|
|
28
|
+
# See who worked on what in the last 6 months
|
|
29
|
+
git contrib-tree --since "6 months ago"
|
|
30
|
+
|
|
31
|
+
# List all contributors
|
|
32
|
+
git contrib-tree --list-emails
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
See [Usage](#usage) section for more detailed examples and options.
|
|
17
36
|
|
|
18
37
|
## Requirements
|
|
19
38
|
|
|
@@ -27,6 +46,17 @@ No external dependencies required - uses only Python standard library and git.
|
|
|
27
46
|
|
|
28
47
|
### Using uv (Recommended)
|
|
29
48
|
|
|
49
|
+
**Run without installing:**
|
|
50
|
+
```bash
|
|
51
|
+
uvx git-contrib-tree
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Install as a tool:**
|
|
55
|
+
```bash
|
|
56
|
+
uv tool install git-contrib-tree
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Install in a virtual environment:**
|
|
30
60
|
```bash
|
|
31
61
|
uv pip install git-contrib-tree
|
|
32
62
|
```
|
|
@@ -37,7 +67,7 @@ uv pip install git-contrib-tree
|
|
|
37
67
|
pip install git-contrib-tree
|
|
38
68
|
```
|
|
39
69
|
|
|
40
|
-
### Arch Linux
|
|
70
|
+
### From AUR (Recommended on Arch Linux)
|
|
41
71
|
|
|
42
72
|
```bash
|
|
43
73
|
# Using an AUR helper
|
|
@@ -48,30 +78,17 @@ This installs the `git-contrib-tree` command, making it available as both:
|
|
|
48
78
|
- A standalone command: `git-contrib-tree`
|
|
49
79
|
- A git subcommand: `git contrib-tree`
|
|
50
80
|
|
|
51
|
-
### Development Installation
|
|
52
|
-
|
|
53
|
-
For development, clone the repository and install in editable mode:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
git clone https://gitlab.com/wykwit/git-contrib-tree.git
|
|
57
|
-
cd git-contrib-tree
|
|
58
|
-
uv pip install -e .
|
|
59
|
-
```
|
|
60
|
-
|
|
61
81
|
### Standalone Script
|
|
62
82
|
|
|
63
83
|
The `git-contrib-tree` script is a self-contained Python file with no external dependencies. You can use it directly without installing the package:
|
|
64
84
|
|
|
65
85
|
```bash
|
|
66
86
|
# Download the script
|
|
67
|
-
curl -
|
|
87
|
+
curl -o git-contrib-tree https://gitlab.com/wykwit/git-contrib-tree/-/raw/main/git-contrib-tree.py
|
|
68
88
|
chmod +x git-contrib-tree
|
|
69
89
|
|
|
70
90
|
# Run it directly
|
|
71
91
|
./git-contrib-tree --help
|
|
72
|
-
|
|
73
|
-
# Or with Python
|
|
74
|
-
python3 git-contrib-tree --help
|
|
75
92
|
```
|
|
76
93
|
|
|
77
94
|
This is useful for:
|
|
@@ -79,20 +96,14 @@ This is useful for:
|
|
|
79
96
|
- Including in other projects or scripts
|
|
80
97
|
- Running on systems where you can't install packages
|
|
81
98
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
# Analyze current directory
|
|
86
|
-
git contrib-tree
|
|
87
|
-
|
|
88
|
-
# Show project-level overview
|
|
89
|
-
git contrib-tree --depth 0
|
|
99
|
+
### Development Installation
|
|
90
100
|
|
|
91
|
-
|
|
92
|
-
git contrib-tree --since "3 months ago"
|
|
101
|
+
For development, clone the repository and install in editable mode:
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
git contrib-tree
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://gitlab.com/wykwit/git-contrib-tree.git
|
|
105
|
+
cd git-contrib-tree
|
|
106
|
+
uv pip install -e .
|
|
96
107
|
```
|
|
97
108
|
|
|
98
109
|
## Usage
|
|
@@ -100,11 +111,17 @@ git contrib-tree --list-emails
|
|
|
100
111
|
### Basic Usage
|
|
101
112
|
|
|
102
113
|
```bash
|
|
103
|
-
# Analyze current directory
|
|
114
|
+
# Analyze current directory (default: last 3 months)
|
|
104
115
|
git contrib-tree
|
|
105
116
|
|
|
106
|
-
# Analyze specific
|
|
107
|
-
git contrib-tree
|
|
117
|
+
# Analyze specific directory (relative to current location)
|
|
118
|
+
git contrib-tree src
|
|
119
|
+
|
|
120
|
+
# Analyze different repository (absolute path)
|
|
121
|
+
git contrib-tree /path/to/repo
|
|
122
|
+
|
|
123
|
+
# Analyze specific file
|
|
124
|
+
git contrib-tree README.md
|
|
108
125
|
```
|
|
109
126
|
|
|
110
127
|
### Depth Control
|
|
@@ -125,26 +142,35 @@ git contrib-tree --depth -1
|
|
|
125
142
|
|
|
126
143
|
**Note:** Depth controls what is *displayed*, not what is analyzed. Directory summaries always include all files within them, even if those files are not shown due to depth limits.
|
|
127
144
|
|
|
128
|
-
### Analyze Specific
|
|
145
|
+
### Analyze Specific Paths
|
|
129
146
|
|
|
130
147
|
```bash
|
|
131
|
-
# Analyze
|
|
132
|
-
git contrib-tree
|
|
148
|
+
# Analyze the src directory (relative to current location)
|
|
149
|
+
git contrib-tree src
|
|
133
150
|
|
|
134
|
-
# Analyze
|
|
135
|
-
git contrib-tree
|
|
151
|
+
# Analyze src/models with depth 1
|
|
152
|
+
git contrib-tree src/models --depth 1
|
|
136
153
|
|
|
137
|
-
# Analyze specific file
|
|
138
|
-
git contrib-tree
|
|
154
|
+
# Analyze specific file with project-level view
|
|
155
|
+
git contrib-tree README.md --depth 0
|
|
156
|
+
|
|
157
|
+
# Analyze different repository
|
|
158
|
+
git contrib-tree /absolute/path/to/other/repo
|
|
159
|
+
|
|
160
|
+
# Combine with date filter
|
|
161
|
+
git contrib-tree src --since "6 months ago"
|
|
139
162
|
```
|
|
140
163
|
|
|
141
164
|
### Date Filtering
|
|
142
165
|
|
|
143
166
|
```bash
|
|
167
|
+
# Analyze all history
|
|
168
|
+
git contrib-tree --since -1
|
|
169
|
+
|
|
144
170
|
# Analyze contributions from specific date
|
|
145
171
|
git contrib-tree --since "2024-01-01"
|
|
146
172
|
|
|
147
|
-
# Analyze last 6 months
|
|
173
|
+
# Analyze last 6 months (default is 3 months)
|
|
148
174
|
git contrib-tree --since "6 months ago"
|
|
149
175
|
|
|
150
176
|
# Analyze until specific date
|
|
@@ -181,14 +207,14 @@ git contrib-tree --email user@example.com --since "6 months ago" --depth 2
|
|
|
181
207
|
# Analyze last year with depth 2
|
|
182
208
|
git contrib-tree --since "1 year ago" --depth 2
|
|
183
209
|
|
|
184
|
-
# Analyze
|
|
185
|
-
git contrib-tree
|
|
210
|
+
# Analyze different repository and time period
|
|
211
|
+
git contrib-tree ~/projects/myapp --since "2024-01-01" --depth 3
|
|
186
212
|
|
|
187
213
|
# Analyze src directory from last 6 months
|
|
188
|
-
git contrib-tree
|
|
214
|
+
git contrib-tree src --since "6 months ago" --depth 2
|
|
189
215
|
|
|
190
216
|
# See specific author's contributions in a directory
|
|
191
|
-
git contrib-tree
|
|
217
|
+
git contrib-tree src --email user@example.com
|
|
192
218
|
```
|
|
193
219
|
|
|
194
220
|
## Output Examples
|
|
@@ -239,10 +265,9 @@ Contributors:
|
|
|
239
265
|
|
|
240
266
|
| Option | Default | Description |
|
|
241
267
|
|--------|---------|-------------|
|
|
242
|
-
|
|
|
268
|
+
| `path` | `.` | Path to analyze (absolute repo path or relative path within repo) |
|
|
243
269
|
| `--depth N` | `-1` | Maximum tree depth to display (0=project only, -1=unlimited) |
|
|
244
|
-
| `--
|
|
245
|
-
| `--since DATE` | None | Show commits after this date |
|
|
270
|
+
| `--since DATE` | `3 months ago` | Show commits after this date (use `-1` for all history) |
|
|
246
271
|
| `--until DATE` | None | Show commits before this date |
|
|
247
272
|
| `--email EMAILS` | None | Filter by author email(s), comma-separated |
|
|
248
273
|
| `--list-emails` | False | List all contributor emails and exit |
|
|
@@ -271,13 +296,14 @@ The tool analyzes git history efficiently using batch operations:
|
|
|
271
296
|
## Troubleshooting
|
|
272
297
|
|
|
273
298
|
**"Not a git repository" error:**
|
|
274
|
-
- Ensure you
|
|
299
|
+
- Ensure the path you specified is inside a git repository
|
|
275
300
|
- Run `git status` to verify the directory is a git repository
|
|
301
|
+
- If using a relative path, make sure you're starting from a location within the git repo
|
|
276
302
|
|
|
277
303
|
**No commits shown:**
|
|
278
|
-
- Check your date filters (`--since`, `--until`) -
|
|
304
|
+
- Check your date filters (`--since`, `--until`) - by default, only the last 3 months are shown
|
|
279
305
|
- Verify files exist in git: `git ls-files`
|
|
280
|
-
- Ensure the specified
|
|
306
|
+
- Ensure the specified path exists in the repository
|
|
281
307
|
- Check that the `--email` filter matches actual contributor emails (use `--list-emails`)
|
|
282
308
|
|
|
283
309
|
**Unexpected contributor names:**
|
|
@@ -16,6 +16,7 @@ from typing import Dict, List, Optional, Set, Tuple
|
|
|
16
16
|
|
|
17
17
|
TOP_CONTRIBUTORS_LIMIT = 3
|
|
18
18
|
NULL_SEPARATOR = "\x00"
|
|
19
|
+
PROJECT_CACHE_KEY = "__PROJECT__"
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class GitContributionAnalyzer:
|
|
@@ -137,7 +138,7 @@ class GitContributionAnalyzer:
|
|
|
137
138
|
Returns:
|
|
138
139
|
List of tuples (author_name, commit_count) for top 3 contributors
|
|
139
140
|
"""
|
|
140
|
-
cache_key = file_path or
|
|
141
|
+
cache_key = file_path or PROJECT_CACHE_KEY
|
|
141
142
|
|
|
142
143
|
if cache_key in self._file_contributors_cache:
|
|
143
144
|
return self._file_contributors_cache[cache_key]
|
|
@@ -509,6 +510,26 @@ class GitContributionAnalyzer:
|
|
|
509
510
|
print(f"{prefix}{connector}{name} - {contrib_str}")
|
|
510
511
|
|
|
511
512
|
|
|
513
|
+
def find_git_repo_root(path: Path) -> Optional[Path]:
|
|
514
|
+
"""Find the git repository root by traversing up the directory tree."""
|
|
515
|
+
if not path.exists():
|
|
516
|
+
return None
|
|
517
|
+
|
|
518
|
+
current = path.resolve()
|
|
519
|
+
while current != current.parent:
|
|
520
|
+
if (current / ".git").exists():
|
|
521
|
+
return current
|
|
522
|
+
current = current.parent
|
|
523
|
+
return None
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def parse_email_list(emails_string: Optional[str]) -> Optional[Set[str]]:
|
|
527
|
+
"""Parse a comma-separated string of emails into a set."""
|
|
528
|
+
if not emails_string:
|
|
529
|
+
return None
|
|
530
|
+
return {email.strip() for email in emails_string.split(",") if email.strip()}
|
|
531
|
+
|
|
532
|
+
|
|
512
533
|
def parse_args():
|
|
513
534
|
"""Parse command line arguments."""
|
|
514
535
|
parser = argparse.ArgumentParser(
|
|
@@ -516,24 +537,25 @@ def parse_args():
|
|
|
516
537
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
517
538
|
epilog="""
|
|
518
539
|
Examples:
|
|
519
|
-
%(prog)s # Analyze
|
|
520
|
-
%(prog)s --
|
|
540
|
+
%(prog)s # Analyze current directory in repo (last 3 months)
|
|
541
|
+
%(prog)s --since -1 # Analyze entire history
|
|
542
|
+
%(prog)s src # Analyze src directory (relative to current dir)
|
|
543
|
+
%(prog)s /absolute/path/to/repo # Analyze different repository
|
|
544
|
+
%(prog)s --depth 0 # Show only top-level contributors
|
|
521
545
|
%(prog)s --depth 2 # Show files up to depth 2
|
|
522
|
-
%(prog)s --path src # Analyze only src directory
|
|
523
|
-
%(prog)s --path src/models --depth 1 # Analyze src/models up to depth 1
|
|
524
546
|
%(prog)s --since "2024-01-01" # Analyze from specific date
|
|
525
547
|
%(prog)s --since "6 months ago" # Analyze last 6 months
|
|
526
548
|
%(prog)s --until "2024-12-31" # Analyze until specific date
|
|
527
|
-
%(prog)s --repo /path/to/repo # Analyze different repository
|
|
528
549
|
%(prog)s --email user@example.com # Show only contributions by specific author
|
|
529
550
|
%(prog)s --email user1@ex.com,user2@ex.com # Show contributions by multiple authors
|
|
530
551
|
""",
|
|
531
552
|
)
|
|
532
553
|
|
|
533
554
|
parser.add_argument(
|
|
534
|
-
"
|
|
555
|
+
"path",
|
|
556
|
+
nargs="?",
|
|
535
557
|
default=".",
|
|
536
|
-
help="Path to
|
|
558
|
+
help="Path to analyze (default: current directory). Can be absolute path to a repo, or relative path within repo.",
|
|
537
559
|
)
|
|
538
560
|
|
|
539
561
|
parser.add_argument(
|
|
@@ -543,13 +565,10 @@ Examples:
|
|
|
543
565
|
help="Maximum tree depth (0 = project only, -1 = unlimited, default: -1)",
|
|
544
566
|
)
|
|
545
567
|
|
|
546
|
-
parser.add_argument(
|
|
547
|
-
"--path", help="Path within repository to analyze (e.g., 'src', 'src/models')"
|
|
548
|
-
)
|
|
549
|
-
|
|
550
568
|
parser.add_argument(
|
|
551
569
|
"--since",
|
|
552
|
-
|
|
570
|
+
default="3 months ago",
|
|
571
|
+
help="Show commits after this date (git date format, default: '3 months ago'). Use '-1' for all history.",
|
|
553
572
|
)
|
|
554
573
|
|
|
555
574
|
parser.add_argument(
|
|
@@ -575,17 +594,29 @@ def main():
|
|
|
575
594
|
args = parse_args()
|
|
576
595
|
|
|
577
596
|
try:
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
)
|
|
597
|
+
target_path = Path(args.path)
|
|
598
|
+
|
|
599
|
+
repo_root = find_git_repo_root(target_path)
|
|
600
|
+
if not repo_root:
|
|
601
|
+
raise ValueError(f"No git repository found for path: {target_path}")
|
|
602
|
+
|
|
603
|
+
subtree_path = None
|
|
604
|
+
try:
|
|
605
|
+
relative = target_path.resolve().relative_to(repo_root)
|
|
606
|
+
if str(relative) != ".":
|
|
607
|
+
subtree_path = str(relative)
|
|
608
|
+
except ValueError:
|
|
609
|
+
pass
|
|
610
|
+
|
|
611
|
+
author_emails = parse_email_list(args.email)
|
|
612
|
+
|
|
613
|
+
since = None if args.since == "-1" else args.since
|
|
583
614
|
|
|
584
615
|
analyzer = GitContributionAnalyzer(
|
|
585
|
-
repo_path=
|
|
586
|
-
since=
|
|
616
|
+
repo_path=str(repo_root),
|
|
617
|
+
since=since,
|
|
587
618
|
until=args.until,
|
|
588
|
-
subtree_path=
|
|
619
|
+
subtree_path=subtree_path,
|
|
589
620
|
author_emails=author_emails,
|
|
590
621
|
)
|
|
591
622
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "git-contrib-tree"
|
|
3
|
-
version = "0.1
|
|
3
|
+
version = "0.2.1"
|
|
4
4
|
description = "Analyze and visualize git repository contributions with a file tree showing top contributors."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.6"
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[project.scripts]
|
|
31
|
-
git-contrib-tree = "
|
|
31
|
+
git-contrib-tree = "git_contrib_tree:main"
|
|
32
32
|
|
|
33
33
|
[project.urls]
|
|
34
34
|
Repository = "https://gitlab.com/wykwit/git-contrib-tree"
|
|
@@ -38,5 +38,5 @@ Issues = "https://gitlab.com/wykwit/git-contrib-tree/issues"
|
|
|
38
38
|
requires = ["hatchling"]
|
|
39
39
|
build-backend = "hatchling.build"
|
|
40
40
|
|
|
41
|
-
[tool.hatch.build.targets.wheel]
|
|
42
|
-
|
|
41
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
42
|
+
"git-contrib-tree.py" = "git_contrib_tree/__init__.py"
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Wrapper module for git-contrib-tree.
|
|
3
|
-
|
|
4
|
-
This wrapper allows us to keep the git-contrib-tree filename (with dash)
|
|
5
|
-
while providing a valid Python module for package entry points.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import importlib.util
|
|
9
|
-
import sys
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def main():
|
|
14
|
-
"""Entry point that loads and executes git-contrib-tree."""
|
|
15
|
-
# Find the script in the same directory as this wrapper
|
|
16
|
-
script_path = Path(__file__).parent / "git-contrib-tree"
|
|
17
|
-
|
|
18
|
-
if not script_path.exists():
|
|
19
|
-
print(f"Error: Could not find git-contrib-tree at {script_path}", file=sys.stderr)
|
|
20
|
-
sys.exit(1)
|
|
21
|
-
|
|
22
|
-
# Use spec_from_loader with SourceFileLoader to load files without .py extension
|
|
23
|
-
from importlib.machinery import SourceFileLoader
|
|
24
|
-
loader = SourceFileLoader("git_contrib_tree_mod", str(script_path))
|
|
25
|
-
spec = importlib.util.spec_from_loader("git_contrib_tree_mod", loader)
|
|
26
|
-
|
|
27
|
-
if spec is None or spec.loader is None:
|
|
28
|
-
print(f"Error: Could not create loader for git-contrib-tree from {script_path}", file=sys.stderr)
|
|
29
|
-
sys.exit(1)
|
|
30
|
-
|
|
31
|
-
module = importlib.util.module_from_spec(spec)
|
|
32
|
-
sys.modules["git_contrib_tree_mod"] = module
|
|
33
|
-
spec.loader.exec_module(module)
|
|
34
|
-
|
|
35
|
-
# Execute the main function from the loaded module
|
|
36
|
-
return module.main()
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if __name__ == "__main__":
|
|
40
|
-
sys.exit(main())
|
|
File without changes
|
|
File without changes
|