sha256convert: use SetEncodedObject; rename --sign to --sign-mode · Entire

sha256convert: use SetEncodedObject; rename --sign to --sign-mode

e7e4a1a→main·

nodo·1mo ago·4 files·+127 added/-182 removed

Address PR #66 review comments from @pjbgf.

go-git v6.0.0-alpha.4 (commit 5cab3a7) made objfile.Writer derive the hash format from the store config, so the SHA1-hardcoding that forced the hand-rolled loose-object writer is gone. Translated objects now go through dst.NewEncodedObject + SetEncodedObject, which binds each object to the target store's SHA256 hasher — the returned hash and the on-disk loose path are both SHA256. Drops encodeBody/writeLoose and the manual zlib/tempfile/rename plumbing; the on-disk sha256(content) invariant test is kept as a regression guard.

Replace the --sign bool with --sign-mode {none,tips} (default none), forward-compatible with a future "all" mode that signs every commit/tag. Run validates the value up front.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

fec9df19e265View transcript

Changes

4

87 unmodified lines
cmd.Flags().BoolVar(&req.Check, "check", false,
    "verify the output after conversion (config, HEAD, refs, git fsck --full)")
cmd.Flags().BoolVar(&req.Sign, "sign", false,
    "after conversion, sign each branch tip as refs/tags/converted/<branch> via `git tag -s`")
cmd.Flags().StringVar(&req.SignMode, "sign-mode", sha256convert.SignModeNone,
    "post-conversion signing: `none` (default), or `tips` to sign each branch tip as refs/tags/converted/<branch> via `git tag -s`")
cmd.Flags().StringVar(&req.SignKey, "sign-key", "",
    "signing key id to pass to `git tag -s -u`; default uses the repo's user.signingkey")
cmd.Flags().BoolVar(&req.KeepSourceObjects, "keep-source-objects", false,

// other content removed

Branch-tip attestation tags (opt in via --sign)

--sign shells out to git tag -s converted/<branch> <tip> for every

--sign-mode defaults to none (sign nothing). --sign-mode tips shells out to git tag -s converted/<branch> <tip> for every converted branch after the conversion completes. Each resulting signed annotated tag is a cryptographic attestation by the converter that the entire reachable history of that branch — every parent, tree,

--no-rewrite-messages skip inline hash rewrites in messages --no-origin-notes skip refs/notes/sha1-origin --check verify the output (config, HEAD, refs, git fsck) --sign sign each branch tip via git tag -s converted/<branch> --sign-mode signing mode: none (default) or tips (sign each branch tip as refs/tags/converted/ via git tag -s) --sign-key signing key id passed to git tag -s -u <key> --keep-source-objects leave the temp SHA1 store on disk --progress live per-phase object counts (TTY only)

Loose object writing is done by hand rather than via go-git's SetEncodedObject. The underlying plumbing/format/objfile.Writer in go-git/v6@v6.0.0-alpha.3 hardcodes SHA1 in its hasher, which would put every translated object at a SHA1-derived path even though the content references SHA256. A unit test recomputes sha256 of every loose object's decompressed content and compares against the filename to prevent regression. Translated objects are written with go-git's SetEncodedObject. Each one is built through the target store's NewEncodedObject, which binds it to the store's SHA256 hasher, so both the returned hash and the on-disk loose path are computed under SHA256.