# Improvements

## Sessions

Transcript data is unavailable for this checkpoint.

## Changes

4

- cmd/git-sync

- Mconvert_sha256.go+11/-25

- internal/sha256convert

- Msha256convert.go+211/-136

- Msha256convert_test.go+66/-37

- docs

- Mconvert-sha256.md+131/-162

`git-sync convert-sha256` is a one-off migration command that fetches a pack from a SHA1 HTTP source and writes a new SHA256 bare repository on disk. Every reachable object is re-hashed under SHA256 and tree, commit, and tag references are rewritten accordingly.

The command is intentionally narrow: it does not push to a remote, it does not modify the source, and it is meant to be run once per repo. Resulting references are rewritten accordingly. The command does not push to a remote, does not modify the source, and is meant to run once per repo. SHA256 hashes have no relation to the original SHA1 hashes beyond a mapping that the command can optionally emit.

## Quick Start

```bash
git-sync convert-sha256 --tags 
git-sync convert-sha256 
https://github.com/source-org/source-repo.git 
/path/to/out.git
```

The target directory must not exist or must be empty. The result is a bare repository with `extensions.objectformat = sha256` and a `refs/notes/sha1-origin`
ref recording each commit's pre-conversion SHA1.

Scope is fixed: every branch and every tag on the source is always converted. Pass `--all-refs` to also include `refs/notes/*`, `refs/pull/*`, and other custom namespaces; pair with `--exclude-ref-prefix` to subtract specific namespaces (e.g. `--exclude-ref-prefix refs/pull/` on GitHub mirrors).

For a private source, pass the token via the environment so it isn't exposed in `ps`:

```bash
GITSYNC_SOURCE_TOKEN=ghp_xxx git-sync convert-sha256 --tags 
GITSYNC_SOURCE_TOKEN=ghp_xxx git-sync convert-sha256 
https://github.com/source-org/private-repo.git 
/path/to/out.git
```

## What It Does

1. Probes the source via smart HTTP and discovers refs matching the requested scope (`--branch`, `--tags`, `--all-refs`, `--map`, `--exclude-ref-prefix`).  
2. Fetches a single self-contained pack via `upload-pack` and lands it in a temporary on-disk SHA1 bare repo. The temp directory is cleaned up on exit unless `--keep-source-objects` is passed.  
3. Initializes the target as a bare SHA256 repository  
4. Runs a **discovery pass** that walks every reachable object from each desired ref tip and records its SHA1 and object type. This gives the rewriter an authoritative "what's in scope" set so abbreviated message references can be resolved consistently and message-reference edges can be added to the translation graph.  
5. Translates every reachable object in topological order via a memoized DFS:
   - **Blobs**: re-hashed under SHA256; content unchanged.  
   - **Trees**: each entry's hash translated via the in-memory mapping; submodule gitlinks left as-is when the referenced commit is in this repo, otherwise the run errors.  
   - **Commits**: `tree` and `parent` hashes translated; GPG signatures dropped; `mergetag` extra headers dropped; in-scope SHA1 references in the message are translated first (so their SHA256s are known) and then substituted into the message.  
   - **Tags**: target hash translated; signatures dropped; tag message hashes rewritten with the same edge mechanism as commits.  
6. Writes refs in the SHA256 target at the translated tip hashes. HEAD is repointed at the source's symbolic HEAD when that ref made it into the conversion.
7. Optionally writes the SHA1 → SHA256 mapping as a TSV sidecar (`--write-mapping <path>`).

## Side Outputs

## Handling External SHA1 References
The conversion deliberately decouples SHA1 from SHA256 — two runs of this tool against the same source produce SHA256 hashes that share nothing with the originals. Three on-ramps help bridge the gap.
