@procedures/git 0.2.3 → 0.4.0

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.
Files changed (157) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/README.md +125 -17
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/index.d.ts +2 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/module.d.ts.map +1 -1
  9. package/dist/module.js +314 -4
  10. package/dist/module.js.map +1 -1
  11. package/dist/procedures/git/blame.d.ts +17 -0
  12. package/dist/procedures/git/blame.d.ts.map +1 -0
  13. package/dist/procedures/git/blame.js +69 -0
  14. package/dist/procedures/git/blame.js.map +1 -0
  15. package/dist/procedures/git/branch/add.d.ts +12 -0
  16. package/dist/procedures/git/branch/add.d.ts.map +1 -0
  17. package/dist/procedures/git/branch/add.js +21 -0
  18. package/dist/procedures/git/branch/add.js.map +1 -0
  19. package/dist/procedures/git/branch/delete.d.ts +13 -0
  20. package/dist/procedures/git/branch/delete.d.ts.map +1 -0
  21. package/dist/procedures/git/branch/delete.js +24 -0
  22. package/dist/procedures/git/branch/delete.js.map +1 -0
  23. package/dist/procedures/git/branch/list.d.ts +13 -0
  24. package/dist/procedures/git/branch/list.d.ts.map +1 -0
  25. package/dist/procedures/git/branch/list.js +37 -0
  26. package/dist/procedures/git/branch/list.js.map +1 -0
  27. package/dist/procedures/git/branch.d.ts +8 -2
  28. package/dist/procedures/git/branch.d.ts.map +1 -1
  29. package/dist/procedures/git/branch.js +18 -37
  30. package/dist/procedures/git/branch.js.map +1 -1
  31. package/dist/procedures/git/commit.d.ts +2 -1
  32. package/dist/procedures/git/commit.d.ts.map +1 -1
  33. package/dist/procedures/git/commit.js +21 -12
  34. package/dist/procedures/git/commit.js.map +1 -1
  35. package/dist/procedures/git/index.d.ts +19 -0
  36. package/dist/procedures/git/index.d.ts.map +1 -1
  37. package/dist/procedures/git/index.js +19 -0
  38. package/dist/procedures/git/index.js.map +1 -1
  39. package/dist/procedures/git/init.d.ts +6 -2
  40. package/dist/procedures/git/init.d.ts.map +1 -1
  41. package/dist/procedures/git/init.js +8 -4
  42. package/dist/procedures/git/init.js.map +1 -1
  43. package/dist/procedures/git/merge/abort.d.ts +14 -0
  44. package/dist/procedures/git/merge/abort.d.ts.map +1 -0
  45. package/dist/procedures/git/merge/abort.js +18 -0
  46. package/dist/procedures/git/merge/abort.js.map +1 -0
  47. package/dist/procedures/git/merge.d.ts +16 -0
  48. package/dist/procedures/git/merge.d.ts.map +1 -0
  49. package/dist/procedures/git/merge.js +41 -0
  50. package/dist/procedures/git/merge.js.map +1 -0
  51. package/dist/procedures/git/porcelain.d.ts +27 -0
  52. package/dist/procedures/git/porcelain.d.ts.map +1 -0
  53. package/dist/procedures/git/porcelain.js +66 -0
  54. package/dist/procedures/git/porcelain.js.map +1 -0
  55. package/dist/procedures/git/push.d.ts.map +1 -1
  56. package/dist/procedures/git/push.js +4 -2
  57. package/dist/procedures/git/push.js.map +1 -1
  58. package/dist/procedures/git/rebase/abort.d.ts +13 -0
  59. package/dist/procedures/git/rebase/abort.d.ts.map +1 -0
  60. package/dist/procedures/git/rebase/abort.js +17 -0
  61. package/dist/procedures/git/rebase/abort.js.map +1 -0
  62. package/dist/procedures/git/rebase/continue.d.ts +13 -0
  63. package/dist/procedures/git/rebase/continue.d.ts.map +1 -0
  64. package/dist/procedures/git/rebase/continue.js +23 -0
  65. package/dist/procedures/git/rebase/continue.js.map +1 -0
  66. package/dist/procedures/git/rebase.d.ts +22 -0
  67. package/dist/procedures/git/rebase.d.ts.map +1 -0
  68. package/dist/procedures/git/rebase.js +46 -0
  69. package/dist/procedures/git/rebase.js.map +1 -0
  70. package/dist/procedures/git/refs.d.ts +31 -0
  71. package/dist/procedures/git/refs.d.ts.map +1 -0
  72. package/dist/procedures/git/refs.js +52 -0
  73. package/dist/procedures/git/refs.js.map +1 -0
  74. package/dist/procedures/git/reset.d.ts +13 -0
  75. package/dist/procedures/git/reset.d.ts.map +1 -0
  76. package/dist/procedures/git/reset.js +31 -0
  77. package/dist/procedures/git/reset.js.map +1 -0
  78. package/dist/procedures/git/restore.d.ts +13 -0
  79. package/dist/procedures/git/restore.d.ts.map +1 -0
  80. package/dist/procedures/git/restore.js +26 -0
  81. package/dist/procedures/git/restore.js.map +1 -0
  82. package/dist/procedures/git/revParse.d.ts +13 -0
  83. package/dist/procedures/git/revParse.d.ts.map +1 -0
  84. package/dist/procedures/git/revParse.js +23 -0
  85. package/dist/procedures/git/revParse.js.map +1 -0
  86. package/dist/procedures/git/run.d.ts +2 -0
  87. package/dist/procedures/git/run.d.ts.map +1 -1
  88. package/dist/procedures/git/run.js +1 -0
  89. package/dist/procedures/git/run.js.map +1 -1
  90. package/dist/procedures/git/show.d.ts +15 -0
  91. package/dist/procedures/git/show.d.ts.map +1 -0
  92. package/dist/procedures/git/show.js +49 -0
  93. package/dist/procedures/git/show.js.map +1 -0
  94. package/dist/procedures/git/status.d.ts +3 -1
  95. package/dist/procedures/git/status.d.ts.map +1 -1
  96. package/dist/procedures/git/status.js +11 -24
  97. package/dist/procedures/git/status.js.map +1 -1
  98. package/dist/procedures/git/tag/add.d.ts +12 -0
  99. package/dist/procedures/git/tag/add.d.ts.map +1 -0
  100. package/dist/procedures/git/tag/add.js +25 -0
  101. package/dist/procedures/git/tag/add.js.map +1 -0
  102. package/dist/procedures/git/tag/delete.d.ts +12 -0
  103. package/dist/procedures/git/tag/delete.d.ts.map +1 -0
  104. package/dist/procedures/git/tag/delete.js +19 -0
  105. package/dist/procedures/git/tag/delete.js.map +1 -0
  106. package/dist/procedures/git/tag/list.d.ts +12 -0
  107. package/dist/procedures/git/tag/list.d.ts.map +1 -0
  108. package/dist/procedures/git/tag/list.js +34 -0
  109. package/dist/procedures/git/tag/list.js.map +1 -0
  110. package/dist/procedures/git/worktree/add.d.ts +13 -0
  111. package/dist/procedures/git/worktree/add.d.ts.map +1 -0
  112. package/dist/procedures/git/worktree/add.js +35 -0
  113. package/dist/procedures/git/worktree/add.js.map +1 -0
  114. package/dist/procedures/git/worktree/list.d.ts +17 -0
  115. package/dist/procedures/git/worktree/list.d.ts.map +1 -0
  116. package/dist/procedures/git/worktree/list.js +52 -0
  117. package/dist/procedures/git/worktree/list.js.map +1 -0
  118. package/dist/procedures/git/worktree/remove.d.ts +13 -0
  119. package/dist/procedures/git/worktree/remove.d.ts.map +1 -0
  120. package/dist/procedures/git/worktree/remove.js +20 -0
  121. package/dist/procedures/git/worktree/remove.js.map +1 -0
  122. package/dist/types.d.ts +315 -0
  123. package/dist/types.d.ts.map +1 -1
  124. package/dist/types.js +280 -0
  125. package/dist/types.js.map +1 -1
  126. package/package.json +4 -4
  127. package/src/index.ts +2 -1
  128. package/src/module.ts +413 -4
  129. package/src/procedures/git/blame.ts +68 -0
  130. package/src/procedures/git/branch/add.ts +24 -0
  131. package/src/procedures/git/branch/delete.ts +29 -0
  132. package/src/procedures/git/branch/list.ts +40 -0
  133. package/src/procedures/git/branch.ts +19 -40
  134. package/src/procedures/git/commit.ts +20 -12
  135. package/src/procedures/git/index.ts +19 -0
  136. package/src/procedures/git/init.ts +11 -10
  137. package/src/procedures/git/merge/abort.ts +20 -0
  138. package/src/procedures/git/merge.ts +42 -0
  139. package/src/procedures/git/porcelain.ts +63 -0
  140. package/src/procedures/git/push.ts +4 -2
  141. package/src/procedures/git/rebase/abort.ts +19 -0
  142. package/src/procedures/git/rebase/continue.ts +25 -0
  143. package/src/procedures/git/rebase.ts +48 -0
  144. package/src/procedures/git/refs.ts +55 -0
  145. package/src/procedures/git/reset.ts +34 -0
  146. package/src/procedures/git/restore.ts +27 -0
  147. package/src/procedures/git/revParse.ts +24 -0
  148. package/src/procedures/git/run.ts +3 -0
  149. package/src/procedures/git/show.ts +57 -0
  150. package/src/procedures/git/status.ts +9 -17
  151. package/src/procedures/git/tag/add.ts +27 -0
  152. package/src/procedures/git/tag/delete.ts +22 -0
  153. package/src/procedures/git/tag/list.ts +36 -0
  154. package/src/procedures/git/worktree/add.ts +35 -0
  155. package/src/procedures/git/worktree/list.ts +48 -0
  156. package/src/procedures/git/worktree/remove.ts +21 -0
  157. package/src/types.ts +641 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # @procedures/git
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0ecc788: `git.status` and `git.commit` take `paths`, and the package root exports the git runner and a parser of `git status --porcelain=v1 -z`.
8
+
9
+ - `git.status` has two new options: `paths` (the pathspecs after `--`) and `untrackedFiles` (`--untracked-files=no|normal|all`). With `"all"`, git gives each file of a new folder. Without the options, the output does not change.
10
+ - `git.commit` has the new option `paths`. The commit then has only those paths, as they are in the working tree (`git commit -m <message> -- <paths>`). The other staged changes stay in the index.
11
+ - With `paths`, a change of a tracked file counts, staged or not. When no tracked file of the paths changed, the output has `skipped: true`. `all` and `paths` together give an error, because git refuses `-a` with paths.
12
+ - `parsePorcelainV1(output)` gives each entry with `xy`, the exact `path`, `status` and `staged`, and `from` for a rename or a copy. `classifyStatus(xy)` gives the status of two status letters.
13
+ - The root also exports `git(args, options)`, the runner of the procedures. It throws a `GitError` when git fails.
14
+
15
+ The effects of `git.status` and `git.commit` do not change.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [d919678]
20
+ - Updated dependencies [057d69a]
21
+ - Updated dependencies [b2a1a1e]
22
+ - Updated dependencies [057d69a]
23
+ - Updated dependencies [057d69a]
24
+ - Updated dependencies [057d69a]
25
+ - Updated dependencies [057d69a]
26
+ - Updated dependencies [057d69a]
27
+ - Updated dependencies [afd6a19]
28
+ - Updated dependencies [057d69a]
29
+ - Updated dependencies [4c51727]
30
+ - Updated dependencies [4e751da]
31
+ - @procedures/client@0.4.0
32
+ - @procedures/shell@0.4.0
33
+
34
+ ## 0.3.0
35
+
36
+ ### Minor Changes
37
+
38
+ - 4cad9ab: More git procedures (roadmap R40): `git.show`, `git.blame`, `git.tag.list`, `git.tag.add`, `git.tag.delete`, `git.revParse`, `git.reset`, `git.restore`, `git.merge`, `git.merge.abort`, `git.rebase`, `git.rebase.continue`, `git.rebase.abort`, `git.worktree.list`, `git.worktree.add` and `git.worktree.remove`. Each one declares its effects. A merge or a rebase that stops on conflicts gives `conflict: true` and the files, and git never starts an editor.
39
+
40
+ `git.branch` becomes three procedures: `git.branch.list`, `git.branch.add` and `git.branch.delete`. `git.branch` is deprecated. It stays for one release with the same input and output, and it calls the new code.
41
+
42
+ The current branch comes from `git symbolic-ref`. Before, `git.branch` and `git.push` used `git rev-parse --abbrev-ref HEAD`, which fails in a repository without commits. `git.branch.list` and `git.branch` work there now.
43
+
44
+ ### Patch Changes
45
+
46
+ - 95b660d: Three defects that the new tests of roadmap R33 found:
47
+
48
+ - `git.commit` gives `skipped: true` when nothing is staged. Before, an untracked file or a change that was not staged made `git commit` fail with "nothing added to commit". With `all`, a change of a tracked file is a change to commit, and an untracked file is not.
49
+ - `git.init` looks for `.git` itself. Before, it used `fs.exists` through its context, so it failed in a registry of `gitModule` alone (`createRegistry(gitModule)`).
50
+ - A component of `@procedures/splay` gives its registry to the children that it renders. Before, the child of a child came from the global registry, so a component in a registry of `createRegistry()` rendered an "unknown" grandchild.
51
+ - Updated dependencies [ddea529]
52
+ - Updated dependencies [b2a3e3a]
53
+ - Updated dependencies [a8c47f1]
54
+ - Updated dependencies [381ce3a]
55
+ - Updated dependencies [0c627f8]
56
+ - Updated dependencies [ae7f05f]
57
+ - Updated dependencies [7873940]
58
+ - Updated dependencies [a70d445]
59
+ - Updated dependencies [bc70357]
60
+ - Updated dependencies [07cc998]
61
+ - Updated dependencies [a6b01a9]
62
+ - Updated dependencies [c799cdd]
63
+ - Updated dependencies [540f8d9]
64
+ - Updated dependencies [b6daaec]
65
+ - Updated dependencies [5b9264e]
66
+ - Updated dependencies [956e88b]
67
+ - Updated dependencies [ff62281]
68
+ - Updated dependencies [d81d0ed]
69
+ - Updated dependencies [aa67cc7]
70
+ - Updated dependencies [061fa22]
71
+ - Updated dependencies [cfb9d69]
72
+ - Updated dependencies [43f7de5]
73
+ - Updated dependencies [b07bb50]
74
+ - Updated dependencies [4a3bfa1]
75
+ - Updated dependencies [bd0b626]
76
+ - Updated dependencies [a6be873]
77
+ - Updated dependencies [fb30718]
78
+ - Updated dependencies [c5528e4]
79
+ - Updated dependencies [fee5d9c]
80
+ - Updated dependencies [21f7743]
81
+ - Updated dependencies [31a0b46]
82
+ - @procedures/client@0.3.0
83
+ - @procedures/shell@0.3.0
84
+
3
85
  ## 0.2.3
