gitx.do 0.1.1 → 0.1.2

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 (356) hide show
  1. package/README.md +40 -353
  2. package/dist/do/logger.d.ts +50 -0
  3. package/dist/do/logger.d.ts.map +1 -0
  4. package/dist/do/logger.js +122 -0
  5. package/dist/do/logger.js.map +1 -0
  6. package/dist/{durable-object → do}/schema.d.ts +3 -3
  7. package/dist/do/schema.d.ts.map +1 -0
  8. package/dist/{durable-object → do}/schema.js +4 -3
  9. package/dist/do/schema.js.map +1 -0
  10. package/dist/do/types.d.ts +267 -0
  11. package/dist/do/types.d.ts.map +1 -0
  12. package/dist/do/types.js +62 -0
  13. package/dist/do/types.js.map +1 -0
  14. package/dist/index.d.ts +14 -469
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +31 -483
  17. package/dist/index.js.map +1 -1
  18. package/package.json +13 -21
  19. package/dist/cli/commands/add.d.ts +0 -176
  20. package/dist/cli/commands/add.d.ts.map +0 -1
  21. package/dist/cli/commands/add.js +0 -979
  22. package/dist/cli/commands/add.js.map +0 -1
  23. package/dist/cli/commands/blame.d.ts +0 -259
  24. package/dist/cli/commands/blame.d.ts.map +0 -1
  25. package/dist/cli/commands/blame.js +0 -609
  26. package/dist/cli/commands/blame.js.map +0 -1
  27. package/dist/cli/commands/branch.d.ts +0 -249
  28. package/dist/cli/commands/branch.d.ts.map +0 -1
  29. package/dist/cli/commands/branch.js +0 -693
  30. package/dist/cli/commands/branch.js.map +0 -1
  31. package/dist/cli/commands/checkout.d.ts +0 -73
  32. package/dist/cli/commands/checkout.d.ts.map +0 -1
  33. package/dist/cli/commands/checkout.js +0 -725
  34. package/dist/cli/commands/checkout.js.map +0 -1
  35. package/dist/cli/commands/commit.d.ts +0 -182
  36. package/dist/cli/commands/commit.d.ts.map +0 -1
  37. package/dist/cli/commands/commit.js +0 -457
  38. package/dist/cli/commands/commit.js.map +0 -1
  39. package/dist/cli/commands/diff.d.ts +0 -464
  40. package/dist/cli/commands/diff.d.ts.map +0 -1
  41. package/dist/cli/commands/diff.js +0 -959
  42. package/dist/cli/commands/diff.js.map +0 -1
  43. package/dist/cli/commands/log.d.ts +0 -239
  44. package/dist/cli/commands/log.d.ts.map +0 -1
  45. package/dist/cli/commands/log.js +0 -535
  46. package/dist/cli/commands/log.js.map +0 -1
  47. package/dist/cli/commands/merge.d.ts +0 -106
  48. package/dist/cli/commands/merge.d.ts.map +0 -1
  49. package/dist/cli/commands/merge.js +0 -852
  50. package/dist/cli/commands/merge.js.map +0 -1
  51. package/dist/cli/commands/review.d.ts +0 -457
  52. package/dist/cli/commands/review.d.ts.map +0 -1
  53. package/dist/cli/commands/review.js +0 -558
  54. package/dist/cli/commands/review.js.map +0 -1
  55. package/dist/cli/commands/stash.d.ts +0 -157
  56. package/dist/cli/commands/stash.d.ts.map +0 -1
  57. package/dist/cli/commands/stash.js +0 -655
  58. package/dist/cli/commands/stash.js.map +0 -1
  59. package/dist/cli/commands/status.d.ts +0 -269
  60. package/dist/cli/commands/status.d.ts.map +0 -1
  61. package/dist/cli/commands/status.js +0 -492
  62. package/dist/cli/commands/status.js.map +0 -1
  63. package/dist/cli/commands/web.d.ts +0 -199
  64. package/dist/cli/commands/web.d.ts.map +0 -1
  65. package/dist/cli/commands/web.js +0 -697
  66. package/dist/cli/commands/web.js.map +0 -1
  67. package/dist/cli/fs-adapter.d.ts +0 -656
  68. package/dist/cli/fs-adapter.d.ts.map +0 -1
  69. package/dist/cli/fs-adapter.js +0 -1177
  70. package/dist/cli/fs-adapter.js.map +0 -1
  71. package/dist/cli/fsx-cli-adapter.d.ts +0 -359
  72. package/dist/cli/fsx-cli-adapter.d.ts.map +0 -1
  73. package/dist/cli/fsx-cli-adapter.js +0 -619
  74. package/dist/cli/fsx-cli-adapter.js.map +0 -1
  75. package/dist/cli/index.d.ts +0 -387
  76. package/dist/cli/index.d.ts.map +0 -1
  77. package/dist/cli/index.js +0 -579
  78. package/dist/cli/index.js.map +0 -1
  79. package/dist/cli/ui/components/DiffView.d.ts +0 -12
  80. package/dist/cli/ui/components/DiffView.d.ts.map +0 -1
  81. package/dist/cli/ui/components/DiffView.js +0 -11
  82. package/dist/cli/ui/components/DiffView.js.map +0 -1
  83. package/dist/cli/ui/components/ErrorDisplay.d.ts +0 -10
  84. package/dist/cli/ui/components/ErrorDisplay.d.ts.map +0 -1
  85. package/dist/cli/ui/components/ErrorDisplay.js +0 -11
  86. package/dist/cli/ui/components/ErrorDisplay.js.map +0 -1
  87. package/dist/cli/ui/components/FuzzySearch.d.ts +0 -15
  88. package/dist/cli/ui/components/FuzzySearch.d.ts.map +0 -1
  89. package/dist/cli/ui/components/FuzzySearch.js +0 -12
  90. package/dist/cli/ui/components/FuzzySearch.js.map +0 -1
  91. package/dist/cli/ui/components/LoadingSpinner.d.ts +0 -10
  92. package/dist/cli/ui/components/LoadingSpinner.d.ts.map +0 -1
  93. package/dist/cli/ui/components/LoadingSpinner.js +0 -10
  94. package/dist/cli/ui/components/LoadingSpinner.js.map +0 -1
  95. package/dist/cli/ui/components/NavigationList.d.ts +0 -14
  96. package/dist/cli/ui/components/NavigationList.d.ts.map +0 -1
  97. package/dist/cli/ui/components/NavigationList.js +0 -11
  98. package/dist/cli/ui/components/NavigationList.js.map +0 -1
  99. package/dist/cli/ui/components/ScrollableContent.d.ts +0 -13
  100. package/dist/cli/ui/components/ScrollableContent.d.ts.map +0 -1
  101. package/dist/cli/ui/components/ScrollableContent.js +0 -11
  102. package/dist/cli/ui/components/ScrollableContent.js.map +0 -1
  103. package/dist/cli/ui/components/index.d.ts +0 -7
  104. package/dist/cli/ui/components/index.d.ts.map +0 -1
  105. package/dist/cli/ui/components/index.js +0 -9
  106. package/dist/cli/ui/components/index.js.map +0 -1
  107. package/dist/cli/ui/terminal-ui.d.ts +0 -85
  108. package/dist/cli/ui/terminal-ui.d.ts.map +0 -1
  109. package/dist/cli/ui/terminal-ui.js +0 -121
  110. package/dist/cli/ui/terminal-ui.js.map +0 -1
  111. package/dist/do/BashModule.d.ts +0 -871
  112. package/dist/do/BashModule.d.ts.map +0 -1
  113. package/dist/do/BashModule.js +0 -1143
  114. package/dist/do/BashModule.js.map +0 -1
  115. package/dist/do/FsModule.d.ts +0 -612
  116. package/dist/do/FsModule.d.ts.map +0 -1
  117. package/dist/do/FsModule.js +0 -1120
  118. package/dist/do/FsModule.js.map +0 -1
  119. package/dist/do/GitModule.d.ts +0 -635
  120. package/dist/do/GitModule.d.ts.map +0 -1
  121. package/dist/do/GitModule.js +0 -784
  122. package/dist/do/GitModule.js.map +0 -1
  123. package/dist/do/GitRepoDO.d.ts +0 -281
  124. package/dist/do/GitRepoDO.d.ts.map +0 -1
  125. package/dist/do/GitRepoDO.js +0 -479
  126. package/dist/do/GitRepoDO.js.map +0 -1
  127. package/dist/do/bash-ast.d.ts +0 -246
  128. package/dist/do/bash-ast.d.ts.map +0 -1
  129. package/dist/do/bash-ast.js +0 -888
  130. package/dist/do/bash-ast.js.map +0 -1
  131. package/dist/do/container-executor.d.ts +0 -491
  132. package/dist/do/container-executor.d.ts.map +0 -1
  133. package/dist/do/container-executor.js +0 -731
  134. package/dist/do/container-executor.js.map +0 -1
  135. package/dist/do/index.d.ts +0 -53
  136. package/dist/do/index.d.ts.map +0 -1
  137. package/dist/do/index.js +0 -91
  138. package/dist/do/index.js.map +0 -1
  139. package/dist/do/tiered-storage.d.ts +0 -403
  140. package/dist/do/tiered-storage.d.ts.map +0 -1
  141. package/dist/do/tiered-storage.js +0 -689
  142. package/dist/do/tiered-storage.js.map +0 -1
  143. package/dist/do/withBash.d.ts +0 -231
  144. package/dist/do/withBash.d.ts.map +0 -1
  145. package/dist/do/withBash.js +0 -244
  146. package/dist/do/withBash.js.map +0 -1
  147. package/dist/do/withFs.d.ts +0 -237
  148. package/dist/do/withFs.d.ts.map +0 -1
  149. package/dist/do/withFs.js +0 -387
  150. package/dist/do/withFs.js.map +0 -1
  151. package/dist/do/withGit.d.ts +0 -180
  152. package/dist/do/withGit.d.ts.map +0 -1
  153. package/dist/do/withGit.js +0 -271
  154. package/dist/do/withGit.js.map +0 -1
  155. package/dist/durable-object/object-store.d.ts +0 -633
  156. package/dist/durable-object/object-store.d.ts.map +0 -1
  157. package/dist/durable-object/object-store.js +0 -1164
  158. package/dist/durable-object/object-store.js.map +0 -1
  159. package/dist/durable-object/schema.d.ts.map +0 -1
  160. package/dist/durable-object/schema.js.map +0 -1
  161. package/dist/durable-object/wal.d.ts +0 -416
  162. package/dist/durable-object/wal.d.ts.map +0 -1
  163. package/dist/durable-object/wal.js +0 -445
  164. package/dist/durable-object/wal.js.map +0 -1
  165. package/dist/mcp/adapter.d.ts +0 -772
  166. package/dist/mcp/adapter.d.ts.map +0 -1
  167. package/dist/mcp/adapter.js +0 -895
  168. package/dist/mcp/adapter.js.map +0 -1
  169. package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -22
  170. package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
  171. package/dist/mcp/sandbox/miniflare-evaluator.js +0 -140
  172. package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
  173. package/dist/mcp/sandbox/object-store-proxy.d.ts +0 -32
  174. package/dist/mcp/sandbox/object-store-proxy.d.ts.map +0 -1
  175. package/dist/mcp/sandbox/object-store-proxy.js +0 -30
  176. package/dist/mcp/sandbox/object-store-proxy.js.map +0 -1
  177. package/dist/mcp/sandbox/template.d.ts +0 -17
  178. package/dist/mcp/sandbox/template.d.ts.map +0 -1
  179. package/dist/mcp/sandbox/template.js +0 -71
  180. package/dist/mcp/sandbox/template.js.map +0 -1
  181. package/dist/mcp/sandbox.d.ts +0 -764
  182. package/dist/mcp/sandbox.d.ts.map +0 -1
  183. package/dist/mcp/sandbox.js +0 -1362
  184. package/dist/mcp/sandbox.js.map +0 -1
  185. package/dist/mcp/sdk-adapter.d.ts +0 -835
  186. package/dist/mcp/sdk-adapter.d.ts.map +0 -1
  187. package/dist/mcp/sdk-adapter.js +0 -974
  188. package/dist/mcp/sdk-adapter.js.map +0 -1
  189. package/dist/mcp/tools/do.d.ts +0 -32
  190. package/dist/mcp/tools/do.d.ts.map +0 -1
  191. package/dist/mcp/tools/do.js +0 -117
  192. package/dist/mcp/tools/do.js.map +0 -1
  193. package/dist/mcp/tools.d.ts +0 -548
  194. package/dist/mcp/tools.d.ts.map +0 -1
  195. package/dist/mcp/tools.js +0 -3170
  196. package/dist/mcp/tools.js.map +0 -1
  197. package/dist/ops/blame.d.ts +0 -551
  198. package/dist/ops/blame.d.ts.map +0 -1
  199. package/dist/ops/blame.js +0 -1037
  200. package/dist/ops/blame.js.map +0 -1
  201. package/dist/ops/branch.d.ts +0 -766
  202. package/dist/ops/branch.d.ts.map +0 -1
  203. package/dist/ops/branch.js +0 -950
  204. package/dist/ops/branch.js.map +0 -1
  205. package/dist/ops/commit-traversal.d.ts +0 -349
  206. package/dist/ops/commit-traversal.d.ts.map +0 -1
  207. package/dist/ops/commit-traversal.js +0 -821
  208. package/dist/ops/commit-traversal.js.map +0 -1
  209. package/dist/ops/commit.d.ts +0 -555
  210. package/dist/ops/commit.d.ts.map +0 -1
  211. package/dist/ops/commit.js +0 -826
  212. package/dist/ops/commit.js.map +0 -1
  213. package/dist/ops/merge-base.d.ts +0 -397
  214. package/dist/ops/merge-base.d.ts.map +0 -1
  215. package/dist/ops/merge-base.js +0 -691
  216. package/dist/ops/merge-base.js.map +0 -1
  217. package/dist/ops/merge.d.ts +0 -855
  218. package/dist/ops/merge.d.ts.map +0 -1
  219. package/dist/ops/merge.js +0 -1551
  220. package/dist/ops/merge.js.map +0 -1
  221. package/dist/ops/tag.d.ts +0 -247
  222. package/dist/ops/tag.d.ts.map +0 -1
  223. package/dist/ops/tag.js +0 -649
  224. package/dist/ops/tag.js.map +0 -1
  225. package/dist/ops/tree-builder.d.ts +0 -178
  226. package/dist/ops/tree-builder.d.ts.map +0 -1
  227. package/dist/ops/tree-builder.js +0 -271
  228. package/dist/ops/tree-builder.js.map +0 -1
  229. package/dist/ops/tree-diff.d.ts +0 -291
  230. package/dist/ops/tree-diff.d.ts.map +0 -1
  231. package/dist/ops/tree-diff.js +0 -705
  232. package/dist/ops/tree-diff.js.map +0 -1
  233. package/dist/pack/delta.d.ts +0 -248
  234. package/dist/pack/delta.d.ts.map +0 -1
  235. package/dist/pack/delta.js +0 -740
  236. package/dist/pack/delta.js.map +0 -1
  237. package/dist/pack/format.d.ts +0 -446
  238. package/dist/pack/format.d.ts.map +0 -1
  239. package/dist/pack/format.js +0 -572
  240. package/dist/pack/format.js.map +0 -1
  241. package/dist/pack/full-generation.d.ts +0 -612
  242. package/dist/pack/full-generation.d.ts.map +0 -1
  243. package/dist/pack/full-generation.js +0 -1378
  244. package/dist/pack/full-generation.js.map +0 -1
  245. package/dist/pack/generation.d.ts +0 -441
  246. package/dist/pack/generation.d.ts.map +0 -1
  247. package/dist/pack/generation.js +0 -707
  248. package/dist/pack/generation.js.map +0 -1
  249. package/dist/pack/index.d.ts +0 -502
  250. package/dist/pack/index.d.ts.map +0 -1
  251. package/dist/pack/index.js +0 -833
  252. package/dist/pack/index.js.map +0 -1
  253. package/dist/refs/branch.d.ts +0 -683
  254. package/dist/refs/branch.d.ts.map +0 -1
  255. package/dist/refs/branch.js +0 -881
  256. package/dist/refs/branch.js.map +0 -1
  257. package/dist/refs/storage.d.ts +0 -833
  258. package/dist/refs/storage.d.ts.map +0 -1
  259. package/dist/refs/storage.js +0 -1023
  260. package/dist/refs/storage.js.map +0 -1
  261. package/dist/refs/tag.d.ts +0 -860
  262. package/dist/refs/tag.d.ts.map +0 -1
  263. package/dist/refs/tag.js +0 -996
  264. package/dist/refs/tag.js.map +0 -1
  265. package/dist/storage/backend.d.ts +0 -425
  266. package/dist/storage/backend.d.ts.map +0 -1
  267. package/dist/storage/backend.js +0 -41
  268. package/dist/storage/backend.js.map +0 -1
  269. package/dist/storage/fsx-adapter.d.ts +0 -204
  270. package/dist/storage/fsx-adapter.d.ts.map +0 -1
  271. package/dist/storage/fsx-adapter.js +0 -518
  272. package/dist/storage/fsx-adapter.js.map +0 -1
  273. package/dist/storage/lru-cache.d.ts +0 -691
  274. package/dist/storage/lru-cache.d.ts.map +0 -1
  275. package/dist/storage/lru-cache.js +0 -813
  276. package/dist/storage/lru-cache.js.map +0 -1
  277. package/dist/storage/object-index.d.ts +0 -585
  278. package/dist/storage/object-index.d.ts.map +0 -1
  279. package/dist/storage/object-index.js +0 -532
  280. package/dist/storage/object-index.js.map +0 -1
  281. package/dist/storage/r2-pack.d.ts +0 -1257
  282. package/dist/storage/r2-pack.d.ts.map +0 -1
  283. package/dist/storage/r2-pack.js +0 -1773
  284. package/dist/storage/r2-pack.js.map +0 -1
  285. package/dist/tiered/cdc-pipeline.d.ts +0 -1888
  286. package/dist/tiered/cdc-pipeline.d.ts.map +0 -1
  287. package/dist/tiered/cdc-pipeline.js +0 -1880
  288. package/dist/tiered/cdc-pipeline.js.map +0 -1
  289. package/dist/tiered/migration.d.ts +0 -1104
  290. package/dist/tiered/migration.d.ts.map +0 -1
  291. package/dist/tiered/migration.js +0 -1217
  292. package/dist/tiered/migration.js.map +0 -1
  293. package/dist/tiered/parquet-writer.d.ts +0 -1145
  294. package/dist/tiered/parquet-writer.d.ts.map +0 -1
  295. package/dist/tiered/parquet-writer.js +0 -1183
  296. package/dist/tiered/parquet-writer.js.map +0 -1
  297. package/dist/tiered/read-path.d.ts +0 -835
  298. package/dist/tiered/read-path.d.ts.map +0 -1
  299. package/dist/tiered/read-path.js +0 -487
  300. package/dist/tiered/read-path.js.map +0 -1
  301. package/dist/types/capability.d.ts +0 -1385
  302. package/dist/types/capability.d.ts.map +0 -1
  303. package/dist/types/capability.js +0 -36
  304. package/dist/types/capability.js.map +0 -1
  305. package/dist/types/index.d.ts +0 -13
  306. package/dist/types/index.d.ts.map +0 -1
  307. package/dist/types/index.js +0 -18
  308. package/dist/types/index.js.map +0 -1
  309. package/dist/types/interfaces.d.ts +0 -673
  310. package/dist/types/interfaces.d.ts.map +0 -1
  311. package/dist/types/interfaces.js +0 -26
  312. package/dist/types/interfaces.js.map +0 -1
  313. package/dist/types/objects.d.ts +0 -692
  314. package/dist/types/objects.d.ts.map +0 -1
  315. package/dist/types/objects.js +0 -837
  316. package/dist/types/objects.js.map +0 -1
  317. package/dist/types/storage.d.ts +0 -603
  318. package/dist/types/storage.d.ts.map +0 -1
  319. package/dist/types/storage.js +0 -191
  320. package/dist/types/storage.js.map +0 -1
  321. package/dist/types/worker-loader.d.ts +0 -60
  322. package/dist/types/worker-loader.d.ts.map +0 -1
  323. package/dist/types/worker-loader.js +0 -62
  324. package/dist/types/worker-loader.js.map +0 -1
  325. package/dist/utils/hash.d.ts +0 -198
  326. package/dist/utils/hash.d.ts.map +0 -1
  327. package/dist/utils/hash.js +0 -272
  328. package/dist/utils/hash.js.map +0 -1
  329. package/dist/utils/sha1.d.ts +0 -325
  330. package/dist/utils/sha1.d.ts.map +0 -1
  331. package/dist/utils/sha1.js +0 -635
  332. package/dist/utils/sha1.js.map +0 -1
  333. package/dist/wire/capabilities.d.ts +0 -1044
  334. package/dist/wire/capabilities.d.ts.map +0 -1
  335. package/dist/wire/capabilities.js +0 -941
  336. package/dist/wire/capabilities.js.map +0 -1
  337. package/dist/wire/path-security.d.ts +0 -157
  338. package/dist/wire/path-security.d.ts.map +0 -1
  339. package/dist/wire/path-security.js +0 -307
  340. package/dist/wire/path-security.js.map +0 -1
  341. package/dist/wire/pkt-line.d.ts +0 -345
  342. package/dist/wire/pkt-line.d.ts.map +0 -1
  343. package/dist/wire/pkt-line.js +0 -381
  344. package/dist/wire/pkt-line.js.map +0 -1
  345. package/dist/wire/receive-pack.d.ts +0 -1059
  346. package/dist/wire/receive-pack.d.ts.map +0 -1
  347. package/dist/wire/receive-pack.js +0 -1414
  348. package/dist/wire/receive-pack.js.map +0 -1
  349. package/dist/wire/smart-http.d.ts +0 -799
  350. package/dist/wire/smart-http.d.ts.map +0 -1
  351. package/dist/wire/smart-http.js +0 -945
  352. package/dist/wire/smart-http.js.map +0 -1
  353. package/dist/wire/upload-pack.d.ts +0 -727
  354. package/dist/wire/upload-pack.d.ts.map +0 -1
  355. package/dist/wire/upload-pack.js +0 -1141
  356. package/dist/wire/upload-pack.js.map +0 -1
