git-hot 0.6__tar.gz → 0.9__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_hot-0.9/PKG-INFO ADDED
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: git-hot
3
+ Version: 0.9
4
+ Summary: Git extension for reporting source code line lifetime and churn
5
+ Author: Diomidis Spinellis
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/dspinellis/code-lifetime
8
+ Project-URL: Issues, https://github.com/dspinellis/code-lifetime/issues
9
+ Keywords: git,churn,software-evolution,repository-mining
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Rust
18
+ Classifier: Topic :: Software Development :: Version Control :: Git
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Dynamic: license-file
23
+
24
+ # git-hot
25
+
26
+ `git-hot` is a Git extension that reports how ``hot'' (often-changing)
27
+ the current lines or files in a repository are.
28
+ It derives line lifetime and churn information from Git history,
29
+ then highlights files and lines that have changed often or recently.
30
+
31
+ Install the package and run it as either:
32
+
33
+ ```sh
34
+ git hot
35
+ git-hot
36
+ ```
37
+
38
+ The package installs two commands:
39
+
40
+ - `git-hot`, the Git extension command; [manual page](https://dspinellis.github.io/manview/?src=https%3A%2F%2Fraw.githubusercontent.com%2Fdspinellis%2Fgit-hot%2Frefs%2Fheads%2Fmaster%2Fgit-hot.1&name=git-hot&link=https%3A%2F%2Fgithub.com%2Fdspinellis%2Fgit-hot).
41
+ - `daglp`, a helper, written in Rust, used to compute the longest path
42
+ through the Git commit DAG; [manual page](https://dspinellis.github.io/manview/?src=https%3A%2F%2Fraw.githubusercontent.com%2Fdspinellis%2Fgit-hot%2Frefs%2Fheads%2Fmaster%2Fdaglp.1&name=daglp&link=https%3A%2F%2Fgithub.com%2Fdspinellis%2Fgit-hot).
43
+
44
+
45
+ ## Installation
46
+
47
+ For an isolated command installation:
48
+
49
+ ```sh
50
+ uv tool install git-hot
51
+ ```
52
+
53
+ For installation in an active virtual environment:
54
+
55
+ ```sh
56
+ uv pip install git-hot
57
+ ```
58
+
59
+ With `pip`:
60
+
61
+ ```sh
62
+ python -m pip install git-hot
63
+ ```
64
+
65
+ After installation, ensure the installation's script directory is on `PATH` so
66
+ Git can find `git-hot` and you can invoke it as `git hot`.
67
+
68
+ ## Usage
69
+
70
+ Show hot files in the current repository:
71
+
72
+ ```sh
73
+ git hot
74
+ ```
75
+
76
+ Show hot files at a specific revision:
77
+
78
+ ```sh
79
+ git hot HEAD
80
+ ```
81
+
82
+ Show line-level churn for one file:
83
+
84
+ ```sh
85
+ git hot -- src/main.py
86
+ ```
87
+
88
+ Show line ages and birth commits for one file:
89
+
90
+ ```sh
91
+ git hot -q --format '{days(age)} {hash[:7]} {line}' -- src/main.py
92
+ ```
93
+
94
+ Reconstruct all source files with churn prefixes below a directory:
95
+
96
+ ```sh
97
+ git hot --dir hot-tree HEAD
98
+ ```
99
+
100
+ ## Output
101
+
102
+ Without a path, `git hot` prints one line per current source file, sorted by
103
+ path. The default columns are:
104
+
105
+ - maximum live-line churn in the file
106
+ - median changed-line lifetime in days
107
+ - median live-line age in days
108
+ - repository path
109
+
110
+ With a path, `git hot` prints the reconstructed contents of that file. By
111
+ default each line is preceded by its churn count.
112
+
113
+ Use `--color always` or `--color never` to control color output. Automatic
114
+ coloring can rank lines by `churn`, `age`, or `lifetime`:
115
+
116
+ ```sh
117
+ git hot --color always --color-domain age -- src/main.py
118
+ ```
119
+
120
+ ## Formatting
121
+
122
+ Use `--format` to customize file or line output with a restricted Python
123
+ f-string expression. The available fields depend on whether repository-wide
124
+ file metrics or selected-path line output is being produced.
125
+
126
+ Examples:
127
+
128
+ ```sh
129
+ git hot --format '{max(churn):5d} {days(median(line_age)):5d} {path}'
130
+ git hot --format '{days(age)} {hash[:7]} {line}' -- src/main.py
131
+ ```
132
+
133
+ Common helpers include `days`, `max`, `min`, `median`, `mean`,
134
+ `quartile_rank`, `color`, and `color_reset`.
135
+
136
+ For the complete list of format fields and options, see:
137
+
138
+ ```sh
139
+ man git-hot
140
+ ```
141
+
142
+ or read the [git-hot manual page](https://dspinellis.github.io/manview/?src=https%3A%2F%2Fraw.githubusercontent.com%2Fdspinellis%2Fgit-hot%2Frefs%2Fheads%2Fmaster%2Fgit-hot.1&name=git-hot&link=https%3A%2F%2Fgithub.com%2Fdspinellis%2Fgit-hot).
143
+
144
+ ## Requirements
145
+
146
+ `git-hot` expects to run inside a Git repository.
147
+ Alternatively, the Git repository can be passed to the `git` command
148
+ using the `--git-dir` option.
149
+ Internally, it invokes Git commands such
150
+ as `git log`, `git show`, and `git diff`, and uses rename and copy detection.
151
+
152
+ Binary files and deleted files are skipped in file-metric output.
153
+
154
+ ## Installing From Source
155
+
156
+ Building from source requires Python 3.10 or later and a Rust toolchain with
157
+ `rustc`, because `daglp` is compiled during installation.
158
+
159
+ ```sh
160
+ uv sync --group dev
161
+ uv pip install -e .
162
+ uv run python -m unittest discover -s . -p 'test*.py'
163
+ uv run --group dev ruff check .
164
+ ```
165
+
166
+ Build a source distribution locally with:
167
+
168
+ ```sh
169
+ uv build --sdist
170
+ ```
171
+
172
+ Platform wheels are built in CI through `cibuildwheel`.
173
+
174
+ ## Research Tools
175
+
176
+ This repository also contains research-oriented source tools used for
177
+ fine-grained code lifetime analysis, including `lifetime.py`, `difflog.sh`,
178
+ `tokenize.pl`, and the top-level `daglp.rs`. They are kept in source form for
179
+ reproducibility and experimentation, but the installable package exposes only
180
+ `git-hot` and `daglp`.
181
+
182
+ For historical and research context, see [lifetime-tools.md](https://github.com/dspinellis/git-hot/blob/master/lifetime-tools.md).
183
+
184
+ ## License
185
+
186
+ `git-hot` is distributed under the Apache License 2.0. See `LICENSE`.
git_hot-0.9/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # git-hot
2
+
3
+ `git-hot` is a Git extension that reports how ``hot'' (often-changing)
4
+ the current lines or files in a repository are.
5
+ It derives line lifetime and churn information from Git history,
6
+ then highlights files and lines that have changed often or recently.
7
+
8
+ Install the package and run it as either:
9
+
10
+ ```sh
11
+ git hot
12
+ git-hot
13
+ ```
14
+
15
+ The package installs two commands:
16
+
17
+ - `git-hot`, the Git extension command; [manual page](https://dspinellis.github.io/manview/?src=https%3A%2F%2Fraw.githubusercontent.com%2Fdspinellis%2Fgit-hot%2Frefs%2Fheads%2Fmaster%2Fgit-hot.1&name=git-hot&link=https%3A%2F%2Fgithub.com%2Fdspinellis%2Fgit-hot).
18
+ - `daglp`, a helper, written in Rust, used to compute the longest path
19
+ through the Git commit DAG; [manual page](https://dspinellis.github.io/manview/?src=https%3A%2F%2Fraw.githubusercontent.com%2Fdspinellis%2Fgit-hot%2Frefs%2Fheads%2Fmaster%2Fdaglp.1&name=daglp&link=https%3A%2F%2Fgithub.com%2Fdspinellis%2Fgit-hot).
20
+
21
+
22
+ ## Installation
23
+
24
+ For an isolated command installation:
25
+
26
+ ```sh
27
+ uv tool install git-hot
28
+ ```
29
+
30
+ For installation in an active virtual environment:
31
+
32
+ ```sh
33
+ uv pip install git-hot
34
+ ```
35
+
36
+ With `pip`:
37
+
38
+ ```sh
39
+ python -m pip install git-hot
40
+ ```
41
+
42
+ After installation, ensure the installation's script directory is on `PATH` so
43
+ Git can find `git-hot` and you can invoke it as `git hot`.
44
+
45
+ ## Usage
46
+
47
+ Show hot files in the current repository:
48
+
49
+ ```sh
50
+ git hot
51
+ ```
52
+
53
+ Show hot files at a specific revision:
54
+
55
+ ```sh
56
+ git hot HEAD
57
+ ```
58
+
59
+ Show line-level churn for one file:
60
+
61
+ ```sh
62
+ git hot -- src/main.py
63
+ ```
64
+
65
+ Show line ages and birth commits for one file:
66
+
67
+ ```sh
68
+ git hot -q --format '{days(age)} {hash[:7]} {line}' -- src/main.py
69
+ ```
70
+
71
+ Reconstruct all source files with churn prefixes below a directory:
72
+
73
+ ```sh
74
+ git hot --dir hot-tree HEAD
75
+ ```
76
+
77
+ ## Output
78
+
79
+ Without a path, `git hot` prints one line per current source file, sorted by
80
+ path. The default columns are:
81
+
82
+ - maximum live-line churn in the file
83
+ - median changed-line lifetime in days
84
+ - median live-line age in days
85
+ - repository path
86
+
87
+ With a path, `git hot` prints the reconstructed contents of that file. By
88
+ default each line is preceded by its churn count.
89
+
90
+ Use `--color always` or `--color never` to control color output. Automatic
91
+ coloring can rank lines by `churn`, `age`, or `lifetime`:
92
+
93
+ ```sh
94
+ git hot --color always --color-domain age -- src/main.py
95
+ ```
96
+
97
+ ## Formatting
98
+
99
+ Use `--format` to customize file or line output with a restricted Python
100
+ f-string expression. The available fields depend on whether repository-wide
101
+ file metrics or selected-path line output is being produced.
102
+
103
+ Examples:
104
+
105
+ ```sh
106
+ git hot --format '{max(churn):5d} {days(median(line_age)):5d} {path}'
107
+ git hot --format '{days(age)} {hash[:7]} {line}' -- src/main.py
108
+ ```
109
+
110
+ Common helpers include `days`, `max`, `min`, `median`, `mean`,
111
+ `quartile_rank`, `color`, and `color_reset`.
112
+
113
+ For the complete list of format fields and options, see:
114
+
115
+ ```sh
116
+ man git-hot
117
+ ```
118
+
119
+ or read the [git-hot manual page](https://dspinellis.github.io/manview/?src=https%3A%2F%2Fraw.githubusercontent.com%2Fdspinellis%2Fgit-hot%2Frefs%2Fheads%2Fmaster%2Fgit-hot.1&name=git-hot&link=https%3A%2F%2Fgithub.com%2Fdspinellis%2Fgit-hot).
120
+
121
+ ## Requirements
122
+
123
+ `git-hot` expects to run inside a Git repository.
124
+ Alternatively, the Git repository can be passed to the `git` command
125
+ using the `--git-dir` option.
126
+ Internally, it invokes Git commands such
127
+ as `git log`, `git show`, and `git diff`, and uses rename and copy detection.
128
+
129
+ Binary files and deleted files are skipped in file-metric output.
130
+
131
+ ## Installing From Source
132
+
133
+ Building from source requires Python 3.10 or later and a Rust toolchain with
134
+ `rustc`, because `daglp` is compiled during installation.
135
+
136
+ ```sh
137
+ uv sync --group dev
138
+ uv pip install -e .
139
+ uv run python -m unittest discover -s . -p 'test*.py'
140
+ uv run --group dev ruff check .
141
+ ```
142
+
143
+ Build a source distribution locally with:
144
+
145
+ ```sh
146
+ uv build --sdist
147
+ ```
148
+
149
+ Platform wheels are built in CI through `cibuildwheel`.
150
+
151
+ ## Research Tools
152
+
153
+ This repository also contains research-oriented source tools used for
154
+ fine-grained code lifetime analysis, including `lifetime.py`, `difflog.sh`,
155
+ `tokenize.pl`, and the top-level `daglp.rs`. They are kept in source form for
156
+ reproducibility and experimentation, but the installable package exposes only
157
+ `git-hot` and `daglp`.
158
+
159
+ For historical and research context, see [lifetime-tools.md](https://github.com/dspinellis/git-hot/blob/master/lifetime-tools.md).
160
+
161
+ ## License
162
+
163
+ `git-hot` is distributed under the Apache License 2.0. See `LICENSE`.
git_hot-0.9/daglp.1 ADDED
@@ -0,0 +1,107 @@
1
+ .\" Copyright 1996-2026 Diomidis Spinellis
2
+ .\"
3
+ .\" Licensed under the Apache License, Version 2.0 (the "License");
4
+ .\" you may not use this file except in compliance with the License.
5
+ .\" You may obtain a copy of the License at
6
+ .\"
7
+ .\" http://www.apache.org/licenses/LICENSE-2.0
8
+ .\"
9
+ .\" Unless required by applicable law or agreed to in writing, software
10
+ .\" distributed under the License is distributed on an "AS IS" BASIS,
11
+ .\" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ .\" See the License for the specific language governing permissions and
13
+ .\" limitations under the License.
14
+ .\"
15
+ .TH DAGLP 1 "May 2026" "git-hot" "User Commands"
16
+ .SH NAME
17
+ daglp \- print the longest path through a directed acyclic graph
18
+ .SH SYNOPSIS
19
+ .SY daglp
20
+ .RI [ file ]
21
+ .YS
22
+ .SH DESCRIPTION
23
+ .B daglp
24
+ reads a directed acyclic graph whose vertices are listed in topological order
25
+ and prints the longest path from the graph's oldest/root side to its
26
+ newest/end side.
27
+ It is primarily used by
28
+ .BR git-hot (1)
29
+ to simplify Git history to a single path for code lifetime analysis.
30
+ .PP
31
+ Input is read from
32
+ .I file
33
+ when one argument is supplied.
34
+ Otherwise input is read from standard input.
35
+ .PP
36
+ Each non-empty input line has the form:
37
+ .PP
38
+ .EX
39
+ node identifier parent...
40
+ .EE
41
+ .PP
42
+ The first field is the node name.
43
+ The second field is an identifier that is printed with the node in output.
44
+ All remaining fields name parent nodes.
45
+ .PP
46
+ For Git history processing, input is normally produced with:
47
+ .PP
48
+ .EX
49
+ git log --topo-order --pretty=format:'%H %at %P'
50
+ .EE
51
+ .PP
52
+ where the node is the commit hash, the identifier is the commit timestamp, and
53
+ the remaining fields are parent commit hashes.
54
+ .SH INPUT ORDER
55
+ .B daglp
56
+ expects the input to be topologically sorted from newest node to oldest node,
57
+ as produced by
58
+ .BR git-log (1)
59
+ with
60
+ .BR --topo-order .
61
+ The program processes that order in reverse when calculating path lengths, so
62
+ parents are considered before their children without recursion.
63
+ .SH OUTPUT
64
+ .B daglp
65
+ prints the selected longest path one node per line, from oldest to newest.
66
+ Each output line has the form:
67
+ .PP
68
+ .EX
69
+ node identifier
70
+ .EE
71
+ .PP
72
+ When multiple parent choices have the same path length, the first encountered
73
+ choice is retained.
74
+ For Git input this preserves the original first-parent tie behavior.
75
+ .SH EXAMPLES
76
+ .PP
77
+ Print the longest path through the current repository's commit DAG:
78
+ .PP
79
+ .EX
80
+ $ git log --topo-order --pretty=format:'%H %at %P' | daglp
81
+ 13af1997c687bb4462f97ab512e51e8c072a2858 1370686723
82
+ d8e85967adc0b188a49117b5db4f10cc6c7c36cb 1370688578
83
+ 27a8ec806f16ae66a7eaa8563220f600c99b9ab9 1370688605
84
+ .EE
85
+ .PP
86
+ Read graph input from a file:
87
+ .PP
88
+ .EX
89
+ $ daglp commit-graph.txt
90
+ .EE
91
+ .SH EXIT STATUS
92
+ .TP
93
+ .B 0
94
+ Successful completion.
95
+ .TP
96
+ .B 1
97
+ An input file could not be opened, or an I/O error occurred while reading
98
+ input.
99
+ .SH NOTES
100
+ .B daglp
101
+ does not validate that the input graph is acyclic beyond relying on the
102
+ topological input order.
103
+ .PP
104
+ Empty input produces no output and exits successfully.
105
+ .SH SEE ALSO
106
+ .BR git-hot (1),
107
+ .BR git-log (1)
@@ -83,26 +83,26 @@ reports progress on standard error.
83
83
  When standard output is a terminal, output is sent through the configured Git
84
84
  pager.
85
85
  .SH OPTIONS
86
- .TP
86
+ .TP 25
87
87
  .B \-h, \-\-help
88
88
  Show usage information and exit.
89
- .TP
89
+ .TP 25
90
90
  .BI "\-d " dir ", \-\-dir " dir
91
91
  Reconstruct source files below
92
92
  .I dir
93
93
  with each line preceded by its churn count.
94
94
  This option also leaves the normal selected output behavior in effect.
95
- .TP
95
+ .TP 25
96
96
  .BI "\-\-format " format
97
97
  Format file or line output using a restricted Python f-string expression.
98
98
  The available fields depend on whether
99
99
  .B git hot
100
100
  is producing file metrics or reconstructed line output; see
101
101
  .BR "FORMAT STRINGS" .
102
- .TP
102
+ .TP 25
103
103
  .B \-q, \-\-quiet
104
104
  Suppress progress output.
105
- .TP
105
+ .TP 25
106
106
  .BI "\-D " opts ", \-\-debug " opts
107
107
  Enable debugging output selected by letters in
108
108
  .IR opts .
@@ -127,7 +127,7 @@ to show splicing operations,
127
127
  to reconstruct repository contents, and
128
128
  .B @
129
129
  to show range headers.
130
- .TP
130
+ .TP 25
131
131
  .BI "\-\-color " when
132
132
  Control ANSI color output.
133
133
  .I when
@@ -137,7 +137,7 @@ or
137
137
  .BR never .
138
138
  When this option is omitted, color is enabled only when standard output is a
139
139
  terminal.
140
- .TP
140
+ .TP 25
141
141
  .BI "\-\-color-domain " domain
142
142
  Choose the metric used for automatic color ranking.
143
143
  .I domain
@@ -174,20 +174,19 @@ The default repository-wide output is equivalent to the format
174
174
  .EE
175
175
  .PP
176
176
  The columns are:
177
- .TP
177
+ .TP 30
178
178
  .B max churn
179
179
  The maximum number of changes recorded for any live line in the file.
180
- .TP
180
+ .TP 30
181
181
  .B median changed lifetime
182
182
  The median time, in rounded integer days, between changes of lines in the file.
183
- .TP
183
+ .TP 30
184
184
  .B median line age
185
185
  The median age, in rounded integer days, of the file's live lines at the
186
186
  analyzed revision.
187
- .TP
187
+ .TP 30
188
188
  .B path
189
189
  The repository path.
190
- .SS Path Output
191
190
  For a selected
192
191
  .IR path ,
193
192
  the default output is equivalent to:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "git-hot"
7
- version = "0.6"
7
+ version = "0.9"
8
8
  description = "Git extension for reporting source code line lifetime and churn"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -12,7 +12,7 @@ license = "Apache-2.0"
12
12
  authors = [{ name = "Diomidis Spinellis" }]
13
13
  keywords = ["git", "churn", "software-evolution", "repository-mining"]
14
14
  classifiers = [
15
- "Development Status :: 3 - Alpha",
15
+ "Development Status :: 4 - Beta",
16
16
  "Environment :: Console",
17
17
  "Intended Audience :: Developers",
18
18
  "Programming Language :: Python :: 3",
@@ -48,7 +48,7 @@ where = ["src"]
48
48
  git_hot = ["daglp.rs"]
49
49
 
50
50
  [tool.setuptools.data-files]
51
- "share/man/man1" = ["git-hot.1"]
51
+ "share/man/man1" = ["git-hot.1", "daglp.1"]
52
52
 
53
53
  [tool.ruff]
54
54
  line-length = 100