4
86
 
5
87
  ### Patch Changes
package/README.md CHANGED
@@ -3,13 +3,13 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@procedures/git.svg)](https://www.npmjs.com/package/@procedures/git)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- > Git operations as RPC procedures - `git.add`, `git.commit`, `git.push`, `git.status`, and 22 more git commands exposed as type-safe procedures.
6
+ > Git operations as RPC procedures - `git.add`, `git.commit`, `git.push`, `git.status`, and 41 more git commands exposed as type-safe procedures.
7
7
 
8
8
  ## Overview
9
9
 
10
- `@procedures/git` exposes comprehensive Git functionality as RPC procedures through the client system. It provides 26 procedures covering all major Git operations including repository state management, staging, commits, branching, remote operations, stashing, and repository predicates.
10
+ `@procedures/git` exposes comprehensive Git functionality as RPC procedures through the client system. It provides 45 procedures covering all major Git operations including repository state management, staging, commits, branching, tags, merges, rebases, working trees, remote operations, stashing, and repository predicates.
11
11
 
12
- This package wraps Git commands directly (not through `client-shell`), providing structured input/output with full type safety via Zod schemas.
12
+ The package starts git with `runCommand` of `@procedures/shell`: an argument list, no shell. Each call is async, and its signal stops git. Zod schemas validate the input and the output.
13
13
 
14
14
  ## Architecture
15
15
 
@@ -36,11 +36,12 @@ graph TB
36
36
 
37
37
  ```mermaid
38
38
  graph LR
39
- A[client-git<br/>26 Procedures] --> B[Repository State<br/>5 procedures]
39
+ A[client-git<br/>45 Procedures] --> B[Repository State<br/>5 procedures]
40
40
  A --> C[Staging & Commits<br/>3 procedures]
41
41
  A --> D[Remote Operations<br/>5 procedures]
42
42
  A --> E[Predicates<br/>6 procedures]
43
43
  A --> F[Stash Operations<br/>7 procedures]
44
+ A --> G[History, Tags, Merge, Rebase,<br/>Working Trees, Branches<br/>19 procedures]
44
45
 
45
46
  B -.-> B1[status, log, diff,<br/>branch, init]
46
47
  C -.-> C1[add, commit,<br/>checkout]
@@ -107,6 +108,10 @@ interface GitStatusInput {
107
108
  cwd?: string;
108
109
  /** Also give `lines` in the format of `git status --short` (default: false) */
109
110
  short?: boolean;
111
+ /** Only the files of these pathspecs (`git status -- <paths>`) */
112
+ paths?: string[];
113
+ /** `--untracked-files`: "no", "normal" (a new folder is one entry) or "all" (each file) */
114
+ untrackedFiles?: "no" | "normal" | "all";
110
115
  }
111
116
 
112
117
  interface GitStatusFile {
@@ -135,8 +140,15 @@ const status = await client.exec(["git", "status"], { cwd: "./my-repo" });
135
140
  console.log(`On branch ${status.branch}`);
136
141
  console.log(`${status.ahead} commits ahead, ${status.behind} behind`);
137
142
  console.log(`${status.files.length} changed files`);
143
+
144
+ // Each new file under notes/, one entry for each file
145
+ const notes = await client.exec(["git", "status"], { cwd: "./my-repo", paths: ["notes"], untrackedFiles: "all" });
138
146
  ```
139
147
 
148
+ - Without `paths` and `untrackedFiles`, the procedure starts the same git command as before.
149
+ - After `--`, git reads each path as a pathspec. A path that starts with `-` is not an option.
150
+ - Without `untrackedFiles: "all"`, git gives a new folder as one entry, for example `notes/`.
151
+
140
152
  #### `git.log`
141
153
 
142
154
  Show commit history.
@@ -226,10 +238,12 @@ console.log(`${diff.additions} additions, ${diff.deletions} deletions`);
226
238
  const staged = await client.exec(["git", "diff"], { staged: true });
227
239
  ```
228
240
 
229
- #### `git.branch`
241
+ #### `git.branch` (deprecated)
230
242
 
231
243
  Branch operations - list, create, delete branches.
232
244
 
245
+ This procedure is deprecated since roadmap R40. Use `git.branch.list`, `git.branch.add` and `git.branch.delete`. It stays for one release, and it calls the code of the three new procedures. Its metadata has `deprecated: true`.
246
+
233
247
  **Path:** `["git", "branch"]`
234
248
 
235
249
  ```typescript
@@ -344,6 +358,8 @@ interface GitCommitInput {
344
358
  all?: boolean;
345
359
  /** Amend the last commit (default: false) */
346
360
  amend?: boolean;
361
+ /** Commit only these pathspecs, as they are in the working tree (`git commit -- <paths>`) */
362
+ paths?: string[];
347
363
  /** Working directory */
348
364
  cwd?: string;
349
365
  }
@@ -367,6 +383,17 @@ const commit = await client.exec(["git", "commit"], {
367
383
  console.log(`Created commit ${commit.hash}`);
368
384
  ```
369
385
 
386
+ With `paths`, the commit has only those paths, as they are in the working tree. The other staged changes stay in the index:
387
+
388
+ ```typescript
389
+ await client.exec(["git", "add"], { paths: ["ledger/new.ndjson"] });
390
+ await client.exec(["git", "commit"], { message: "ledger: the day", paths: ["ledger"] });
391
+ ```
392
+
393
+ - With `paths`, a change of a tracked file counts, staged or not. When no tracked file of the paths changed, the output has `skipped: true`.
394
+ - git does not commit an untracked file. Add a new file with `git.add` first.
395
+ - git refuses `-a` with paths. Thus `all` and `paths` together give an error.
396
+
370
397
  #### `git.checkout`
371
398
 
372
399
  Checkout branch, tag, or restore files.
@@ -841,6 +868,51 @@ const exported = await client.exec(["git", "stash", "export"], { index: 0 });
841
868
  fs.writeFileSync("backup.patch", exported.patch);
842
869
  ```
843
870
 
871
+ ### History, tags, merges, rebases and working trees (roadmap R40)
872
+
873
+ Each procedure takes `cwd`, the folder of the repository. A value that starts with `-` is not an option: a ref or a name is refused, and a path stays a path after `--`. The effects column shows `metadata.effects`. "process" means that git starts the hooks of the repository, which are code of the project.
874
+
875
+ | Procedure | Input | Output | Effects |
876
+ |---|---|---|---|
877
+ | `git.show` | `ref` (default `HEAD`), `path`, `stat` | Without `path`: `hash`, `author`, `email`, `date`, `message`, `body`, `files`, `diff`. With `path`: `content` | reads |
878
+ | `git.blame` | `path`, `ref`, `startLine`, `endLine` | `lines`: `line`, `hash`, `author`, `email`, `date`, `summary`, `content` | reads |
879
+ | `git.tag.list` | `pattern` | `tags`: `name`, `hash` (the commit), `annotated`, `message` | reads |
880
+ | `git.tag.add` | `name`, `ref`, `message` | `name`, `hash`, `annotated` | writes, not destructive, idempotent |
881
+ | `git.tag.delete` | `name` | `name`, `hash` (the object of the tag) | writes, destructive, idempotent |
882
+ | `git.revParse` | `ref` (default `HEAD`), `abbrevRef`, `short` | `ref`, `value` | reads |
883
+ | `git.reset` | `ref` (default `HEAD`), `mode` (`soft`, `mixed`, `hard`, `merge`, `keep`), `paths` | `ref`, `mode`, `hash` | writes, destructive |
884
+ | `git.restore` | `paths`, `source`, `staged`, `worktree` | `restored` | writes, process, destructive, idempotent |
885
+ | `git.merge` | `ref`, `fastForward` (`auto`, `only`, `never`), `message` | `hash`, `fastForward`, `upToDate`, `conflict`, `conflicts` | writes, process, idempotent |
886
+ | `git.merge.abort` | none | `aborted`, `hash` | writes, destructive, idempotent |
887
+ | `git.rebase` | `upstream`, `onto`, `branch` | `hash`, `completed`, `upToDate`, `conflict`, `conflicts` | writes, process, destructive, idempotent |
888
+ | `git.rebase.continue` | none | the output of `git.rebase` | writes, process, destructive |
889
+ | `git.rebase.abort` | none | `aborted`, `hash` | writes, destructive, idempotent |
890
+ | `git.worktree.list` | none | `worktrees`: `path`, `head`, `branch`, `detached`, `bare`, `locked`, `prunable` | reads |
891
+ | `git.worktree.add` | `path`, `ref`, `branch`, `detach` | `path`, `head`, `branch` | writes, process, not destructive, idempotent |
892
+ | `git.worktree.remove` | `path`, `force` | `path` | writes, destructive, idempotent |
893
+ | `git.branch.list` | `remote` | `branches`, `current` | reads |
894
+ | `git.branch.add` | `name`, `startPoint` | `name`, `hash` | writes, not destructive, idempotent |
895
+ | `git.branch.delete` | `name`, `force` | `name`, `hash` (the last commit) | writes, destructive, idempotent |
896
+
897
+ - A merge or a rebase that stops on conflicts is a result, not an error. Then `conflict` is `true`, and `conflicts` names the files.
898
+ - After the conflicts of a merge, resolve them and call `git.commit`, or call `git.merge.abort`.
899
+ - After the conflicts of a rebase, resolve them, stage them with `git.add`, and call `git.rebase.continue`. Or call `git.rebase.abort`.
900
+ - A merge and a rebase never start an editor. The rebase is never interactive.
901
+ - `git.tag.add` and `git.branch.add` never move a ref. An existing tag or branch is an error.
902
+ - `git.branch.delete` and `git.tag.delete` give the deleted hash. `git.branch.add` with it makes the branch again.
903
+ - `git.branch.list` works in a repository without commits. Then `branches` is empty and `current` is the branch that `HEAD` names.
904
+
905
+ ```typescript
906
+ const merge = await client.exec(["git", "merge"], { ref: "feature", cwd: "./repo" });
907
+ if (merge.conflict) {
908
+ console.log("Conflicts in", merge.conflicts);
909
+ await client.exec(["git", "merge", "abort"], { cwd: "./repo" });
910
+ }
911
+
912
+ const { lines } = await client.exec(["git", "blame"], { path: "src/index.ts", startLine: 1, endLine: 10 });
913
+ const { value: branch } = await client.exec(["git", "revParse"], { abbrevRef: true });
914
+ ```
915
+
844
916
  ## Complete Procedure List
845
917
 
846
918
  | Category | Procedure | Description |
@@ -848,8 +920,27 @@ fs.writeFileSync("backup.patch", exported.patch);
848
920
  | **Repository State** | `git.status` | Get repository status |
849
921
  | | `git.log` | Show commit history |
850
922
  | | `git.diff` | Show changes |
851
- | | `git.branch` | Branch operations |
923
+ | | `git.show` | Show a commit, or a file at a commit |
924
+ | | `git.blame` | Show the commit and the author of each line |
925
+ | | `git.revParse` | Give the hash or the name of a ref |
926
+ | | `git.branch` | Branch operations (deprecated) |
852
927
  | | `git.init` | Initialize repository |
928
+ | **Branches and Tags** | `git.branch.list` | List the branches |
929
+ | | `git.branch.add` | Make a branch |
930
+ | | `git.branch.delete` | Delete a branch |
931
+ | | `git.tag.list` | List the tags |
932
+ | | `git.tag.add` | Make a tag |
933
+ | | `git.tag.delete` | Delete a tag |
934
+ | **Merge and Rebase** | `git.merge` | Merge into the current branch |
935
+ | | `git.merge.abort` | Stop a merge with conflicts |
936
+ | | `git.rebase` | Rebase the current branch |
937
+ | | `git.rebase.continue` | Continue a rebase |
938
+ | | `git.rebase.abort` | Stop a rebase |
939
+ | **Working Trees** | `git.worktree.list` | List the working trees |
940
+ | | `git.worktree.add` | Add a working tree |
941
+ | | `git.worktree.remove` | Remove a working tree |
942
+ | **Undo** | `git.reset` | Move `HEAD`, reset the index or the working tree |
943
+ | | `git.restore` | Restore files |
853
944
  | **Staging & Commits** | `git.add` | Stage files |
854
945
  | | `git.commit` | Create commit |
855
946
  | | `git.checkout` | Checkout branch/files |
@@ -932,11 +1023,9 @@ await client.exec(["git", "commit"], { message: "feat: complete feature" });
932
1023
  await client.exec(["git", "checkout"], { ref: "main" });
933
1024
  await client.exec(["git", "pull"], {});
934
1025
 
935
- // Delete feature branch
936
- await client.exec(["git", "branch"], {
937
- name: "feature/new-feature",
938
- delete: true,
939
- });
1026
+ // Merge it, then delete the feature branch
1027
+ await client.exec(["git", "merge"], { ref: "feature/new-feature" });
1028
+ await client.exec(["git", "branch", "delete"], { name: "feature/new-feature" });
940
1029
  ```
941
1030
 
942
1031
  ### Working with Remotes
@@ -949,7 +1038,7 @@ const clone = await client.exec(["git", "clone"], {
949
1038
  });
950
1039
 
951
1040
  // Set remote
952
- await client.exec(["git", "remote"], {
1041
+ await client.exec(["git", "remote", "set"], {
953
1042
  name: "upstream",
954
1043
  url: "https://github.com/original/repo.git",
955
1044
  });
@@ -1013,17 +1102,20 @@ export async function commit(
1013
1102
 
1014
1103
  ## Configuration
1015
1104
 
1016
- ### Auto-Registration
1105
+ ### Registration
1106
+
1107
+ An import of the package root registers nothing. Import the `./register` entry to register the procedures in the global registry:
1108
+
1109
+ ```typescript
1110
+ import "@procedures/git/register";
1111
+ ```
1017
1112
 
1018
- Procedures are automatically registered when the package is loaded:
1113
+ The `client.procedures` field of `package.json` names that entry. `mark` finds the package by this field:
1019
1114
 
1020
1115
  ```json
1021
1116
  {
1022
1117
  "client": {
1023
1118
  "procedures": "./dist/register.js"
1024
- },
1025
- "scripts": {
1026
- "postinstall": "client-registry announce"
1027
1119
  }
1028
1120
  }
1029
1121
  ```
@@ -1055,6 +1147,22 @@ await gitCommit({ message: "feat: new feature", cwd: "./repo" });
1055
1147
  await gitPush({ remote: "origin", cwd: "./repo" }, { signal: AbortSignal.timeout(60_000) });
1056
1148
  ```
1057
1149
 
1150
+ ### The git runner and the porcelain parser
1151
+
1152
+ The package root also exports the functions that the procedures use:
1153
+
1154
+ - `git(args, { cwd, signal, input, env })` starts git with an argument list and gives its stdout. It throws a `GitError` when git fails.
1155
+ - `parsePorcelainV1(output)` reads the output of `git status --porcelain=v1 -z`.
1156
+ - Each entry has `xy` (the two status letters), the exact `path`, `status` and `staged`. A rename or a copy also has `from`.
1157
+ - `classifyStatus(xy)` gives the `status` and `staged` of two status letters.
1158
+
1159
+ ```typescript
1160
+ import { git, parsePorcelainV1 } from "@procedures/git";
1161
+
1162
+ const output = await git(["status", "--porcelain=v1", "-z", "--untracked-files=all", "--", "ledger"], { cwd: "./repo" });
1163
+ const untracked = parsePorcelainV1(output).filter((entry) => entry.status === "untracked");
1164
+ ```
1165
+
1058
1166
  ### Custom Registration
1059
1167
 
1060
1168
  ```typescript