lupaxa-git-archaeologist 0.1.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.
@@ -0,0 +1,22 @@
1
+ # OS
2
+ .DS_Store
3
+
4
+ # Cursor
5
+ .superpowers/
6
+ cursor-docs
7
+
8
+ # Make
9
+ .makefiles/
10
+
11
+ # MkDocs
12
+ site/
13
+
14
+ # Python
15
+ .venv/
16
+ __pycache__/
17
+ .mypy_cache/
18
+ .ruff_cache/
19
+ .pytest_cache/
20
+ dist/
21
+ build/
22
+ *.egg-info/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) The Lupaxa Project
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,375 @@
1
+ Metadata-Version: 2.5
2
+ Name: lupaxa-git-archaeologist
3
+ Version: 0.1.0
4
+ Summary: Read-only local Git history analysis for activity, lineage, churn, and tree snapshots.
5
+ Project-URL: Homepage, https://github.com/lupaxa-git-toolbox/git-archaeologist
6
+ Project-URL: Repository, https://github.com/lupaxa-git-toolbox/git-archaeologist
7
+ Project-URL: Issues, https://github.com/lupaxa-git-toolbox/git-archaeologist/issues
8
+ Author: The Lupaxa Project
9
+ License: MIT License
10
+
11
+ Copyright (c) The Lupaxa Project
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENCE
31
+ Keywords: archaeology,cli,git,history
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Programming Language :: Python :: 3.14
43
+ Classifier: Topic :: Software Development :: Version Control :: Git
44
+ Requires-Python: >=3.10
45
+ Requires-Dist: colored>=2.2
46
+ Provides-Extra: dev
47
+ Requires-Dist: bump-my-version>=1.2.0; extra == 'dev'
48
+ Requires-Dist: hatch>=1.12.0; extra == 'dev'
49
+ Requires-Dist: mypy>=1.12.0; extra == 'dev'
50
+ Requires-Dist: pip-audit>=2.7.0; extra == 'dev'
51
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
52
+ Requires-Dist: pytest>=8.0; extra == 'dev'
53
+ Requires-Dist: ruff>=0.6.0; extra == 'dev'
54
+ Provides-Extra: test
55
+ Requires-Dist: pytest-cov>=5.0; extra == 'test'
56
+ Requires-Dist: pytest>=8.0; extra == 'test'
57
+ Description-Content-Type: text/markdown
58
+
59
+ <p align="center">
60
+ <a href="https://github.com/lupaxa-git-toolbox">
61
+ <img src="https://raw.githubusercontent.com/the-lupaxa-project/brand-assets/master/logos/organisations/git-toolbox/readme-logo.png" alt="Git Toolbox" />
62
+ </a>
63
+ </p>
64
+
65
+ <h1 align="center">Git Archaeologist</h1>
66
+
67
+ Git tells you what your repository is. Git Archaeologist tells you how it
68
+ got there.
69
+
70
+ It reads a local Git repository and reports activity, contributors,
71
+ surviving files, vanished paths, file biographies, churn, large historical
72
+ blobs, and tree snapshots. The same facts are available as console text,
73
+ JSON, or Markdown.
74
+
75
+ The tool is read-only. It does not fetch, rewrite history, or write reports
76
+ into the repository. Reports go to stdout. Redirect them yourself if you
77
+ want a file.
78
+
79
+ The PyPI name is `lupaxa-git-archaeologist`. The import path is
80
+ `lupaxa.git_archaeologist`. `lupaxa` is a namespace package. The console
81
+ script is `git-archaeologist`.
82
+
83
+ ## Install
84
+
85
+ ```bash
86
+ pip install lupaxa-git-archaeologist
87
+ ```
88
+
89
+ Requires Python 3.10+ and Git 2.30 or newer. The `colored` package is
90
+ installed with the tool and is used for console colour.
91
+
92
+ You can also run `python -m lupaxa.git_archaeologist`.
93
+
94
+ ## Commands
95
+
96
+ No command is implied. `git-archaeologist` with no command prints help and
97
+ exits 2. The optional repository argument defaults to the current directory.
98
+ Running from a subdirectory still analyses the whole repository. Paths
99
+ passed to `history` are relative to the repository root.
100
+
101
+ The default target is `HEAD`, including a detached HEAD. `--branch` selects
102
+ an exact local branch. `--revision` selects one commit, tag, or
103
+ remote-tracking ref. Those two options cannot be combined.
104
+
105
+ | Command | What it shows |
106
+ | -------------- | ---------------------------------------------------------------- |
107
+ | `dig` | A short overview, then small ranked findings |
108
+ | `timeline` | Activity buckets by day, month, or year |
109
+ | `contributors` | Author activity, using a committed `.mailmap` when one exists |
110
+ | `survivors` | Oldest paths still present in the target tree |
111
+ | `extinct` | Paths and directory prefixes absent from the target tree |
112
+ | `files` | Statistics for files in the target tree |
113
+ | `history` | The biography of one repository-relative path |
114
+ | `churn` | Recorded text changes, by file or by directory |
115
+ | `blobs` | Reachable historical blob sizes |
116
+ | `evolution` | First-parent snapshots of the tree |
117
+
118
+ ## Options
119
+
120
+ Global options work before or after the command. `git-archaeologist --help`
121
+ and `git-archaeologist COMMAND --help` exit 0 without opening a repository.
122
+
123
+ ### Show Every Row
124
+
125
+ `--limit` only shortens the printed table. The analysis still covers the
126
+ whole history, which is why a report can say `Showing 20 of 39 truncated`.
127
+ The default is 20 rows. `dig` prints 5 rows in each ranked section until you
128
+ pass `--limit`.
129
+
130
+ ```bash
131
+ git-archaeologist churn --limit 0
132
+ ```
133
+
134
+ `0` prints every ranked row. The same option applies to `contributors`,
135
+ `survivors`, `extinct`, `files`, `blobs`, and the event list from `history`.
136
+ `timeline` and `evolution` are not row-limited. JSON still reports `total`,
137
+ `returned`, and `truncated` when a limit is in effect.
138
+
139
+ ### Global Options
140
+
141
+ | Option | Default | What it does |
142
+ | ---------------------- | --------- | ------------------------------------------------------------------ |
143
+ | `--format FORMAT` | `console` | `console`, `json`, or `markdown` |
144
+ | `--branch NAME` | | Exact local branch. No tag or remote fallback |
145
+ | `--revision REV` | | One commit, tag, or remote-tracking ref |
146
+ | `--since DATE` | | Inclusive committer-time lower bound, in UTC |
147
+ | `--until DATE` | | Upper bound. A date covers that whole UTC day |
148
+ | `--since-rev REV` | | Exclude commits reachable from REV, including REV |
149
+ | `--until-rev REV` | | Keep commits reachable from REV. Must be an ancestor of the target |
150
+ | `--path PATH` | | Limit ranked rows to one file or directory |
151
+ | `--rename-threshold N` | `50` | Similarity percentage for renames and copies |
152
+ | `--no-copies` | off | Record copies as new files |
153
+ | `--limit N` | `20` | Ranked rows to print. `0` prints every row |
154
+ | `--quiet` | off | Hide the spinner and stderr warnings |
155
+ | `--verbose` | off | Extra phase diagnostics on stderr |
156
+ | `--no-color` | off | Disable console colour |
157
+ | `--help` | | Help, then exit 0, without opening a repository |
158
+ | `--version` | | Version, then exit 0 |
159
+
160
+ `--branch` and `--revision` cannot be combined. `--quiet` and `--verbose`
161
+ cannot be combined. Dates are `YYYY-MM-DD` or RFC 3339 with an explicit
162
+ offset. Relative words such as `yesterday` are rejected.
163
+
164
+ `--since-rev` and `--until-rev` select activity the way `git log REV1..REV2`
165
+ does. `--since-rev v1.0.0 --until-rev v2.0.0` keeps commits reachable from
166
+ `v2.0.0` and drops commits reachable from `v1.0.0`. The target tree stays the
167
+ resolved commit, so `survivors` and `files` still describe that tree. Touch
168
+ and churn counts use the selected commits.
169
+
170
+ `--path src/api` limits `churn`, `files`, `survivors`, `extinct`,
171
+ `contributors`, `timeline`, `blobs`, and `evolution` to that file or to that
172
+ directory and its children. `history` already takes its path as the first
173
+ argument. `extinct` directories include the commits that touched them, the
174
+ authors of those commits, and the commit that removed the directory.
175
+
176
+ Renames and copies use the same similarity percentage. The default is 50. A
177
+ lower `--rename-threshold` keeps a rewritten file on one identity. Git still
178
+ requires the measured similarity to clear that percentage, so a total rewrite
179
+ stays an add and a delete. `--no-copies` records a duplicate as a new file.
180
+ `--no-renames` turns off both rename and copy detection.
181
+
182
+ ### Command Options
183
+
184
+ | Command | Options |
185
+ | -------------- | -------------------------------------------------------------------------------------------------------------------------------- |
186
+ | `dig` | `--quick` skips rename, churn, extinct, and blob scans |
187
+ | `timeline` | `--group auto`, `day`, `month`, or `year`. Default `auto` |
188
+ | `contributors` | `--sort commits`, `first`, `last`, or `name`. `--no-mailmap` |
189
+ | `survivors` | `--sort age`, `commits`, or `path`. `--no-renames` |
190
+ | `extinct` | `--kind files`, `directories`, or `all`. `--sort last`, `age`, `commits`, or `path` |
191
+ | `files` | `--sort age`, `commits`, `contributors`, `churn`, `size`, or `path`. `--no-renames` |
192
+ | `history` | `--events` prints the event table. `--incarnation COMMIT`. `--no-renames` |
193
+ | `churn` | `--by files` or `directories`. `--depth N` for directories. `--sort churn`, `commits`, `contributors`, or `path`. `--no-renames` |
194
+ | `blobs` | `--min-size SIZE`, default `10MiB`. `--deleted`. `--sort size` or `path` |
195
+ | `evolution` | `--group auto`, `day`, `month`, or `year`. `--lines`. `--max-snapshots N`, default `120` |
196
+
197
+ `--depth` is only valid with `churn --by directories`, and it must be 1 or
198
+ greater. `--deleted` lists blobs absent from the target tree, including older
199
+ versions of paths that still exist. Sizes are logical blob bytes. `--lines`
200
+ counts text lines and skips binaries, symlinks, gitlinks, and recognised LFS
201
+ pointers.
202
+
203
+ ## Examples
204
+
205
+ ```bash
206
+ git-archaeologist dig
207
+ git-archaeologist dig ~/Projects/demo --branch master
208
+ git-archaeologist --format json churn --revision release/2.0
209
+ git-archaeologist churn --limit 0
210
+ git-archaeologist churn --since-rev v1.0.0 --until-rev v2.0.0
211
+ git-archaeologist churn --path src/api
212
+ git-archaeologist contributors --since 2025-01-01 --until 2025-12-31
213
+ git-archaeologist history --rename-threshold 20 --events src/grammar.py
214
+ git-archaeologist blobs --deleted --min-size 10MiB
215
+ git-archaeologist timeline --group year
216
+ git-archaeologist evolution --group month --lines
217
+ ```
218
+
219
+ `--format` selects `console`, `json`, or `markdown`. Console reports draw
220
+ ranked results as tables. Colour is used only when stdout is a terminal,
221
+ `NO_COLOR` is unset, and `--no-color` was not passed. JSON and Markdown
222
+ never contain ANSI sequences. Console dates are UTC calendar days. JSON
223
+ keeps the full timestamp.
224
+
225
+ A terminal shows a spinner on stderr while a phase runs, with a count when
226
+ the total is already known. A pipe prints one phase line instead. `--quiet`
227
+ hides progress and stderr warnings. Warnings that affect the report stay in
228
+ the JSON or Markdown output. `--verbose` adds phase diagnostics on stderr.
229
+ `--quiet` and `--verbose` cannot be combined.
230
+
231
+ > **Note:** Merge commits count as activity. File events include only changes
232
+ > that differ from every parent, such as a conflict resolution. A clean merge
233
+ > does not add a second copy of the branch diff. Every report names this
234
+ > policy. Dates use committer time in UTC. A date-only `--since` starts at
235
+ > midnight UTC. A date-only `--until` runs through the end of that day.
236
+
237
+ ## Sample Output
238
+
239
+ The samples below come from a six-commit repository. It adds `src/parser.py`,
240
+ extends it, adds `src/lexer.py`, renames the parser to `src/grammar.py`, then
241
+ adds and deletes `old.txt`. The display name in a real run is the worktree
242
+ directory name. The tool version below is the package version at the time of
243
+ the run.
244
+
245
+ ### Contributors
246
+
247
+ ```text
248
+ Git Archaeologist 0.0.0
249
+ Repository demo
250
+ State normal
251
+ Target 6641bef03fc4
252
+ Commits 6 selected, 6 reachable
253
+ Merge commits count toward activity and are excluded from file change and churn events.
254
+
255
+ Contributors
256
+ Showing 1 of 1
257
+ ╭──────────────┬─────────────────┬─────────┬──────┬────────────┬────────────╮
258
+ │ Name │ Email │ Commits │ % │ First │ Last │
259
+ ├──────────────┼─────────────────┼─────────┼──────┼────────────┼────────────┤
260
+ │ Ada Lovelace │ ada@example.com │ 6 │ 100% │ 2024-01-15 │ 2025-04-01 │
261
+ ╰──────────────┴─────────────────┴─────────┴──────┴────────────┴────────────╯
262
+ ```
263
+
264
+ Canonical names come from the `.mailmap` blob in the selected target tree.
265
+ A missing mailmap leaves the raw author identities unchanged. A dirty
266
+ worktree mailmap is ignored.
267
+
268
+ ### Churn
269
+
270
+ ```text
271
+ Churn
272
+ Showing 4 of 4
273
+ ╭────────────────┬───────┬───────┬─────────┬─────────┬─────────┬────────╮
274
+ │ Path │ Churn │ Added │ Deleted │ Commits │ Authors │ Binary │
275
+ ├────────────────┼───────┼───────┼─────────┼─────────┼─────────┼────────┤
276
+ │ src/grammar.py │ 5 │ 5 │ 0 │ 3 │ 1 │ 0 │
277
+ │ old.txt │ 2 │ 1 │ 1 │ 2 │ 1 │ 0 │
278
+ │ README.md │ 1 │ 1 │ 0 │ 1 │ 1 │ 0 │
279
+ │ src/lexer.py │ 1 │ 1 │ 0 │ 1 │ 1 │ 0 │
280
+ ╰────────────────┴───────┴───────┴─────────┴─────────┴─────────┴────────╯
281
+ ```
282
+
283
+ Churn is numeric additions plus deletions. The renamed parser is reported
284
+ under its target path, `src/grammar.py`. Binary changes are counted
285
+ separately and are not treated as zero-length text edits.
286
+
287
+ ### Timeline
288
+
289
+ `timeline` is a table of buckets, including empty months between the first
290
+ and last selected commit. Columns are bucket, commits, authors, added,
291
+ deleted, renames, and churn. `dig` uses the same header, then one table
292
+ each for survivors, the most changed files, extinct paths, large blobs,
293
+ and discoveries. `blobs` stays empty on this repository because the default
294
+ threshold is 10 MiB.
295
+
296
+ ### File Biography
297
+
298
+ `history --events src/grammar.py` follows the rename:
299
+
300
+ ```text
301
+ History
302
+ Origin confirmed Events 3
303
+ ╭──────────────┬────────────┬────────┬─────────────────────────────────┬───────╮
304
+ │ Commit │ When │ Status │ Path │ +/- │
305
+ ├──────────────┼────────────┼────────┼─────────────────────────────────┼───────┤
306
+ │ 2ea96a9a7202 │ 2024-01-15 │ A │ src/parser.py │ +2/-0 │
307
+ │ 46eecb288582 │ 2024-06-01 │ M │ src/parser.py │ +3/-0 │
308
+ │ a47913a78f68 │ 2025-02-01 │ R │ src/parser.py -> src/grammar.py │ +0/-0 │
309
+ ╰──────────────┴────────────┴────────┴─────────────────────────────────┴───────╯
310
+ ```
311
+
312
+ JSON always includes the event list. This excerpt is the rename event:
313
+
314
+ ```json
315
+ {
316
+ "additions": 0,
317
+ "deletions": 0,
318
+ "new_path": {
319
+ "path": "src/grammar.py",
320
+ "path_bytes_base64": "c3JjL2dyYW1tYXIucHk="
321
+ },
322
+ "old_path": {
323
+ "path": "src/parser.py",
324
+ "path_bytes_base64": "c3JjL3BhcnNlci5weQ=="
325
+ },
326
+ "similarity": 100,
327
+ "status": "R"
328
+ }
329
+ ```
330
+
331
+ `path_bytes_base64` is the reversible path. `origin_status` for this file is
332
+ `confirmed`. A shallow boundary or several possible introductions is reported
333
+ as `boundary` or `ambiguous` instead of an invented creation date.
334
+
335
+ ## Formats
336
+
337
+ JSON is one object plus a trailing newline. Keys are sorted. Repeated runs on
338
+ an unchanged repository are byte-stable: there is no generated-at timestamp.
339
+ Field names for schema 1.0 are described in
340
+ `schema/git-archaeologist-1.0.schema.json`.
341
+
342
+ ```json
343
+ {
344
+ "schema_version": "1.0",
345
+ "tool_version": "0.0.0",
346
+ "command": "contributors",
347
+ "status": "ok",
348
+ "data": {
349
+ "returned": 1,
350
+ "total": 1,
351
+ "truncated": false
352
+ },
353
+ "warnings": [],
354
+ "errors": []
355
+ }
356
+ ```
357
+
358
+ Markdown is a standalone report with a scope section, the command results,
359
+ and any warnings. Filenames are escaped in table cells.
360
+
361
+ ## Exit Status
362
+
363
+ | Exit | Meaning |
364
+ | ---- | ---------------------------------------------------------------- |
365
+ | 0 | Complete, including an empty repository or an empty date window |
366
+ | 1 | Internal failure |
367
+ | 2 | Usage error, including a bad date, size, or option combination |
368
+ | 3 | Git is missing, too old, or the path is not a usable repository |
369
+ | 4 | The branch, revision, or path could not be resolved |
370
+ | 5 | An optional section failed and a partial report was written |
371
+ | 130 | Interrupted |
372
+
373
+ <a href="https://github.com/the-lupaxa-project">
374
+ <img src="https://raw.githubusercontent.com/the-lupaxa-project/brand-assets/master/logos/components/footer-for-child-orgs.svg" alt="The Lupaxa Project Footer" width="100%" />
375
+ </a>