git-hunk 0.3.0__tar.gz → 0.4.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_hunk-0.3.0 → git_hunk-0.4.0}/PKG-INFO +53 -50
- {git_hunk-0.3.0 → git_hunk-0.4.0}/README.md +51 -48
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/__init__.py +2 -0
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_cli.py +123 -70
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_git.py +22 -11
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_hunk.py +48 -47
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_lines.py +41 -38
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_patch.py +15 -13
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_skills.py +2 -2
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/_ui.py +75 -68
- {git_hunk-0.3.0 → git_hunk-0.4.0}/pyproject.toml +31 -1
- {git_hunk-0.3.0 → git_hunk-0.4.0}/.gitignore +0 -0
- {git_hunk-0.3.0 → git_hunk-0.4.0}/LICENSE +0 -0
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/__main__.py +0 -0
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/skills/core/SKILL.md +0 -0
- {git_hunk-0.3.0 → git_hunk-0.4.0}/git_hunk/skills/logical-commits/SKILL.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: git-hunk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Non-interactive, programmatic git hunk staging with durable Hunk IDs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/wkentaro/git-hunk
|
|
6
6
|
Project-URL: Issues, https://github.com/wkentaro/git-hunk/issues
|
|
@@ -41,6 +41,9 @@ Conditional IDs.
|
|
|
41
41
|
|
|
42
42
|
<img src="https://raw.githubusercontent.com/wkentaro/git-hunk/main/assets/teaser.png" alt="git-hunk teaser" width="800">
|
|
43
43
|
|
|
44
|
+
[Comparison](#comparison) • [Install](#install) • [For AI agents](#for-ai-agents) •
|
|
45
|
+
[Quick start](#quick-start) • [Usage](#usage) • [JSON output](#json-output)
|
|
46
|
+
|
|
44
47
|
## Why?
|
|
45
48
|
|
|
46
49
|
`git add -p` requires interactive input. That makes it unusable for:
|
|
@@ -52,38 +55,46 @@ Conditional IDs.
|
|
|
52
55
|
`git-hunk` solves this by assigning each staged or unstaged Hunk a durable ID
|
|
53
56
|
and exposing simple stage/unstage/discard commands.
|
|
54
57
|
|
|
55
|
-
##
|
|
58
|
+
## Comparison
|
|
59
|
+
|
|
60
|
+
| | Interactive | Programmatic | Hunk IDs | Line-level control | JSON output |
|
|
61
|
+
| ---------------- | ----------- | ------------ | -------- | ------------------ | ----------- |
|
|
62
|
+
| `git add -p` | Yes | No | No | Yes | No |
|
|
63
|
+
| `git add <file>` | No | Yes | No | No | No |
|
|
64
|
+
| **`git-hunk`** | **No** | **Yes** | **Yes** | **Yes** | **Yes** |
|
|
65
|
+
|
|
66
|
+
### Eval
|
|
56
67
|
|
|
57
68
|
One agent (Claude Code 2.1.226, `claude-sonnet-5`, reasoning effort `high`)
|
|
58
|
-
attempted the same eight tasks from identical repository state,
|
|
69
|
+
attempted the same eight tasks from identical repository state, five times per
|
|
59
70
|
variant: organize a dirty working tree into correct, focused commits, once
|
|
60
71
|
following git-hunk's bundled skills and once restricted to bare Git. The
|
|
61
|
-
[checked-in eval harness](https://github.com/wkentaro/git-hunk/tree/
|
|
72
|
+
[checked-in eval harness](https://github.com/wkentaro/git-hunk/tree/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval)
|
|
62
73
|
grades the exact resulting repository state — commit partition and order, final
|
|
63
74
|
tree, index, and leftovers. This table records the qualifying run; `make eval`
|
|
64
75
|
reruns the protocol and prints a table in the same format.
|
|
65
76
|
|
|
66
|
-
| Task
|
|
77
|
+
| Task | git-hunk | bare Git |
|
|
67
78
|
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------- |
|
|
68
|
-
| [split_refactor_vs_feature](https://github.com/wkentaro/git-hunk/blob/
|
|
69
|
-
| [separate_mixed_hunks](https://github.com/wkentaro/git-hunk/blob/
|
|
70
|
-
| [drop_debug_lines](https://github.com/wkentaro/git-hunk/blob/
|
|
71
|
-
| [protect_unrelated_work](https://github.com/wkentaro/git-hunk/blob/
|
|
72
|
-
| [split_single_hunk](https://github.com/wkentaro/git-hunk/blob/
|
|
73
|
-
| [separate_formatter_noise](https://github.com/wkentaro/git-hunk/blob/
|
|
74
|
-
| [pick_duplicate_hunk](https://github.com/wkentaro/git-hunk/blob/
|
|
75
|
-
| [commit_parseable_subset](https://github.com/wkentaro/git-hunk/blob/
|
|
76
|
-
| **total**
|
|
77
|
-
|
|
78
|
-
`c` = tool calls, `t` = turns; a cell reports the median of its
|
|
79
|
+
| [split_refactor_vs_feature](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/split_refactor_vs_feature.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 3c [2-5] · 4t [3-6] |
|
|
80
|
+
| [separate_mixed_hunks](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/separate_mixed_hunks.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 8c [7-12] · 9t [8-13] |
|
|
81
|
+
| [drop_debug_lines](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/drop_debug_lines.py) | PASS 5/5 · 3c [3-4] · 4t [4-5] | MIXED 4/5 partition · 8c [7-27] · 9t [8-28] |
|
|
82
|
+
| [protect_unrelated_work](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/protect_unrelated_work.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 3c [3-4] · 4t [4-5] |
|
|
83
|
+
| [split_single_hunk](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/split_single_hunk.py) | PASS 5/5 · 4c [3-4] · 5t [4-5] | PASS 5/5 · 11c [9-19] · 12t [10-20] |
|
|
84
|
+
| [separate_formatter_noise](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/separate_formatter_noise.py) | PASS 5/5 · 4c [4-6] · 5t [5-7] | PASS 5/5 · 13c [12-16] · 14t [13-17] |
|
|
85
|
+
| [pick_duplicate_hunk](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/pick_duplicate_hunk.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 8c [7-25] · 9t [8-26] |
|
|
86
|
+
| [commit_parseable_subset](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/commit_parseable_subset.py) | PASS 5/5 · 4c [3-5] · 5t [4-6] | MIXED 4/5 partition · 13c [10-23] · 14t [11-24] |
|
|
87
|
+
| **total** | **8/8 · 27c [25-31] · 35t [33-39]** | **6/8 (2 mixed) · 67c [57-131] · 75t [65-139]** |
|
|
88
|
+
|
|
89
|
+
`c` = tool calls, `t` = turns; a cell reports the median of its five repeats
|
|
79
90
|
with the observed range in brackets, dropped where every repeat agreed, and the
|
|
80
|
-
pass column counts passing repeats. `MIXED j/
|
|
81
|
-
|
|
91
|
+
pass column counts passing repeats. `MIXED j/5` means the variant passed j of its
|
|
92
|
+
five repeats, and `partition` names the failure: the commits made do not match
|
|
82
93
|
the required change groups. The cost column is omitted: bare Git runs second in
|
|
83
94
|
each pair and partly reads the prompt cache the git-hunk run warmed, so raw costs
|
|
84
95
|
are not order-neutral
|
|
85
|
-
([#224](https://github.com/wkentaro/git-hunk/issues/224)).
|
|
86
|
-
variant, dated 2026-08-
|
|
96
|
+
([#224](https://github.com/wkentaro/git-hunk/issues/224)). Five samples per task
|
|
97
|
+
variant, dated 2026-08-10 at commit `0ef14be`.
|
|
87
98
|
|
|
88
99
|
## Install
|
|
89
100
|
|
|
@@ -303,32 +314,32 @@ body; `show --json` adds a structured `lines` array. A `show --json` hunk
|
|
|
303
314
|
}
|
|
304
315
|
```
|
|
305
316
|
|
|
306
|
-
| Field
|
|
317
|
+
| Field | Type | Description |
|
|
307
318
|
| ---------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
308
|
-
| `schema_version` | int
|
|
309
|
-
| `hunks`
|
|
310
|
-
| `id`
|
|
311
|
-
| `id_stability`
|
|
312
|
-
| `file`
|
|
313
|
-
| `status`
|
|
314
|
-
| `change_kind`
|
|
315
|
-
| `a_mode`
|
|
316
|
-
| `b_mode`
|
|
317
|
-
| `binary`
|
|
318
|
-
| `header`
|
|
319
|
-
| `context_before` | union
|
|
320
|
-
| `additions`
|
|
321
|
-
| `deletions`
|
|
322
|
-
| `lines`
|
|
319
|
+
| `schema_version` | int | Envelope version; bumped on any incompatible change to the shape below. |
|
|
320
|
+
| `hunks` | array | The hunks (empty array when there are no changes). |
|
|
321
|
+
| `id` | string | Full canonical SHA-256 Hunk ID; empty for an `untracked` entry, which no command can address. Human output uses a unique prefix of at least seven characters. |
|
|
322
|
+
| `id_stability` | string | `stable` or `conditional`. An untracked inventory entry reports `stable`, but its empty `id` remains unaddressable. |
|
|
323
|
+
| `file` | union | Repository path of the changed file, as a byte-safe `{text\|bytes}` union (see below). |
|
|
324
|
+
| `status` | string | One of `staged`, `unstaged`, `untracked`. |
|
|
325
|
+
| `change_kind` | string | Git status letter: `A` added, `D` deleted, `M` modified, `T` typechange (`R`/`C` reserved and currently rejected). Always present. |
|
|
326
|
+
| `a_mode` | string | null | 6-digit octal git mode on the pre-image side; `null` when that side does not exist. |
|
|
327
|
+
| `b_mode` | string | null | 6-digit octal git mode on the post-image side; `null` when that side does not exist. |
|
|
328
|
+
| `binary` | bool | Whether the change is binary. Always present. |
|
|
329
|
+
| `header` | string | null | The bare `@@ -a,b +c,d @@` range for a text hunk; `null` for a whole-file hunk (binary, mode-only, type, or empty tracked file change) or an `untracked` inventory entry. |
|
|
330
|
+
| `context_before` | union | null | The function/section name after a text hunk's `@@` header, as a `{text\|bytes}` union; `null` for a text hunk without a heading, a whole-file hunk, or an `untracked` inventory entry. |
|
|
331
|
+
| `additions` | int | Number of added lines. |
|
|
332
|
+
| `deletions` | int | Number of removed lines. |
|
|
333
|
+
| `lines` | array | `show --json` only. The structured body; `[]` for a whole-file hunk. See below. |
|
|
323
334
|
|
|
324
335
|
A `lines` entry is `{ "n", "op", "content", "no_newline"? }`:
|
|
325
336
|
|
|
326
|
-
| Field
|
|
337
|
+
| Field | Type | Description |
|
|
327
338
|
| ------------ | ------ | --------------------------------------------------------------------------------------------------- |
|
|
328
|
-
| `n`
|
|
329
|
-
| `op`
|
|
330
|
-
| `content`
|
|
331
|
-
| `no_newline` | bool
|
|
339
|
+
| `n` | int | 1-based position within the hunk body — the index `-l` line selection uses. Counts every body line. |
|
|
340
|
+
| `op` | string | `" "` context, `"+"` addition, `"-"` deletion. |
|
|
341
|
+
| `content` | union | The line text **without** its leading op character, as a `{text\|bytes}` union. |
|
|
342
|
+
| `no_newline` | bool | Present and `true` only when the line has no trailing newline; consumes no `n`. |
|
|
332
343
|
|
|
333
344
|
Any field carrying arbitrary git/source bytes (`file`, `context_before`,
|
|
334
345
|
`lines[].content`) is a byte-safe `{text | bytes}` union: `{"text": "..."}` for
|
|
@@ -339,14 +350,6 @@ Adding a new field is backward-compatible and does not change `schema_version`;
|
|
|
339
350
|
renaming, removing, or changing the type of an existing field bumps it. (Before
|
|
340
351
|
`schema_version` existed, `list --json` returned a bare array.)
|
|
341
352
|
|
|
342
|
-
## Comparison
|
|
343
|
-
|
|
344
|
-
| | Interactive | Programmatic | Hunk IDs | Line-level control | JSON output |
|
|
345
|
-
| ---------------- | ----------- | ------------ | -------- | ------------------ | ----------- |
|
|
346
|
-
| `git add -p` | Yes | No | No | Yes | No |
|
|
347
|
-
| `git add <file>` | No | Yes | No | No | No |
|
|
348
|
-
| **`git-hunk`** | **No** | **Yes** | **Yes** | **Yes** | **Yes** |
|
|
349
|
-
|
|
350
353
|
## How it works
|
|
351
354
|
|
|
352
355
|
1. Rejects detected rename, copy, and unmerged states.
|
|
@@ -13,6 +13,9 @@ Conditional IDs.
|
|
|
13
13
|
|
|
14
14
|
<img src="assets/teaser.png" alt="git-hunk teaser" width="800">
|
|
15
15
|
|
|
16
|
+
[Comparison](#comparison) • [Install](#install) • [For AI agents](#for-ai-agents) •
|
|
17
|
+
[Quick start](#quick-start) • [Usage](#usage) • [JSON output](#json-output)
|
|
18
|
+
|
|
16
19
|
## Why?
|
|
17
20
|
|
|
18
21
|
`git add -p` requires interactive input. That makes it unusable for:
|
|
@@ -24,38 +27,46 @@ Conditional IDs.
|
|
|
24
27
|
`git-hunk` solves this by assigning each staged or unstaged Hunk a durable ID
|
|
25
28
|
and exposing simple stage/unstage/discard commands.
|
|
26
29
|
|
|
27
|
-
##
|
|
30
|
+
## Comparison
|
|
31
|
+
|
|
32
|
+
| | Interactive | Programmatic | Hunk IDs | Line-level control | JSON output |
|
|
33
|
+
| ---------------- | ----------- | ------------ | -------- | ------------------ | ----------- |
|
|
34
|
+
| `git add -p` | Yes | No | No | Yes | No |
|
|
35
|
+
| `git add <file>` | No | Yes | No | No | No |
|
|
36
|
+
| **`git-hunk`** | **No** | **Yes** | **Yes** | **Yes** | **Yes** |
|
|
37
|
+
|
|
38
|
+
### Eval
|
|
28
39
|
|
|
29
40
|
One agent (Claude Code 2.1.226, `claude-sonnet-5`, reasoning effort `high`)
|
|
30
|
-
attempted the same eight tasks from identical repository state,
|
|
41
|
+
attempted the same eight tasks from identical repository state, five times per
|
|
31
42
|
variant: organize a dirty working tree into correct, focused commits, once
|
|
32
43
|
following git-hunk's bundled skills and once restricted to bare Git. The
|
|
33
|
-
[checked-in eval harness](https://github.com/wkentaro/git-hunk/tree/
|
|
44
|
+
[checked-in eval harness](https://github.com/wkentaro/git-hunk/tree/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval)
|
|
34
45
|
grades the exact resulting repository state — commit partition and order, final
|
|
35
46
|
tree, index, and leftovers. This table records the qualifying run; `make eval`
|
|
36
47
|
reruns the protocol and prints a table in the same format.
|
|
37
48
|
|
|
38
|
-
| Task
|
|
49
|
+
| Task | git-hunk | bare Git |
|
|
39
50
|
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------- |
|
|
40
|
-
| [split_refactor_vs_feature](https://github.com/wkentaro/git-hunk/blob/
|
|
41
|
-
| [separate_mixed_hunks](https://github.com/wkentaro/git-hunk/blob/
|
|
42
|
-
| [drop_debug_lines](https://github.com/wkentaro/git-hunk/blob/
|
|
43
|
-
| [protect_unrelated_work](https://github.com/wkentaro/git-hunk/blob/
|
|
44
|
-
| [split_single_hunk](https://github.com/wkentaro/git-hunk/blob/
|
|
45
|
-
| [separate_formatter_noise](https://github.com/wkentaro/git-hunk/blob/
|
|
46
|
-
| [pick_duplicate_hunk](https://github.com/wkentaro/git-hunk/blob/
|
|
47
|
-
| [commit_parseable_subset](https://github.com/wkentaro/git-hunk/blob/
|
|
48
|
-
| **total**
|
|
49
|
-
|
|
50
|
-
`c` = tool calls, `t` = turns; a cell reports the median of its
|
|
51
|
+
| [split_refactor_vs_feature](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/split_refactor_vs_feature.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 3c [2-5] · 4t [3-6] |
|
|
52
|
+
| [separate_mixed_hunks](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/separate_mixed_hunks.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 8c [7-12] · 9t [8-13] |
|
|
53
|
+
| [drop_debug_lines](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/drop_debug_lines.py) | PASS 5/5 · 3c [3-4] · 4t [4-5] | MIXED 4/5 partition · 8c [7-27] · 9t [8-28] |
|
|
54
|
+
| [protect_unrelated_work](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/protect_unrelated_work.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 3c [3-4] · 4t [4-5] |
|
|
55
|
+
| [split_single_hunk](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/split_single_hunk.py) | PASS 5/5 · 4c [3-4] · 5t [4-5] | PASS 5/5 · 11c [9-19] · 12t [10-20] |
|
|
56
|
+
| [separate_formatter_noise](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/separate_formatter_noise.py) | PASS 5/5 · 4c [4-6] · 5t [5-7] | PASS 5/5 · 13c [12-16] · 14t [13-17] |
|
|
57
|
+
| [pick_duplicate_hunk](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/pick_duplicate_hunk.py) | PASS 5/5 · 3c · 4t | PASS 5/5 · 8c [7-25] · 9t [8-26] |
|
|
58
|
+
| [commit_parseable_subset](https://github.com/wkentaro/git-hunk/blob/0ef14bef657e187b5ab7283b0dbd64751a02736f/eval/tasks/commit_parseable_subset.py) | PASS 5/5 · 4c [3-5] · 5t [4-6] | MIXED 4/5 partition · 13c [10-23] · 14t [11-24] |
|
|
59
|
+
| **total** | **8/8 · 27c [25-31] · 35t [33-39]** | **6/8 (2 mixed) · 67c [57-131] · 75t [65-139]** |
|
|
60
|
+
|
|
61
|
+
`c` = tool calls, `t` = turns; a cell reports the median of its five repeats
|
|
51
62
|
with the observed range in brackets, dropped where every repeat agreed, and the
|
|
52
|
-
pass column counts passing repeats. `MIXED j/
|
|
53
|
-
|
|
63
|
+
pass column counts passing repeats. `MIXED j/5` means the variant passed j of its
|
|
64
|
+
five repeats, and `partition` names the failure: the commits made do not match
|
|
54
65
|
the required change groups. The cost column is omitted: bare Git runs second in
|
|
55
66
|
each pair and partly reads the prompt cache the git-hunk run warmed, so raw costs
|
|
56
67
|
are not order-neutral
|
|
57
|
-
([#224](https://github.com/wkentaro/git-hunk/issues/224)).
|
|
58
|
-
variant, dated 2026-08-
|
|
68
|
+
([#224](https://github.com/wkentaro/git-hunk/issues/224)). Five samples per task
|
|
69
|
+
variant, dated 2026-08-10 at commit `0ef14be`.
|
|
59
70
|
|
|
60
71
|
## Install
|
|
61
72
|
|
|
@@ -275,32 +286,32 @@ body; `show --json` adds a structured `lines` array. A `show --json` hunk
|
|
|
275
286
|
}
|
|
276
287
|
```
|
|
277
288
|
|
|
278
|
-
| Field
|
|
289
|
+
| Field | Type | Description |
|
|
279
290
|
| ---------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
280
|
-
| `schema_version` | int
|
|
281
|
-
| `hunks`
|
|
282
|
-
| `id`
|
|
283
|
-
| `id_stability`
|
|
284
|
-
| `file`
|
|
285
|
-
| `status`
|
|
286
|
-
| `change_kind`
|
|
287
|
-
| `a_mode`
|
|
288
|
-
| `b_mode`
|
|
289
|
-
| `binary`
|
|
290
|
-
| `header`
|
|
291
|
-
| `context_before` | union
|
|
292
|
-
| `additions`
|
|
293
|
-
| `deletions`
|
|
294
|
-
| `lines`
|
|
291
|
+
| `schema_version` | int | Envelope version; bumped on any incompatible change to the shape below. |
|
|
292
|
+
| `hunks` | array | The hunks (empty array when there are no changes). |
|
|
293
|
+
| `id` | string | Full canonical SHA-256 Hunk ID; empty for an `untracked` entry, which no command can address. Human output uses a unique prefix of at least seven characters. |
|
|
294
|
+
| `id_stability` | string | `stable` or `conditional`. An untracked inventory entry reports `stable`, but its empty `id` remains unaddressable. |
|
|
295
|
+
| `file` | union | Repository path of the changed file, as a byte-safe `{text\|bytes}` union (see below). |
|
|
296
|
+
| `status` | string | One of `staged`, `unstaged`, `untracked`. |
|
|
297
|
+
| `change_kind` | string | Git status letter: `A` added, `D` deleted, `M` modified, `T` typechange (`R`/`C` reserved and currently rejected). Always present. |
|
|
298
|
+
| `a_mode` | string | null | 6-digit octal git mode on the pre-image side; `null` when that side does not exist. |
|
|
299
|
+
| `b_mode` | string | null | 6-digit octal git mode on the post-image side; `null` when that side does not exist. |
|
|
300
|
+
| `binary` | bool | Whether the change is binary. Always present. |
|
|
301
|
+
| `header` | string | null | The bare `@@ -a,b +c,d @@` range for a text hunk; `null` for a whole-file hunk (binary, mode-only, type, or empty tracked file change) or an `untracked` inventory entry. |
|
|
302
|
+
| `context_before` | union | null | The function/section name after a text hunk's `@@` header, as a `{text\|bytes}` union; `null` for a text hunk without a heading, a whole-file hunk, or an `untracked` inventory entry. |
|
|
303
|
+
| `additions` | int | Number of added lines. |
|
|
304
|
+
| `deletions` | int | Number of removed lines. |
|
|
305
|
+
| `lines` | array | `show --json` only. The structured body; `[]` for a whole-file hunk. See below. |
|
|
295
306
|
|
|
296
307
|
A `lines` entry is `{ "n", "op", "content", "no_newline"? }`:
|
|
297
308
|
|
|
298
|
-
| Field
|
|
309
|
+
| Field | Type | Description |
|
|
299
310
|
| ------------ | ------ | --------------------------------------------------------------------------------------------------- |
|
|
300
|
-
| `n`
|
|
301
|
-
| `op`
|
|
302
|
-
| `content`
|
|
303
|
-
| `no_newline` | bool
|
|
311
|
+
| `n` | int | 1-based position within the hunk body — the index `-l` line selection uses. Counts every body line. |
|
|
312
|
+
| `op` | string | `" "` context, `"+"` addition, `"-"` deletion. |
|
|
313
|
+
| `content` | union | The line text **without** its leading op character, as a `{text\|bytes}` union. |
|
|
314
|
+
| `no_newline` | bool | Present and `true` only when the line has no trailing newline; consumes no `n`. |
|
|
304
315
|
|
|
305
316
|
Any field carrying arbitrary git/source bytes (`file`, `context_before`,
|
|
306
317
|
`lines[].content`) is a byte-safe `{text | bytes}` union: `{"text": "..."}` for
|
|
@@ -311,14 +322,6 @@ Adding a new field is backward-compatible and does not change `schema_version`;
|
|
|
311
322
|
renaming, removing, or changing the type of an existing field bumps it. (Before
|
|
312
323
|
`schema_version` existed, `list --json` returned a bare array.)
|
|
313
324
|
|
|
314
|
-
## Comparison
|
|
315
|
-
|
|
316
|
-
| | Interactive | Programmatic | Hunk IDs | Line-level control | JSON output |
|
|
317
|
-
| ---------------- | ----------- | ------------ | -------- | ------------------ | ----------- |
|
|
318
|
-
| `git add -p` | Yes | No | No | Yes | No |
|
|
319
|
-
| `git add <file>` | No | Yes | No | No | No |
|
|
320
|
-
| **`git-hunk`** | **No** | **Yes** | **Yes** | **Yes** | **Yes** |
|
|
321
|
-
|
|
322
325
|
## How it works
|
|
323
326
|
|
|
324
327
|
1. Rejects detected rename, copy, and unmerged states.
|