@@ -1,826 +0,0 @@
1
- /**
2
- * @fileoverview Commit Creation Operations
3
- *
4
- * Provides functionality for creating, formatting, and amending git commits.
5
- * Supports author/committer info, parent handling, GPG signing, and message formatting.
6
- *
7
- * ## Features
8
- *
9
- * - Create new commits with full metadata
10
- * - Amend existing commits
11
- * - GPG signature support
12
- * - Message formatting and validation
13
- * - Empty commit detection
14
- * - Author/committer timestamp handling
15
- *
16
- * ## Usage Example
17
- *
18
- * ```typescript
19
- * import { createCommit, formatCommitMessage } from './ops/commit'
20
- *
21
- * // Create a commit
22
- * const result = await createCommit(store, {
23
- * message: 'Add new feature',
24
- * tree: treeHash,
25
- * parents: [parentHash],
26
- * author: { name: 'John Doe', email: 'john@example.com' }
27
- * })
28
- *
29
- * console.log('Created commit:', result.sha)
30
- * ```
31
- *
32
- * @module ops/commit
33
- */
34
- // ============================================================================
35
- // Author/Timestamp Utilities
36
- // ============================================================================
37
- /**
38
- * Gets the current timezone offset string.
39
- *
40
- * Returns the local timezone in Git's format (e.g., '+0000', '-0500').
41
- *
42
- * @returns Timezone offset string
43
- *
44
- * @example
45
- * ```typescript
46
- * const tz = getCurrentTimezone()
47
- * // Returns something like '-0800' for Pacific time
48
- * ```
49
- */
50
- export function getCurrentTimezone() {
51
- const offset = new Date().getTimezoneOffset();
52
- const sign = offset <= 0 ? '+' : '-';
53
- const absOffset = Math.abs(offset);
54
- const hours = Math.floor(absOffset / 60);
55
- const minutes = absOffset % 60;
56
- return `${sign}${String(hours).padStart(2, '0')}${String(minutes).padStart(2, '0')}`;
57
- }
58
- /**
59
- * Formats a timestamp and timezone as git author/committer format.
60
- *
61
- * @param timestamp - Unix timestamp in seconds
62
- * @param timezone - Timezone offset string (e.g., '+0000', '-0500')
63
- * @returns Formatted string like "1234567890 +0000"
64
- *
65
- * @example
66
- * ```typescript
67
- * const formatted = formatTimestamp(1609459200, '+0000')
68
- * // Returns "1609459200 +0000"
69
- * ```
70
- */
71
- export function formatTimestamp(timestamp, timezone) {
72
- return `${timestamp} ${timezone}`;
73
- }
74
- /**
75
- * Parses a git timestamp string.
76
- *
77
- * @param timestampStr - Timestamp string like "1234567890 +0000"
78
- * @returns Object with parsed timestamp and timezone
79
- *
80
- * @throws {Error} If the format is invalid
81
- *
82
- * @example
83
- * ```typescript
84
- * const { timestamp, timezone } = parseTimestamp("1609459200 -0500")
85
- * // timestamp = 1609459200, timezone = "-0500"
86
- * ```
87
- */
88
- export function parseTimestamp(timestampStr) {
89
- const match = timestampStr.match(/^(\d+) ([+-]\d{4})$/);
90
- if (!match) {
91
- throw new Error(`Invalid timestamp format: ${timestampStr}`);
92
- }
93
- return {
94
- timestamp: parseInt(match[1], 10),
95
- timezone: match[2]
96
- };
97
- }
98
- /**
99
- * Creates an Author object with current timestamp.
100
- *
101
- * Convenience function for creating author information with
102
- * the current time and local timezone.
103
- *
104
- * @param name - Author name
105
- * @param email - Author email
106
- * @param timezone - Optional timezone (defaults to local timezone)
107
- * @returns Author object with current timestamp
108
- *
109
- * @example
110
- * ```typescript
111
- * const author = createAuthor('John Doe', 'john@example.com')
112
- * // { name: 'John Doe', email: 'john@example.com', timestamp: <now>, timezone: <local> }
113
- * ```
114
- */
115
- export function createAuthor(name, email, timezone) {
116
- return {
117
- name,
118
- email,
119
- timestamp: Math.floor(Date.now() / 1000),
120
- timezone: timezone ?? getCurrentTimezone()
121
- };
122
- }
123
- // ============================================================================
124
- // Message Formatting
125
- // ============================================================================
126
- /**
127
- * Wraps text at a specified column width.
128
- * @internal
129
- */
130
- function wrapText(text, column) {
131
- if (column <= 0)
132
- return text;
133
- const words = text.split(/\s+/);
134
- const lines = [];
135
- let currentLine = '';
136
- for (const word of words) {
137
- if (currentLine.length === 0) {
138
- currentLine = word;
139
- }
140
- else if (currentLine.length + 1 + word.length <= column) {
141
- currentLine += ' ' + word;
142
- }
143
- else {
144
- lines.push(currentLine);
145
- currentLine = word;
146
- }
147
- }
148
- if (currentLine.length > 0) {
149
- lines.push(currentLine);
150
- }
151
- return lines.join('\n');
152
- }
153
- /**
154
- * Formats a commit message according to git conventions.
155
- *
156
- * Applies various transformations based on the cleanup mode:
157
- * - Strips comments
158
- * - Normalizes whitespace
159
- * - Wraps long lines
160
- * - Removes scissors markers
161
- *
162
- * @param message - The raw commit message
163
- * @param options - Formatting options
164
- * @returns The formatted commit message
165
- *
166
- * @example
167
- * ```typescript
168
- * // Clean up a message
169
- * const formatted = formatCommitMessage(`
170
- * Add feature
171
- *
172
- * # This is a comment
173
- * Long description here
174
- * `, { cleanup: 'strip' })
175
- * // Returns: "Add feature\n\nLong description here"
176
- * ```
177
- */
178
- export function formatCommitMessage(message, options = {}) {
179
- const { cleanup = 'default', commentChar = '#', wrapColumn = 0 } = options;
180
- // Verbatim mode: return message as-is
181
- if (cleanup === 'verbatim') {
182
- return message;
183
- }
184
- let result = message;
185
- // Scissors mode: remove everything after scissors line
186
- if (cleanup === 'scissors') {
187
- const scissorsPattern = new RegExp(`^${commentChar} -+ >8 -+`, 'm');
188
- const scissorsMatch = result.match(scissorsPattern);
189
- if (scissorsMatch && scissorsMatch.index !== undefined) {
190
- result = result.slice(0, scissorsMatch.index);
191
- }
192
- }
193
- // Strip comments if cleanup is 'strip' or 'scissors'
194
- if (cleanup === 'strip' || cleanup === 'scissors') {
195
- const lines = result.split('\n');
196
- result = lines.filter(line => !line.startsWith(commentChar)).join('\n');
197
- }
198
- // Strip whitespace (for 'whitespace', 'strip', 'scissors', 'default')
199
- // Note: verbatim check already handled above, so this always runs
200
- if (true) {
201
- // Strip leading/trailing whitespace from each line
202
- const lines = result.split('\n');
203
- const trimmedLines = lines.map(line => line.trim());
204
- // Collapse multiple blank lines into one
205
- const collapsedLines = [];
206
- let lastWasBlank = false;
207
- for (const line of trimmedLines) {
208
- if (line === '') {
209
- if (!lastWasBlank) {
210
- collapsedLines.push(line);
211
- }
212
- lastWasBlank = true;
213
- }
214
- else {
215
- collapsedLines.push(line);
216
- lastWasBlank = false;
217
- }
218
- }
219
- result = collapsedLines.join('\n');
220
- // Trim leading/trailing blank lines
221
- result = result.replace(/^\n+/, '').replace(/\n+$/, '');
222
- }
223
- // Wrap body (not subject) if wrapColumn is specified
224
- if (wrapColumn > 0 && result.length > 0) {
225
- const lines = result.split('\n');
226
- if (lines.length > 0) {
227
- const subject = lines[0];
228
- const rest = lines.slice(1);
229
- // Find where body starts (after blank line)
230
- let bodyStartIndex = 0;
231
- for (let i = 0; i < rest.length; i++) {
232
- if (rest[i] === '') {
233
- bodyStartIndex = i + 1;
234
- break;
235
- }
236
- }
237
- // Wrap body lines
238
- const wrappedRest = [];
239
- for (let i = 0; i < rest.length; i++) {
240
- if (i >= bodyStartIndex && rest[i] !== '') {
241
- wrappedRest.push(wrapText(rest[i], wrapColumn));
242
- }
243
- else {
244
- wrappedRest.push(rest[i]);
245
- }
246
- }
247
- result = [subject, ...wrappedRest].join('\n');
248
- }
249
- }
250
- return result;
251
- }
252
- /**
253
- * Parses a commit message into subject and body.
254
- *
255
- * The subject is the first line. The body starts after the first
256
- * blank line following the subject.
257
- *
258
- * @param message - The commit message
259
- * @returns Object with subject (first line) and body (rest)
260
- *
261
- * @example
262
- * ```typescript
263
- * const { subject, body } = parseCommitMessage(
264
- * 'Add feature\n\nThis adds the new feature'
265
- * )
266
- * // subject = 'Add feature'
267
- * // body = 'This adds the new feature'
268
- * ```
269
- */
270
- export function parseCommitMessage(message) {
271
- if (!message) {
272
- return { subject: '', body: '' };
273
- }
274
- const lines = message.split('\n');
275
- const subject = lines[0] || '';
276
- // Find the body - it starts after the first blank line (or second line if no blank)
277
- let bodyStartIndex = 1;
278
- for (let i = 1; i < lines.length; i++) {
279
- if (lines[i] === '') {
280
- bodyStartIndex = i + 1;
281
- break;
282
- }
283
- }
284
- const body = lines.slice(bodyStartIndex).join('\n');
285
- return { subject, body };
286
- }
287
- /**
288
- * Validates a commit message format.
289
- *
290
- * Checks for common issues and provides warnings for style violations.
291
- * Returns errors for critical issues that would prevent commit creation.
292
- *
293
- * @param message - The commit message to validate
294
- * @returns Object with valid flag and any error/warning messages
295
- *
296
- * @example
297
- * ```typescript
298
- * const result = validateCommitMessage('Fix bug.')
299
- * // {
300
- * // valid: true,
301
- * // errors: [],
302
- * // warnings: ['Subject line should not end with a period']
303
- * // }
304
- * ```
305
- */
306
- export function validateCommitMessage(message) {
307
- const errors = [];
308
- const warnings = [];
309
- if (!message || message.trim() === '') {
310
- errors.push('Commit message is empty');
311
- return { valid: false, errors, warnings };
312
- }
313
- const { subject, body: _body } = parseCommitMessage(message);
314
- // Check subject line length (72 chars is conventional max)
315
- if (subject.length > 72) {
316
- warnings.push('Subject line exceeds 72 characters');
317
- }
318
- // Check if subject ends with a period
319
- if (subject.endsWith('.')) {
320
- warnings.push('Subject line should not end with a period');
321
- }
322
- // Check for missing blank line between subject and body
323
- const lines = message.split('\n');
324
- if (lines.length > 1 && lines[1] !== '') {
325
- warnings.push('Missing blank line between subject and body');
326
- }
327
- return { valid: errors.length === 0, errors, warnings };
328
- }
329
- // ============================================================================
330
- // GPG Signing
331
- // ============================================================================
332
- /**
333
- * Checks if a commit is signed.
334
- *
335
- * @param commit - The commit object
336
- * @returns true if the commit has a GPG signature
337
- *
338
- * @example
339
- * ```typescript
340
- * if (isCommitSigned(commit)) {
341
- * const sig = extractCommitSignature(commit)
342
- * // Verify signature...
343
- * }
344
- * ```
345
- */
346
- export function isCommitSigned(commit) {
347
- const signedCommit = commit;
348
- return signedCommit.gpgsig !== undefined && signedCommit.gpgsig !== null;
349
- }
350
- /**
351
- * Extracts the GPG signature from a signed commit.
352
- *
353
- * @param commit - The commit object
354
- * @returns The signature string if present, null otherwise
355
- */
356
- export function extractCommitSignature(commit) {
357
- const signedCommit = commit;
358
- return signedCommit.gpgsig ?? null;
359
- }
360
- /**
361
- * Adds a GPG signature to a commit.
362
- *
363
- * Creates a new commit object with the signature attached.
364
- * Does not modify the original commit object.
365
- *
366
- * @param commit - The unsigned commit object
367
- * @param signature - The GPG signature string
368
- * @returns The signed commit object
369
- */
370
- export function addSignatureToCommit(commit, signature) {
371
- const signedCommit = {
372
- ...commit,
373
- gpgsig: signature
374
- };
375
- return signedCommit;
376
- }
377
- // ============================================================================
378
- // Empty Commit Detection
379
- // ============================================================================
380
- /**
381
- * Extracts tree SHA from raw commit data.
382
- * @internal
383
- */
384
- function extractTreeFromCommitData(data) {
385
- const decoder = new TextDecoder();
386
- const content = decoder.decode(data);
387
- const match = content.match(/tree ([0-9a-f]{40})/);
388
- return match ? match[1] : null;
389
- }
390
- /**
391
- * Checks if a commit would be empty (same tree as parent).
392
- *
393
- * A commit is considered empty if its tree SHA is identical to
394
- * its parent's tree SHA, meaning no files were changed.
395
- *
396
- * @param store - The object store for reading objects
397
- * @param tree - The tree SHA for the new commit
398
- * @param parent - The parent commit SHA (or null for initial commit)
399
- * @returns true if the commit would have no changes
400
- *
401
- * @example
402
- * ```typescript
403
- * const isEmpty = await isEmptyCommit(store, newTreeSha, parentSha)
404
- * if (isEmpty && !options.allowEmpty) {
405
- * throw new Error('Nothing to commit')
406
- * }
407
- * ```
408
- */
409
- export async function isEmptyCommit(store, tree, parent) {
410
- // Initial commits are never "empty"
411
- if (parent === null) {
412
- return false;
413
- }
414
- const parentObj = await store.getObject(parent);
415
- if (!parentObj) {
416
- return false;
417
- }
418
- // Extract tree from parent commit
419
- const parentTree = extractTreeFromCommitData(parentObj.data);
420
- return parentTree === tree;
421
- }
422
- // ============================================================================
423
- // Validation Helpers
424
- // ============================================================================
425
- const SHA_REGEX = /^[0-9a-f]{40}$/;
426
- /**
427
- * Validates a SHA format.
428
- * @internal
429
- */
430
- function isValidSha(sha) {
431
- return SHA_REGEX.test(sha);
432
- }
433
- /**
434
- * Validates an email format.
435
- * @internal
436
- */
437
- function isValidEmail(email) {
438
- // Basic email validation - must contain @ and have something before and after
439
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
440
- }
441
- /**
442
- * Validates an author name.
443
- * @internal
444
- */
445
- function validateAuthorName(name) {
446
- if (name.includes('<') || name.includes('>')) {
447
- throw new Error('Author name cannot contain angle brackets');
448
- }
449
- if (name.includes('\n')) {
450
- throw new Error('Author name cannot contain newlines');
451
- }
452
- }
453
- /**
454
- * Validates commit options.
455
- * @internal
456
- */
457
- function validateCommitOptions(options) {
458
- // Validate tree
459
- if (!options.tree) {
460
- throw new Error('Tree SHA is required');
461
- }
462
- if (!isValidSha(options.tree)) {
463
- throw new Error('Invalid tree SHA format');
464
- }
465
- // Validate author
466
- if (!options.author) {
467
- throw new Error('Author is required');
468
- }
469
- validateAuthorName(options.author.name);
470
- if (!isValidEmail(options.author.email)) {
471
- throw new Error('Invalid author email format');
472
- }
473
- // Validate committer if provided
474
- if (options.committer) {
475
- validateAuthorName(options.committer.name);
476
- if (!isValidEmail(options.committer.email)) {
477
- throw new Error('Invalid committer email format');
478
- }
479
- }
480
- // Validate message
481
- if (!options.message || options.message.trim() === '') {
482
- throw new Error('Commit message is required');
483
- }
484
- // Validate parents
485
- if (options.parents) {
486
- for (const parent of options.parents) {
487
- if (!isValidSha(parent)) {
488
- throw new Error('Invalid parent SHA format');
489
- }
490
- }
491
- }
492
- // Validate timestamp if provided
493
- if (options.author.timestamp !== undefined && options.author.timestamp < 0) {
494
- throw new Error('Timestamp cannot be negative');
495
- }
496
- if (options.committer?.timestamp !== undefined && options.committer.timestamp < 0) {
497
- throw new Error('Timestamp cannot be negative');
498
- }
499
- }
500
- // ============================================================================
501
- // Commit Creation
502
- // ============================================================================
503
- /**
504
- * Resolves a CommitAuthor to a full Author with timestamp and timezone.
505
- * @internal
506
- */
507
- function resolveAuthor(commitAuthor) {
508
- return {
509
- name: commitAuthor.name,
510
- email: commitAuthor.email,
511
- timestamp: commitAuthor.timestamp ?? Math.floor(Date.now() / 1000),
512
- timezone: commitAuthor.timezone ?? getCurrentTimezone()
513
- };
514
- }
515
- /**
516
- * Serializes commit content to bytes (without the header).
517
- * @internal
518
- */
519
- function serializeCommitContent(commit) {
520
- const encoder = new TextEncoder();
521
- const lines = [];
522
- lines.push(`tree ${commit.tree}`);
523
- for (const parent of commit.parents) {
524
- lines.push(`parent ${parent}`);
525
- }
526
- lines.push(`author ${commit.author.name} <${commit.author.email}> ${commit.author.timestamp} ${commit.author.timezone}`);
527
- lines.push(`committer ${commit.committer.name} <${commit.committer.email}> ${commit.committer.timestamp} ${commit.committer.timezone}`);
528
- // Add gpgsig if present
529
- if (commit.gpgsig) {
530
- const sigLines = commit.gpgsig.split('\n');
531
- lines.push(`gpgsig ${sigLines[0]}`);
532
- for (let i = 1; i < sigLines.length; i++) {
533
- lines.push(` ${sigLines[i]}`);
534
- }
535
- }
536
- lines.push('');
537
- lines.push(commit.message);
538
- return encoder.encode(lines.join('\n'));
539
- }
540
- /**
541
- * Builds a commit object from options without storing it.
542
- *
543
- * Useful for creating commit objects for inspection or testing
544
- * without actually persisting them to the object store.
545
- *
546
- * @param options - Commit creation options
547
- * @returns The commit object (not stored)
548
- *
549
- * @example
550
- * ```typescript
551
- * const commit = buildCommitObject({
552
- * message: 'Test commit',
553
- * tree: treeSha,
554
- * parents: [parentSha],
555
- * author: { name: 'Test', email: 'test@example.com' }
556
- * })
557
- *
558
- * console.log(commit.message) // 'Test commit'
559
- * ```
560
- */
561
- export function buildCommitObject(options) {
562
- const author = resolveAuthor(options.author);
563
- const committer = options.committer ? resolveAuthor(options.committer) : author;
564
- const parents = options.parents ?? [];
565
- const commit = {
566
- type: 'commit',
567
- data: new Uint8Array(),
568
- tree: options.tree,
569
- parents,
570
- author,
571
- committer,
572
- message: options.message
573
- };
574
- // Set the data field
575
- commit.data = serializeCommitContent({
576
- tree: commit.tree,
577
- parents: commit.parents,
578
- author: commit.author,
579
- committer: commit.committer,
580
- message: commit.message
581
- });
582
- return commit;
583
- }
584
- /**
585
- * Creates a new commit.
586
- *
587
- * Creates a commit object with the specified options and stores it
588
- * in the object store. Handles validation, empty commit detection,
589
- * and optional GPG signing.
590
- *
591
- * @param store - The object store for reading/writing objects
592
- * @param options - Commit creation options
593
- * @returns The created commit result with SHA and commit object
594
- *
595
- * @throws {Error} If tree SHA is missing or invalid
596
- * @throws {Error} If author is missing or invalid
597
- * @throws {Error} If commit message is empty
598
- * @throws {Error} If commit would be empty and allowEmpty is false
599
- *
600
- * @example
601
- * ```typescript
602
- * // Basic commit
603
- * const result = await createCommit(store, {
604
- * message: 'Add new feature',
605
- * tree: treeSha,
606
- * parents: [headSha],
607
- * author: { name: 'John', email: 'john@example.com' }
608
- * })
609
- *
610
- * // Signed commit
611
- * const signedResult = await createCommit(store, {
612
- * message: 'Signed commit',
613
- * tree: treeSha,
614
- * parents: [headSha],
615
- * author: { name: 'John', email: 'john@example.com' },
616
- * signing: {
617
- * sign: true,
618
- * signer: async (data) => myGpgSign(data)
619
- * }
620
- * })
621
- *
622
- * // Initial commit (no parents)
623
- * const initialResult = await createCommit(store, {
624
- * message: 'Initial commit',
625
- * tree: treeSha,
626
- * parents: [],
627
- * author: { name: 'John', email: 'john@example.com' }
628
- * })
629
- * ```
630
- */
631
- export async function createCommit(store, options) {
632
- // Validate options
633
- validateCommitOptions(options);
634
- const parents = options.parents ?? [];
635
- // Check for empty commit
636
- if (options.allowEmpty === false && parents.length > 0) {
637
- const isEmpty = await isEmptyCommit(store, options.tree, parents[0]);
638
- if (isEmpty) {
639
- throw new Error('Nothing to commit (empty commit not allowed)');
640
- }
641
- }
642
- // Build the commit object
643
- let commit = buildCommitObject(options);
644
- // Sign if requested
645
- if (options.signing?.sign && options.signing.signer) {
646
- const commitData = serializeCommitContent({
647
- tree: commit.tree,
648
- parents: commit.parents,
649
- author: commit.author,
650
- committer: commit.committer,
651
- message: commit.message
652
- });
653
- const signature = await options.signing.signer(commitData);
654
- commit = addSignatureToCommit(commit, signature);
655
- // Update commit data with signature
656
- const signedCommit = commit;
657
- commit.data = serializeCommitContent({
658
- tree: commit.tree,
659
- parents: commit.parents,
660
- author: commit.author,
661
- committer: commit.committer,
662
- message: commit.message,
663
- gpgsig: signedCommit.gpgsig
664
- });
665
- }
666
- // Store the commit
667
- const sha = await store.storeObject('commit', commit.data);
668
- return {
669
- sha,
670
- commit,
671
- created: true
672
- };
673
- }
674
- // ============================================================================
675
- // Commit Amendment
676
- // ============================================================================
677
- /**
678
- * Parses a stored commit object from raw data.
679
- * Supports both git text format and JSON format (for testing).
680
- * @internal
681
- */
682
- function parseStoredCommit(data) {
683
- const decoder = new TextDecoder();
684
- const content = decoder.decode(data);
685
- // Try to parse as JSON first (for test compatibility)
686
- if (content.startsWith('{')) {
687
- try {
688
- const parsed = JSON.parse(content);
689
- return {
690
- tree: parsed.tree,
691
- parents: parsed.parents || [],
692
- author: parsed.author,
693
- committer: parsed.committer || parsed.author,
694
- message: parsed.message
695
- };
696
- }
697
- catch {
698
- // Not JSON, fall through to git format parsing
699
- }
700
- }
701
- // Parse git text format
702
- const lines = content.split('\n');
703
- let tree = '';
704
- const parents = [];
705
- let author = null;
706
- let committer = null;
707
- let messageStartIndex = 0;
708
- for (let i = 0; i < lines.length; i++) {
709
- const line = lines[i];
710
- if (line === '') {
711
- messageStartIndex = i + 1;
712
- break;
713
- }
714
- if (line.startsWith('tree ')) {
715
- tree = line.slice(5);
716
- }
717
- else if (line.startsWith('parent ')) {
718
- parents.push(line.slice(7));
719
- }
720
- else if (line.startsWith('author ')) {
721
- const match = line.match(/^author (.+) <(.+)> (\d+) ([+-]\d{4})$/);
722
- if (match) {
723
- author = {
724
- name: match[1],
725
- email: match[2],
726
- timestamp: parseInt(match[3], 10),
727
- timezone: match[4]
728
- };
729
- }
730
- }
731
- else if (line.startsWith('committer ')) {
732
- const match = line.match(/^committer (.+) <(.+)> (\d+) ([+-]\d{4})$/);
733
- if (match) {
734
- committer = {
735
- name: match[1],
736
- email: match[2],
737
- timestamp: parseInt(match[3], 10),
738
- timezone: match[4]
739
- };
740
- }
741
- }
742
- }
743
- const message = lines.slice(messageStartIndex).join('\n');
744
- if (!author) {
745
- author = { name: 'Unknown', email: 'unknown@example.com', timestamp: 0, timezone: '+0000' };
746
- }
747
- if (!committer) {
748
- committer = author;
749
- }
750
- return { tree, parents, author, committer, message };
751
- }
752
- /**
753
- * Amends an existing commit.
754
- *
755
- * Creates a new commit that replaces the specified commit.
756
- * The original commit is not modified. Only specified fields
757
- * in options will be changed from the original.
758
- *
759
- * Note: This does not update any refs. The caller is responsible
760
- * for updating HEAD or branch refs to point to the new commit.
761
- *
762
- * @param store - The object store for reading/writing objects
763
- * @param commitSha - SHA of the commit to amend
764
- * @param options - Amendment options (only specified fields are changed)
765
- * @returns The new commit result (original commit is not modified)
766
- *
767
- * @throws {Error} If the commit doesn't exist
768
- *
769
- * @example
770
- * ```typescript
771
- * // Change just the message
772
- * const newCommit = await amendCommit(store, headSha, {
773
- * message: 'Better commit message'
774
- * })
775
- *
776
- * // Update tree and committer
777
- * const newCommit = await amendCommit(store, headSha, {
778
- * tree: newTreeSha,
779
- * committer: { name: 'New Name', email: 'new@example.com' }
780
- * })
781
- * ```
782
- */
783
- export async function amendCommit(store, commitSha, options) {
784
- // Get the original commit
785
- const originalObj = await store.getObject(commitSha);
786
- if (!originalObj) {
787
- throw new Error(`Commit not found: ${commitSha}`);
788
- }
789
- // Parse the original commit
790
- const original = parseStoredCommit(originalObj.data);
791
- // Build new author
792
- let newAuthor = original.author;
793
- if (options.author) {
794
- newAuthor = resolveAuthor(options.author);
795
- }
796
- else if (options.resetAuthorDate) {
797
- newAuthor = {
798
- ...original.author,
799
- timestamp: Math.floor(Date.now() / 1000)
800
- };
801
- }
802
- // Build new committer (defaults to current time)
803
- let newCommitter;
804
- if (options.committer) {
805
- newCommitter = resolveAuthor(options.committer);
806
- }
807
- else {
808
- newCommitter = {
809
- ...original.committer,
810
- timestamp: Math.floor(Date.now() / 1000),
811
- timezone: getCurrentTimezone()
812
- };
813
- }
814
- // Build new commit
815
- const newCommitOptions = {
816
- message: options.message ?? original.message,
817
- tree: options.tree ?? original.tree,
818
- parents: original.parents,
819
- author: newAuthor,
820
- committer: newCommitter,
821
- signing: options.signing,
822
- allowEmpty: true
823
- };
824
- return createCommit(store, newCommitOptions);
825
- }
826
- //# sourceMappingURL=commit.js.map