git-remote-ops 0.1.0 → 0.2.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.
- package/AGENTS.md +33 -32
- package/README.md +80 -206
- package/dist/cli.js +215 -0
- package/dist/cli.js.map +1 -0
- package/{types → dist}/client.d.ts +11 -15
- package/dist/client.d.ts.map +1 -0
- package/{esm → dist}/client.js +107 -83
- package/dist/client.js.map +1 -0
- package/{types → dist}/errors.d.ts +30 -16
- package/dist/errors.d.ts.map +1 -0
- package/{esm → dist}/errors.js +17 -8
- package/dist/errors.js.map +1 -0
- package/{types → dist}/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/{esm → dist}/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/{types → dist}/logger.d.ts +11 -0
- package/dist/logger.d.ts.map +1 -0
- package/{esm → dist}/logger.js +3 -19
- package/dist/logger.js.map +1 -0
- package/{esm → dist}/objects/commit.js +1 -0
- package/dist/objects/commit.js.map +1 -0
- package/{esm → dist}/objects/index.js +1 -0
- package/dist/objects/index.js.map +1 -0
- package/{types → dist}/objects/tree.d.ts.map +1 -1
- package/{esm → dist}/objects/tree.js +2 -2
- package/dist/objects/tree.js.map +1 -0
- package/{esm → dist}/pack/delta.js +1 -0
- package/dist/pack/delta.js.map +1 -0
- package/{esm → dist}/pack/index.js +1 -0
- package/dist/pack/index.js.map +1 -0
- package/{types → dist}/pack/objects.d.ts.map +1 -1
- package/{esm → dist}/pack/objects.js +3 -3
- package/dist/pack/objects.js.map +1 -0
- package/{types → dist}/pack/parser.d.ts +19 -3
- package/dist/pack/parser.d.ts.map +1 -0
- package/{esm → dist}/pack/parser.js +46 -15
- package/dist/pack/parser.js.map +1 -0
- package/{esm → dist}/protocol/index.js +1 -0
- package/dist/protocol/index.js.map +1 -0
- package/{types → dist}/protocol/pkt_line.d.ts +3 -3
- package/{types → dist}/protocol/pkt_line.d.ts.map +1 -1
- package/{esm → dist}/protocol/pkt_line.js +1 -0
- package/dist/protocol/pkt_line.js.map +1 -0
- package/{esm → dist}/protocol/refs.js +1 -0
- package/dist/protocol/refs.js.map +1 -0
- package/{types → dist}/protocol/upload_pack.d.ts +1 -0
- package/{types → dist}/protocol/upload_pack.d.ts.map +1 -1
- package/{esm → dist}/protocol/upload_pack.js +10 -1
- package/dist/protocol/upload_pack.js.map +1 -0
- package/dist/store.d.ts +28 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +179 -0
- package/dist/store.js.map +1 -0
- package/{types → dist}/transport.d.ts +15 -2
- package/dist/transport.d.ts.map +1 -0
- package/{esm → dist}/transport.js +44 -15
- package/dist/transport.js.map +1 -0
- package/{types → dist}/types.d.ts +12 -7
- package/dist/types.d.ts.map +1 -0
- package/{esm → dist}/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -29
- package/esm/_dnt.shims.js +0 -72
- package/esm/cli.js +0 -217
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.js +0 -1
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_errors.js +0 -133
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_spread.js +0 -1
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.js +0 -1
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_utils.js +0 -141
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/command.js +0 -1861
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.js +0 -357
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/mod.js +0 -13
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/type.js +0 -27
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.js +0 -16
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.js +0 -13
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.js +0 -14
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/command.js +0 -9
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/enum.js +0 -24
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/file.js +0 -12
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/integer.js +0 -9
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/number.js +0 -9
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/secret.js +0 -7
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/string.js +0 -9
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types.js +0 -2
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.js +0 -26
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_errors.js +0 -129
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_utils.js +0 -100
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.js +0 -166
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/flags.js +0 -750
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/mod.js +0 -55
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.js +0 -11
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.js +0 -9
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/number.js +0 -11
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/string.js +0 -4
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types.js +0 -1
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.js +0 -16
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.js +0 -11
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.js +0 -25
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.js +0 -18
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.js +0 -11
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/_layout.js +0 -616
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/_utils.js +0 -79
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/border.js +0 -18
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/cell.js +0 -190
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/column.js +0 -117
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/consume_words.js +0 -64
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/mod.js +0 -42
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/row.js +0 -82
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/table.js +0 -341
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.js +0 -101
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.js +0 -2
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +0 -237
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +0 -2277
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +0 -46
- package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +0 -132
- package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.js +0 -270
- package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.js +0 -23
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +0 -61
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -51
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -13
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -2
- package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -87
- package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.js +0 -903
- package/esm/deps/jsr.io/@std/text/1.0.18/closest_string.js +0 -46
- package/esm/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.js +0 -127
- package/esm/package.json +0 -3
- package/types/_dnt.shims.d.ts +0 -16
- package/types/_dnt.shims.d.ts.map +0 -1
- package/types/client.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.d.ts +0 -163
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_errors.d.ts +0 -71
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_errors.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_spread.d.ts +0 -16
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_spread.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.d.ts +0 -15
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_utils.d.ts +0 -38
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_utils.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/command.d.ts +0 -1086
- package/types/deps/jsr.io/@cliffy/command/1.1.0/command.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.d.ts +0 -33
- package/types/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/mod.d.ts +0 -78
- package/types/deps/jsr.io/@cliffy/command/1.1.0/mod.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/type.d.ts +0 -51
- package/types/deps/jsr.io/@cliffy/command/1.1.0/type.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.d.ts +0 -10
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.d.ts +0 -10
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.d.ts +0 -10
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/command.d.ts +0 -8
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/command.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/enum.d.ts +0 -11
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/enum.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/file.d.ts +0 -6
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/file.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/integer.d.ts +0 -8
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/integer.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/number.d.ts +0 -8
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/number.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/secret.d.ts +0 -6
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/secret.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/string.d.ts +0 -8
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/string.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types.d.ts +0 -161
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.d.ts +0 -4
- package/types/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_errors.d.ts +0 -67
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_errors.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_utils.d.ts +0 -17
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_utils.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.d.ts +0 -11
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/flags.d.ts +0 -154
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/flags.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/mod.d.ts +0 -57
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/mod.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.d.ts +0 -4
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.d.ts +0 -4
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/number.d.ts +0 -4
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/number.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/string.d.ts +0 -4
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/string.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types.d.ts +0 -170
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.d.ts +0 -8
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.d.ts +0 -7
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.d.ts +0 -7
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.d.ts +0 -8
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.d.ts +0 -7
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_layout.d.ts +0 -108
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_layout.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_utils.d.ts +0 -26
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_utils.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/border.d.ts +0 -21
- package/types/deps/jsr.io/@cliffy/table/1.1.0/border.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/cell.d.ts +0 -155
- package/types/deps/jsr.io/@cliffy/table/1.1.0/cell.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/column.d.ts +0 -97
- package/types/deps/jsr.io/@cliffy/table/1.1.0/column.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/consume_words.d.ts +0 -30
- package/types/deps/jsr.io/@cliffy/table/1.1.0/consume_words.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/mod.d.ts +0 -43
- package/types/deps/jsr.io/@cliffy/table/1.1.0/mod.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/row.d.ts +0 -67
- package/types/deps/jsr.io/@cliffy/table/1.1.0/row.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/table.d.ts +0 -235
- package/types/deps/jsr.io/@cliffy/table/1.1.0/table.d.ts.map +0 -1
- package/types/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.d.ts +0 -40
- package/types/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +0 -9
- package/types/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +0 -2
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +0 -69
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +0 -13
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +0 -76
- package/types/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +0 -149
- package/types/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +0 -22
- package/types/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +0 -40
- package/types/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
- package/types/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
- package/types/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts +0 -700
- package/types/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/text/1.0.18/closest_string.d.ts +0 -42
- package/types/deps/jsr.io/@std/text/1.0.18/closest_string.d.ts.map +0 -1
- package/types/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.d.ts +0 -23
- package/types/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.d.ts.map +0 -1
- package/types/errors.d.ts.map +0 -1
- package/types/index.d.ts.map +0 -1
- package/types/logger.d.ts.map +0 -1
- package/types/pack/parser.d.ts.map +0 -1
- package/types/transport.d.ts.map +0 -1
- package/types/types.d.ts.map +0 -1
- /package/{types → dist}/cli.d.ts +0 -0
- /package/{types → dist}/cli.d.ts.map +0 -0
- /package/{types → dist}/objects/commit.d.ts +0 -0
- /package/{types → dist}/objects/commit.d.ts.map +0 -0
- /package/{types → dist}/objects/index.d.ts +0 -0
- /package/{types → dist}/objects/index.d.ts.map +0 -0
- /package/{types → dist}/objects/tree.d.ts +0 -0
- /package/{types → dist}/pack/delta.d.ts +0 -0
- /package/{types → dist}/pack/delta.d.ts.map +0 -0
- /package/{types → dist}/pack/index.d.ts +0 -0
- /package/{types → dist}/pack/index.d.ts.map +0 -0
- /package/{types → dist}/pack/objects.d.ts +0 -0
- /package/{types → dist}/protocol/index.d.ts +0 -0
- /package/{types → dist}/protocol/index.d.ts.map +0 -0
- /package/{types → dist}/protocol/refs.d.ts +0 -0
- /package/{types → dist}/protocol/refs.d.ts.map +0 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @module cli
|
|
4
|
+
*
|
|
5
|
+
* Commander-driven command-line front-end. Each subcommand wires the global
|
|
6
|
+
* verbosity / stats flags into a freshly built {@link RemoteGit}, executes
|
|
7
|
+
* one operation, and prints a plain-text result to stdout. Errors come back
|
|
8
|
+
* through {@link unwrap} as `[Tag] message` lines on stderr with exit 1.
|
|
9
|
+
*
|
|
10
|
+
* Subcommands:
|
|
11
|
+
* - `probe` — capability + filter probe
|
|
12
|
+
* - `ls-refs` — list advertised refs
|
|
13
|
+
* - `cat-commit` — fetch one commit
|
|
14
|
+
* - `cat-tree` — fetch a commit's root tree (or a tree by sha)
|
|
15
|
+
* - `list-files` — walk a snapshot and emit every file path
|
|
16
|
+
* - `cat-blob` — pipe one blob's raw bytes to stdout
|
|
17
|
+
*/
|
|
18
|
+
import { Command, InvalidArgumentError } from "commander";
|
|
19
|
+
import { Logger, RemoteGit } from "./index.js";
|
|
20
|
+
import { parseTree } from "./objects/index.js";
|
|
21
|
+
/** Bumped in lockstep with `package.json`. Surfaced by `git-remote-ops --version`. */
|
|
22
|
+
const VERSION = "0.2.0";
|
|
23
|
+
/** Octal mode of a subtree entry — used to recurse during `list-files`. */
|
|
24
|
+
const TREE_MODE = "40000";
|
|
25
|
+
function resolveLevel(flags) {
|
|
26
|
+
if (flags.quiet)
|
|
27
|
+
return "silent";
|
|
28
|
+
if (flags.debug)
|
|
29
|
+
return "trace";
|
|
30
|
+
if (flags.verbose)
|
|
31
|
+
return "debug";
|
|
32
|
+
return "info";
|
|
33
|
+
}
|
|
34
|
+
function makeClient(url, flags) {
|
|
35
|
+
const logger = new Logger({
|
|
36
|
+
level: resolveLevel(flags),
|
|
37
|
+
sink: (line) => console.error(line),
|
|
38
|
+
}, "client");
|
|
39
|
+
const client = new RemoteGit(url, { logger, storeDir: flags.storeDir });
|
|
40
|
+
return { client, logger };
|
|
41
|
+
}
|
|
42
|
+
function unwrap(result) {
|
|
43
|
+
if (result.isErr()) {
|
|
44
|
+
console.error(`[${result.error._tag}] ${result.error.message}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
return result.value;
|
|
48
|
+
}
|
|
49
|
+
function maybeStats(logger, flags) {
|
|
50
|
+
if (flags.stats)
|
|
51
|
+
console.error(logger.summary());
|
|
52
|
+
}
|
|
53
|
+
async function cachedTreeEntries(client, treeSha) {
|
|
54
|
+
const object = await client.getObject(treeSha);
|
|
55
|
+
if (!object) {
|
|
56
|
+
console.error(`[ObjectNotFoundError] tree not present in fetched pack: ${treeSha}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (object.type !== "tree") {
|
|
60
|
+
console.error(`[ObjectDecodeError] object is not a tree: ${treeSha}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
const entries = parseTree(object.content);
|
|
64
|
+
if (entries.isErr()) {
|
|
65
|
+
console.error(`[${entries.error._tag}] ${entries.error.message}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
return entries.value;
|
|
69
|
+
}
|
|
70
|
+
async function printCachedFiles(client, entries, prefix, details) {
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
const path = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
73
|
+
if (entry.mode === TREE_MODE) {
|
|
74
|
+
await printCachedFiles(client, await cachedTreeEntries(client, entry.sha), path, details);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.log(details ? `${entry.mode} ${entry.sha} ${path}` : path);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function parseDepth(value) {
|
|
82
|
+
const depth = Number(value);
|
|
83
|
+
if (!Number.isInteger(depth) || depth < 1) {
|
|
84
|
+
throw new InvalidArgumentError("--depth must be >= 1");
|
|
85
|
+
}
|
|
86
|
+
return depth;
|
|
87
|
+
}
|
|
88
|
+
function globalFlags() {
|
|
89
|
+
return program.opts();
|
|
90
|
+
}
|
|
91
|
+
const program = new Command()
|
|
92
|
+
.name("git-remote-ops")
|
|
93
|
+
.version(VERSION)
|
|
94
|
+
.description("Read-only Git remote operations over smart HTTP.")
|
|
95
|
+
.showHelpAfterError()
|
|
96
|
+
.option("-q, --quiet", "Suppress all log output (silent level).")
|
|
97
|
+
.option("-v, --verbose", "Enable debug-level logs to stderr.")
|
|
98
|
+
.option("--debug", "Enable trace-level logs to stderr (very chatty).")
|
|
99
|
+
.requiredOption("--store-dir <path>", "Directory for reusable loose-object cache.")
|
|
100
|
+
.option("--stats", "Print performance/analytics summary on stderr after completion.")
|
|
101
|
+
.hook("preAction", (thisCommand) => {
|
|
102
|
+
const flags = thisCommand.optsWithGlobals();
|
|
103
|
+
if (flags.quiet && (flags.verbose || flags.debug)) {
|
|
104
|
+
thisCommand.error("error: option '-q, --quiet' cannot be used with '-v, --verbose' or '--debug'");
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
program
|
|
108
|
+
.command("probe")
|
|
109
|
+
.description("Probe server capabilities (protocol, filter, shallow).")
|
|
110
|
+
.argument("<url>")
|
|
111
|
+
.action(async (url, command) => {
|
|
112
|
+
const flags = globalFlags();
|
|
113
|
+
const { client, logger } = makeClient(url, flags);
|
|
114
|
+
const profile = unwrap(await client.probe(true));
|
|
115
|
+
console.log(`refs=${profile.refs.size}`);
|
|
116
|
+
console.log(`protocol=${profile.protocolVersion}`);
|
|
117
|
+
console.log(`filter_blob_none=${profile.supportsFilterBlobNone}`);
|
|
118
|
+
console.log(`filter_tree_0=${profile.supportsFilterTree0}`);
|
|
119
|
+
console.log(`shallow=${profile.supportsShallow}`);
|
|
120
|
+
maybeStats(logger, flags);
|
|
121
|
+
});
|
|
122
|
+
program
|
|
123
|
+
.command("ls-refs")
|
|
124
|
+
.description("List remote refs as '<sha> <name>' per line.")
|
|
125
|
+
.argument("<url>")
|
|
126
|
+
.action(async (url, command) => {
|
|
127
|
+
const flags = globalFlags();
|
|
128
|
+
const { client, logger } = makeClient(url, flags);
|
|
129
|
+
for (const [name, sha] of unwrap(await client.lsRefs())) {
|
|
130
|
+
console.log(`${sha} ${name}`);
|
|
131
|
+
}
|
|
132
|
+
maybeStats(logger, flags);
|
|
133
|
+
});
|
|
134
|
+
program
|
|
135
|
+
.command("cat-commit")
|
|
136
|
+
.description("Fetch & print a commit object.")
|
|
137
|
+
.argument("<url>")
|
|
138
|
+
.option("--ref <ref>", "Ref or sha to resolve.", "HEAD")
|
|
139
|
+
.option("--depth <n>", "Shallow depth (ignored if server lacks shallow).", parseDepth, 1)
|
|
140
|
+
.option("--filter <spec>", "Object filter spec (e.g. blob:none, tree:0).", "blob:none")
|
|
141
|
+
.option("--no-filter", "Fetch without object filter; may download a full snapshot pack.")
|
|
142
|
+
.action(async (url, options) => {
|
|
143
|
+
const flags = globalFlags();
|
|
144
|
+
const { client, logger } = makeClient(url, flags);
|
|
145
|
+
const filter = options.filter === false ? undefined : options.filter;
|
|
146
|
+
const { sha, commit } = unwrap(await client.fetchCommit(options.ref, { depth: options.depth, filter }));
|
|
147
|
+
console.log(`commit ${sha}`);
|
|
148
|
+
console.log(`tree ${commit.tree}`);
|
|
149
|
+
if (commit.parent)
|
|
150
|
+
console.log(`parent ${commit.parent}`);
|
|
151
|
+
if (commit.author)
|
|
152
|
+
console.log(`author ${commit.author}`);
|
|
153
|
+
if (commit.committer)
|
|
154
|
+
console.log(`committer ${commit.committer}`);
|
|
155
|
+
maybeStats(logger, flags);
|
|
156
|
+
});
|
|
157
|
+
program
|
|
158
|
+
.command("cat-tree")
|
|
159
|
+
.description("Fetch a commit snapshot and print its root tree as '<mode> <sha> <name>' per entry.")
|
|
160
|
+
.argument("<url>")
|
|
161
|
+
.option("--ref <ref>", "Ref or commit sha to resolve.", "HEAD")
|
|
162
|
+
.option("--depth <n>", "Shallow depth (ignored if server lacks shallow).", parseDepth, 1)
|
|
163
|
+
.option("--filter <spec>", "Object filter spec (e.g. blob:none, tree:0).", "blob:none")
|
|
164
|
+
.option("--no-filter", "Fetch without object filter; downloads a full snapshot pack.")
|
|
165
|
+
.option("--tree-sha <sha>", "Fetch the tree by SHA directly (no commit snapshot).")
|
|
166
|
+
.action(async (url, options) => {
|
|
167
|
+
const flags = globalFlags();
|
|
168
|
+
const { client, logger } = makeClient(url, flags);
|
|
169
|
+
if (options.treeSha) {
|
|
170
|
+
for (const entry of unwrap(await client.fetchTree(options.treeSha))) {
|
|
171
|
+
console.log(`${entry.mode} ${entry.sha} ${entry.name}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const filter = options.filter === false ? undefined : options.filter;
|
|
176
|
+
const result = unwrap(await client.fetchTreeForCommit(options.ref, { depth: options.depth, filter }));
|
|
177
|
+
for (const entry of result.entries) {
|
|
178
|
+
console.log(`${entry.mode} ${entry.sha} ${entry.name}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
maybeStats(logger, flags);
|
|
182
|
+
});
|
|
183
|
+
program
|
|
184
|
+
.command("list-files")
|
|
185
|
+
.description("List all files in a commit snapshot without cloning.")
|
|
186
|
+
.argument("<url>")
|
|
187
|
+
.option("--ref <ref>", "Ref or commit sha to resolve.", "HEAD")
|
|
188
|
+
.option("--depth <n>", "Shallow depth (ignored if server lacks shallow).", parseDepth, 1)
|
|
189
|
+
.option("--filter <spec>", "Object filter spec (e.g. blob:none, tree:0).", "blob:none")
|
|
190
|
+
.option("--no-filter", "Fetch without object filter; downloads a full snapshot pack.")
|
|
191
|
+
.option("--details", "Print '<mode> <sha> <path>' instead of path only.")
|
|
192
|
+
.action(async (url, options) => {
|
|
193
|
+
const flags = globalFlags();
|
|
194
|
+
const { client, logger } = makeClient(url, flags);
|
|
195
|
+
const filter = options.filter === false ? undefined : options.filter;
|
|
196
|
+
const result = unwrap(await client.fetchTreeForCommit(options.ref, {
|
|
197
|
+
depth: options.depth,
|
|
198
|
+
filter,
|
|
199
|
+
}));
|
|
200
|
+
await printCachedFiles(client, result.entries, "", !!options.details);
|
|
201
|
+
maybeStats(logger, flags);
|
|
202
|
+
});
|
|
203
|
+
program
|
|
204
|
+
.command("cat-blob")
|
|
205
|
+
.description("Fetch a blob and write raw bytes to stdout.")
|
|
206
|
+
.argument("<url>")
|
|
207
|
+
.argument("<blob-sha>")
|
|
208
|
+
.action(async (url, sha, command) => {
|
|
209
|
+
const flags = globalFlags();
|
|
210
|
+
const { client, logger } = makeClient(url, flags);
|
|
211
|
+
process.stdout.write(unwrap(await client.fetchBlob(sha)));
|
|
212
|
+
maybeStats(logger, flags);
|
|
213
|
+
});
|
|
214
|
+
await program.parseAsync(process.argv);
|
|
215
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,11 +5,8 @@
|
|
|
5
5
|
* transport, protocol, and pack layers behind a small surface: discover a
|
|
6
6
|
* server, ask for commits/trees/blobs, get them back as decoded objects.
|
|
7
7
|
*
|
|
8
|
-
* The client caches
|
|
9
|
-
*
|
|
10
|
-
* - every object materialized by any prior fetch, in a process-lifetime
|
|
11
|
-
* map. Subsequent fetches dedupe wants against this map so multi-step
|
|
12
|
-
* workflows (commit → tree → blob) only pay for what's new.
|
|
8
|
+
* The client caches a single {@link ServerProfile}; objects are stored in the
|
|
9
|
+
* caller-supplied loose-object directory and deduped across calls by SHA.
|
|
13
10
|
*/
|
|
14
11
|
import { Result } from "better-result";
|
|
15
12
|
import type { GitRemoteOpsError } from "./errors.js";
|
|
@@ -26,19 +23,17 @@ export declare class RemoteGit {
|
|
|
26
23
|
readonly url: string;
|
|
27
24
|
readonly logger: Logger;
|
|
28
25
|
private profile;
|
|
29
|
-
private
|
|
30
|
-
private snapshotCommits;
|
|
26
|
+
private store;
|
|
31
27
|
private diagnostic?;
|
|
32
28
|
private transportLogger;
|
|
33
29
|
private packLogger;
|
|
34
30
|
/**
|
|
35
31
|
* @param url Base repository URL (e.g. `https://github.com/owner/repo.git`).
|
|
36
32
|
* Trailing slashes are stripped.
|
|
37
|
-
* @param options
|
|
38
|
-
* silent logger is used. Passing `diagnostic` alone gets you a `debug`
|
|
39
|
-
* logger routed to the diagnostic function.
|
|
33
|
+
* @param options Required object store directory plus optional logger / diagnostic sink. When no
|
|
34
|
+
* logger is given, a silent logger is used. Passing `diagnostic` alone gets you a `debug` logger.
|
|
40
35
|
*/
|
|
41
|
-
constructor(url: string, options
|
|
36
|
+
constructor(url: string, options: RemoteGitOptions);
|
|
42
37
|
/**
|
|
43
38
|
* Fetch and cache the server's ref/capability advertisement.
|
|
44
39
|
*
|
|
@@ -85,9 +80,8 @@ export declare class RemoteGit {
|
|
|
85
80
|
/**
|
|
86
81
|
* Fetch the commit at `ref` *and* its root tree from a single snapshot pack.
|
|
87
82
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* for "list files at HEAD" without a clone.
|
|
83
|
+
* Uses tree retention so the tree object — which the commit references but
|
|
84
|
+
* doesn't `want` directly — ends up in the local object store without blobs.
|
|
91
85
|
*/
|
|
92
86
|
fetchTreeForCommit(ref: string, options?: FetchCommitOptions): Promise<Result<{
|
|
93
87
|
commit: CommitInfo;
|
|
@@ -97,8 +91,10 @@ export declare class RemoteGit {
|
|
|
97
91
|
/** Fetch and decode a single tree by sha. */
|
|
98
92
|
fetchTree(sha: string): Promise<Result<TreeEntry[], GitRemoteOpsError>>;
|
|
99
93
|
/** Look up an already-materialized object by sha. Does not fetch on miss. */
|
|
100
|
-
getObject(sha: string): GitObject | undefined
|
|
94
|
+
getObject(sha: string): Promise<GitObject | undefined>;
|
|
95
|
+
private requiredObject;
|
|
101
96
|
private fetchObjects;
|
|
97
|
+
private parsePackFile;
|
|
102
98
|
private probeFilter;
|
|
103
99
|
private fetchPack;
|
|
104
100
|
private normalizeWants;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EAClB,SAAS,EAGT,gBAAgB,EAChB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AA8CpB;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,UAAU,CAAC,CAAe;IAClC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;;OAKG;gBACS,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB;IAalD;;;;;;;OAOG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAoCnE;;;;;;;;;OASG;IACG,KAAK,CAAC,OAAO,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAkB/E,8FAA8F;IACxF,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAMvE;;;;;;OAMG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAezE;;;;;;OAMG;IACG,WAAW,CACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,iBAAiB,CAAC,CAAC;IAwC1E,uDAAuD;IACjD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IAoB5E;;;;;OAKG;IACG,kBAAkB,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CACR,MAAM,CAAC;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,EAAE,CAAA;KAAE,EAAE,iBAAiB,CAAC,CAC3F;IAwBD,6CAA6C;IACvC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,iBAAiB,CAAC,CAAC;IAsB7E,6EAA6E;IACvE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YAK9C,cAAc;YAMd,YAAY;YAkDZ,aAAa;YAqBb,WAAW;YAoCX,SAAS;YAoCT,cAAc;IAa5B,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,GAAG;CAGZ"}
|
package/{esm → dist}/client.js
RENAMED
|
@@ -5,18 +5,17 @@
|
|
|
5
5
|
* transport, protocol, and pack layers behind a small surface: discover a
|
|
6
6
|
* server, ask for commits/trees/blobs, get them back as decoded objects.
|
|
7
7
|
*
|
|
8
|
-
* The client caches
|
|
9
|
-
*
|
|
10
|
-
* - every object materialized by any prior fetch, in a process-lifetime
|
|
11
|
-
* map. Subsequent fetches dedupe wants against this map so multi-step
|
|
12
|
-
* workflows (commit → tree → blob) only pay for what's new.
|
|
8
|
+
* The client caches a single {@link ServerProfile}; objects are stored in the
|
|
9
|
+
* caller-supplied loose-object directory and deduped across calls by SHA.
|
|
13
10
|
*/
|
|
14
11
|
import { Result } from "better-result";
|
|
15
|
-
import {
|
|
12
|
+
import { readFile, rm } from "node:fs/promises";
|
|
13
|
+
import { ObjectDecodeError, ObjectNotFoundError, PackParseError, RefNotFoundError, } from "./errors.js";
|
|
16
14
|
import { Logger } from "./logger.js";
|
|
17
15
|
import { parseCommit, parseTree } from "./objects/index.js";
|
|
18
16
|
import { parsePackfile } from "./pack/index.js";
|
|
19
|
-
import { buildFetchRequest,
|
|
17
|
+
import { buildFetchRequest, extractPackToFile, parseRefAdvertisement, parseV2CapabilityAdvertisement, } from "./protocol/index.js";
|
|
18
|
+
import { LooseObjectStore } from "./store.js";
|
|
20
19
|
import { getSmartHttp, postUploadPack } from "./transport.js";
|
|
21
20
|
/**
|
|
22
21
|
* Capabilities offered on every v0 fetch unless overridden. `shallow` and
|
|
@@ -33,8 +32,9 @@ const DEFAULT_CAPS = [
|
|
|
33
32
|
"multi_ack",
|
|
34
33
|
"side-band-64k",
|
|
35
34
|
"ofs-delta",
|
|
36
|
-
"agent=git-remote-ops
|
|
35
|
+
"agent=git-remote-ops/0.1",
|
|
37
36
|
];
|
|
37
|
+
const TREE_RETAIN_TYPES = new Set(["commit", "tree"]);
|
|
38
38
|
function fail(error) {
|
|
39
39
|
return Result.err(error);
|
|
40
40
|
}
|
|
@@ -56,25 +56,24 @@ export class RemoteGit {
|
|
|
56
56
|
url;
|
|
57
57
|
logger;
|
|
58
58
|
profile = null;
|
|
59
|
-
|
|
60
|
-
snapshotCommits = new Set();
|
|
59
|
+
store;
|
|
61
60
|
diagnostic;
|
|
62
61
|
transportLogger;
|
|
63
62
|
packLogger;
|
|
64
63
|
/**
|
|
65
64
|
* @param url Base repository URL (e.g. `https://github.com/owner/repo.git`).
|
|
66
65
|
* Trailing slashes are stripped.
|
|
67
|
-
* @param options
|
|
68
|
-
* silent logger is used. Passing `diagnostic` alone gets you a `debug`
|
|
69
|
-
* logger routed to the diagnostic function.
|
|
66
|
+
* @param options Required object store directory plus optional logger / diagnostic sink. When no
|
|
67
|
+
* logger is given, a silent logger is used. Passing `diagnostic` alone gets you a `debug` logger.
|
|
70
68
|
*/
|
|
71
69
|
constructor(url, options) {
|
|
72
70
|
this.url = url.replace(/\/+$/, "");
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
71
|
+
this.store = new LooseObjectStore(options.storeDir);
|
|
72
|
+
this.diagnostic = options.diagnostic;
|
|
73
|
+
this.logger = options.logger ??
|
|
75
74
|
new Logger({
|
|
76
|
-
level: options
|
|
77
|
-
sink: options
|
|
75
|
+
level: options.diagnostic ? "debug" : "silent",
|
|
76
|
+
sink: options.diagnostic,
|
|
78
77
|
}, "client");
|
|
79
78
|
this.transportLogger = this.logger.child("transport");
|
|
80
79
|
this.packLogger = this.logger.child("pack");
|
|
@@ -204,10 +203,10 @@ export class RemoteGit {
|
|
|
204
203
|
if (options.filter !== undefined && filter === undefined) {
|
|
205
204
|
this.logger.info(`server does not advertise object filters; fetching without ${options.filter}`);
|
|
206
205
|
}
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
return fail(
|
|
210
|
-
const object = requiredObject(
|
|
206
|
+
const fetched = await this.fetchObjects([commitSha.value], depth, filter, options.parseScope ?? "target");
|
|
207
|
+
if (fetched.isErr())
|
|
208
|
+
return fail(fetched.error);
|
|
209
|
+
const object = await this.requiredObject(commitSha.value);
|
|
211
210
|
if (object.isErr())
|
|
212
211
|
return fail(object.error);
|
|
213
212
|
if (object.value.type !== "commit") {
|
|
@@ -228,10 +227,10 @@ export class RemoteGit {
|
|
|
228
227
|
const profile = this.profile ? Result.ok(this.profile) : await this.discover();
|
|
229
228
|
if (profile.isErr())
|
|
230
229
|
return fail(profile.error);
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
return fail(
|
|
234
|
-
const object = requiredObject(
|
|
230
|
+
const fetched = await this.fetchObjects([sha]);
|
|
231
|
+
if (fetched.isErr())
|
|
232
|
+
return fail(fetched.error);
|
|
233
|
+
const object = await this.requiredObject(sha);
|
|
235
234
|
if (object.isErr())
|
|
236
235
|
return fail(object.error);
|
|
237
236
|
if (object.value.type !== "blob") {
|
|
@@ -247,30 +246,25 @@ export class RemoteGit {
|
|
|
247
246
|
/**
|
|
248
247
|
* Fetch the commit at `ref` *and* its root tree from a single snapshot pack.
|
|
249
248
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* for "list files at HEAD" without a clone.
|
|
249
|
+
* Uses tree retention so the tree object — which the commit references but
|
|
250
|
+
* doesn't `want` directly — ends up in the local object store without blobs.
|
|
253
251
|
*/
|
|
254
252
|
async fetchTreeForCommit(ref, options = {}) {
|
|
255
|
-
const commit = await this.fetchCommit(ref, { ...options,
|
|
253
|
+
const commit = await this.fetchCommit(ref, { ...options, parseScope: "trees" });
|
|
256
254
|
if (commit.isErr())
|
|
257
255
|
return fail(commit.error);
|
|
258
|
-
const treeObject = this.
|
|
259
|
-
if (
|
|
260
|
-
return fail(
|
|
261
|
-
|
|
262
|
-
message: `tree ${commit.value.commit.tree} not present in snapshot pack`,
|
|
263
|
-
}));
|
|
264
|
-
}
|
|
265
|
-
if (treeObject.type !== "tree") {
|
|
256
|
+
const treeObject = await this.requiredObject(commit.value.commit.tree);
|
|
257
|
+
if (treeObject.isErr())
|
|
258
|
+
return fail(treeObject.error);
|
|
259
|
+
if (treeObject.value.type !== "tree") {
|
|
266
260
|
return fail(new ObjectDecodeError({
|
|
267
261
|
reason: "unexpected-object-type",
|
|
268
262
|
message: `object is not a tree: ${commit.value.commit.tree}`,
|
|
269
|
-
objectType: treeObject.type,
|
|
263
|
+
objectType: treeObject.value.type,
|
|
270
264
|
sha: commit.value.commit.tree,
|
|
271
265
|
}));
|
|
272
266
|
}
|
|
273
|
-
const entries = parseTree(treeObject.content);
|
|
267
|
+
const entries = parseTree(treeObject.value.content);
|
|
274
268
|
if (entries.isErr())
|
|
275
269
|
return fail(entries.error);
|
|
276
270
|
return Result.ok({
|
|
@@ -284,10 +278,10 @@ export class RemoteGit {
|
|
|
284
278
|
const profile = this.profile ? Result.ok(this.profile) : await this.discover();
|
|
285
279
|
if (profile.isErr())
|
|
286
280
|
return fail(profile.error);
|
|
287
|
-
const
|
|
288
|
-
if (
|
|
289
|
-
return fail(
|
|
290
|
-
const object = requiredObject(
|
|
281
|
+
const fetched = await this.fetchObjects([sha]);
|
|
282
|
+
if (fetched.isErr())
|
|
283
|
+
return fail(fetched.error);
|
|
284
|
+
const object = await this.requiredObject(sha);
|
|
291
285
|
if (object.isErr())
|
|
292
286
|
return fail(object.error);
|
|
293
287
|
if (object.value.type !== "tree") {
|
|
@@ -304,39 +298,71 @@ export class RemoteGit {
|
|
|
304
298
|
return Result.ok(tree.value);
|
|
305
299
|
}
|
|
306
300
|
/** Look up an already-materialized object by sha. Does not fetch on miss. */
|
|
307
|
-
getObject(sha) {
|
|
308
|
-
|
|
301
|
+
async getObject(sha) {
|
|
302
|
+
const object = await this.store.read(sha);
|
|
303
|
+
return object.isOk() ? object.value : undefined;
|
|
309
304
|
}
|
|
310
|
-
async
|
|
311
|
-
const
|
|
312
|
-
if (
|
|
313
|
-
return
|
|
314
|
-
|
|
305
|
+
async requiredObject(sha) {
|
|
306
|
+
const object = await this.store.read(sha);
|
|
307
|
+
if (object.isErr())
|
|
308
|
+
return fail(object.error);
|
|
309
|
+
return object;
|
|
310
|
+
}
|
|
311
|
+
async fetchObjects(wants, depth, filterSpec, parseScope = "target") {
|
|
312
|
+
const normalized = await this.normalizeWants(wants, depth, filterSpec);
|
|
313
|
+
if (normalized.length === 0)
|
|
314
|
+
return Result.ok(0);
|
|
315
315
|
this.logger.debug(`fetchObjects wants=${normalized.length} depth=${depth ?? "-"} filter=${filterSpec ?? "-"}`);
|
|
316
316
|
const pack = await this.fetchPack(normalized, depth, filterSpec);
|
|
317
317
|
if (pack.isErr())
|
|
318
318
|
return fail(pack.error);
|
|
319
319
|
const parseStart = performance.now();
|
|
320
|
-
const targets =
|
|
321
|
-
|
|
320
|
+
const targets = parseScope === "target" && normalized.length === 1
|
|
321
|
+
? new Set(normalized)
|
|
322
|
+
: undefined;
|
|
323
|
+
const retainTypes = parseScope === "trees" ? TREE_RETAIN_TYPES : undefined;
|
|
324
|
+
const parsed = await this.parsePackFile(pack.value, { targets, retainTypes }, (sha, object) => {
|
|
325
|
+
const written = this.store.writeSync(object.type, object.content);
|
|
326
|
+
if (written.isErr()) {
|
|
327
|
+
return Result.err(new PackParseError({
|
|
328
|
+
reason: "store-write-failed",
|
|
329
|
+
message: `failed to write object ${sha}`,
|
|
330
|
+
cause: written.error,
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
return Result.ok(undefined);
|
|
334
|
+
});
|
|
322
335
|
const parseMs = performance.now() - parseStart;
|
|
323
336
|
if (parsed.isErr())
|
|
324
337
|
return fail(parsed.error);
|
|
325
|
-
const counts =
|
|
338
|
+
const counts = parsed.value.stats.byType;
|
|
326
339
|
this.packLogger.recordPack({
|
|
327
340
|
bytes: pack.value.length,
|
|
328
341
|
durationMs: parseMs,
|
|
329
342
|
byType: counts,
|
|
330
343
|
});
|
|
331
|
-
this.packLogger.debug(`parsed ${parsed.value.
|
|
332
|
-
for (const [sha, object] of parsed.value) {
|
|
333
|
-
this.objects.set(sha, object);
|
|
334
|
-
}
|
|
344
|
+
this.packLogger.debug(`parsed ${parsed.value.stats.materialized} objects, retained ${parsed.value.stats.retained} (${counts.commit}c/${counts.tree}t/${counts.blob}b/${counts.tag}T) in ${parseMs.toFixed(1)}ms`);
|
|
335
345
|
if (depth === 1 && filterSpec === undefined) {
|
|
336
346
|
for (const sha of normalized)
|
|
337
|
-
this.
|
|
347
|
+
await this.store.markSnapshot(sha);
|
|
348
|
+
}
|
|
349
|
+
return Result.ok(parsed.value.stats.retained);
|
|
350
|
+
}
|
|
351
|
+
async parsePackFile(pack, options, sink) {
|
|
352
|
+
try {
|
|
353
|
+
const packBytes = new Uint8Array(await readFile(pack.path));
|
|
354
|
+
return parsePackfile(packBytes, options, sink);
|
|
355
|
+
}
|
|
356
|
+
catch (cause) {
|
|
357
|
+
return fail(new PackParseError({
|
|
358
|
+
reason: "pack-read-failed",
|
|
359
|
+
message: `failed to read pack file: ${pack.path}`,
|
|
360
|
+
cause,
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
363
|
+
finally {
|
|
364
|
+
await removeIfExists(pack.path);
|
|
338
365
|
}
|
|
339
|
-
return Result.ok(this.objects);
|
|
340
366
|
}
|
|
341
367
|
async probeFilter(profile, sha, verbose) {
|
|
342
368
|
const caps = buildCaps({ shallow: true, filter: true });
|
|
@@ -346,13 +372,13 @@ export class RemoteGit {
|
|
|
346
372
|
this.log(`filter blob:none probe failed: ${blobNonePack.error}`);
|
|
347
373
|
}
|
|
348
374
|
else {
|
|
349
|
-
const parsed =
|
|
375
|
+
const parsed = await this.parsePackFile(blobNonePack.value);
|
|
350
376
|
if (parsed.isErr()) {
|
|
351
377
|
if (verbose)
|
|
352
378
|
this.log(`filter blob:none probe failed: ${parsed.error}`);
|
|
353
379
|
}
|
|
354
380
|
else {
|
|
355
|
-
const counts =
|
|
381
|
+
const counts = parsed.value.stats.byType;
|
|
356
382
|
if (verbose)
|
|
357
383
|
this.log(`filter blob:none probe: ${counts.tree} trees, ${counts.blob} blobs`);
|
|
358
384
|
profile.supportsFilterBlobNone = counts.blob === 0 ||
|
|
@@ -365,13 +391,13 @@ export class RemoteGit {
|
|
|
365
391
|
this.log(`filter tree:0 probe failed: ${tree0Pack.error}`);
|
|
366
392
|
}
|
|
367
393
|
else {
|
|
368
|
-
const parsed =
|
|
394
|
+
const parsed = await this.parsePackFile(tree0Pack.value);
|
|
369
395
|
if (parsed.isErr()) {
|
|
370
396
|
if (verbose)
|
|
371
397
|
this.log(`filter tree:0 probe failed: ${parsed.error}`);
|
|
372
398
|
}
|
|
373
399
|
else {
|
|
374
|
-
const counts =
|
|
400
|
+
const counts = parsed.value.stats.byType;
|
|
375
401
|
profile.supportsFilterTree0 = counts.tree === 0;
|
|
376
402
|
}
|
|
377
403
|
}
|
|
@@ -391,23 +417,30 @@ export class RemoteGit {
|
|
|
391
417
|
});
|
|
392
418
|
if (body.isErr())
|
|
393
419
|
return fail(body.error);
|
|
394
|
-
const
|
|
420
|
+
const rawPath = this.store.incomingPath(".raw");
|
|
421
|
+
const packPath = this.store.incomingPath(".pack");
|
|
422
|
+
const response = await postUploadPack(this.url, body.value, rawPath, {
|
|
395
423
|
protocolVersion,
|
|
396
424
|
logger: this.transportLogger,
|
|
397
425
|
});
|
|
398
426
|
if (response.isErr())
|
|
399
427
|
return fail(response.error);
|
|
400
|
-
const pack =
|
|
401
|
-
|
|
428
|
+
const pack = await extractPackToFile(response.value.path, packPath, this.diagnostic);
|
|
429
|
+
await removeIfExists(response.value.path);
|
|
430
|
+
if (pack.isErr()) {
|
|
431
|
+
await removeIfExists(packPath);
|
|
402
432
|
return fail(pack.error);
|
|
403
|
-
|
|
404
|
-
|
|
433
|
+
}
|
|
434
|
+
this.packLogger.debug(`extracted pack: ${pack.value}B`);
|
|
435
|
+
return Result.ok({ path: packPath, length: pack.value });
|
|
405
436
|
}
|
|
406
|
-
normalizeWants(wants, depth, filterSpec) {
|
|
437
|
+
async normalizeWants(wants, depth, filterSpec) {
|
|
407
438
|
if (depth === 1 && filterSpec === undefined) {
|
|
408
|
-
|
|
439
|
+
const present = await Promise.all(wants.map((want) => this.store.hasSnapshot(want)));
|
|
440
|
+
return present.every(Boolean) ? [] : wants;
|
|
409
441
|
}
|
|
410
|
-
|
|
442
|
+
const present = await Promise.all(wants.map((want) => this.store.has(want)));
|
|
443
|
+
return wants.filter((_, index) => !present[index]);
|
|
411
444
|
}
|
|
412
445
|
pickProbeSha(profile) {
|
|
413
446
|
for (const ref of ["HEAD", "refs/heads/main", "refs/heads/master"]) {
|
|
@@ -424,16 +457,7 @@ export class RemoteGit {
|
|
|
424
457
|
this.diagnostic?.(message);
|
|
425
458
|
}
|
|
426
459
|
}
|
|
427
|
-
function
|
|
428
|
-
|
|
429
|
-
if (!object) {
|
|
430
|
-
return fail(new ObjectNotFoundError({ sha, message: `object not found: ${sha}` }));
|
|
431
|
-
}
|
|
432
|
-
return Result.ok(object);
|
|
433
|
-
}
|
|
434
|
-
function countByType(objects) {
|
|
435
|
-
const counts = { commit: 0, tree: 0, blob: 0, tag: 0 };
|
|
436
|
-
for (const obj of objects.values())
|
|
437
|
-
counts[obj.type]++;
|
|
438
|
-
return counts;
|
|
460
|
+
async function removeIfExists(path) {
|
|
461
|
+
await rm(path, { force: true });
|
|
439
462
|
}
|
|
463
|
+
//# sourceMappingURL=client.js.map
|