Skip to content

feat(add)!: start from the current worktree's branch; auto mise-trust new worktrees - #153

Open
jadb wants to merge 3 commits into
mainfrom
feat/hop-add-defaults
Open

jadb wants to merge 3 commits into
mainfrom
feat/hop-add-defaults

Conversation

@jadb

@jadb jadb commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Summary

git hop add without --from now starts from the branch of the worktree it runs in (or the local default branch at the hub root), and trusts the new worktree's mise config when the source worktree's is trusted. mise stays optional: nothing is printed when it is absent or unused.

Changes

Default start-point (feat(add)!)

Before: no --from meant refs/remotes/origin/<default>, always fetched first, set as upstream, regardless of the worktree you were in.

Now, with no --from:

  • inside a worktree: that worktree's current branch (local ref)
  • hub root / outside any worktree: local default branch (hop.json repo.defaultBranch, else origin/HEAD's name); origin/<default> only when no local branch exists
  • detached HEAD: the detached commit (like git switch -c), no base recorded

Configured through the existing hop.add.defaultStartPoint key, GIT_HOP_ADD_FROM, or --from:

value start-point
cwd (new default) current worktree's branch; local default branch at hub root
default-branch local default branch
origin-default origin/<default> (previous behaviour)
initial / any ref unchanged
  • automatic fetch only when the resolved start-point is an origin ref
  • --dry-run prints the resolved start-point and the reason
  • copy-ignored source and git-flow base follow the resolved start-point
  • fixed the misleading resolveStartPoint comment

mise trust (feat(add), fix(add))

mise's own cross-worktree trust sharing looks for the main checkout, which in a bare hub is the bare repo, so new worktrees with a mise config start untrusted and mise-backed hooks and make targets fail.

New step after ignored files are copied, before environment set-up and post-worktree-add hooks. In auto mode it runs mise trust <worktree> only when:

  • mise is installed
  • the new worktree has mise config
  • the source worktree's config is trusted (mise trust --show)
  • both worktrees have byte-identical mise config files (listed via mise's paranoid mode)

Settings: hop.add.miseTrust auto|always|never (default auto), --mise-trust / --no-mise-trust per run. always trusts whenever the new worktree has mise config.

Output: silent when mise is not installed or the worktree has no mise config (debug line with -V). A hint with the manual mise trust <worktree> command appears only when mise and config are present but trust was skipped.

mise.<env>.toml files are compared only when MISE_ENV is set.

Breaking change

New branches no longer start from a freshly fetched origin/<default> and no longer get it as upstream. Restore with:

git config hop.add.defaultStartPoint origin-default

Testing

  • e2e start-point tests (inside a worktree, subdirectory, hub root, each config value, --from, env over config, detached HEAD, dry-run output) fail before the change and again when it is reverted
  • tests that pinned the old default now set origin-default explicitly
  • mise: unit tests with a fake mise; e2e with real mise in isolated MISE_DATA_DIR / MISE_STATE_DIR / MISE_CONFIG_DIR / MISE_CACHE_DIR covering trusted and untrusted source, differing and extra config, no config, mise missing (silent), always / never, flags; each behaviour re-broken to confirm the tests fail
  • go test ./..., gofmt, go vet, staticcheck clean

Docs: docs/04-commands.mdx, docs/configuration.md, docs/09-reference.mdx, docs/hooks.md, add --help reference.

jadb added 3 commits October 15, 2026 09:23
- default start-point cwd: branch checked out in worktree add runs in;
  hub root / outside worktrees -> local default branch
- detached HEAD -> its commit, like git switch -c; no base recorded
- keywords for --from / GIT_HOP_ADD_FROM / hop.add.defaultStartPoint:
  cwd, default-branch (now local ref; origin/<default> only when no
  local branch), origin-default (old behaviour), initial
- default branch name falls back to origin/HEAD when hop.json has none
- dry-run: resolved start-point + setting that picked it
- copy-ignored source: worktree start-point came from
- auto fetch only when resolved start-point is an origin ref
- help text, docs, help golden; resolveStartPoint comment corrected

BREAKING CHANGE: add without --from no longer starts new branches from a
freshly fetched origin/<default>, nor sets it as their upstream; inside a
worktree it starts from that worktree's branch, at the hub root from the
local default branch. `git config hop.add.defaultStartPoint
origin-default` restores the old behaviour.
- after copy-ignored, before env set-up + post-worktree-add hooks
- auto: mise on PATH, new worktree has mise config, source worktree's
  trusted (mise trust --show), config files identical byte for byte
  (file list via mise's paranoid-mode trust --show, no parsing)
- otherwise skip with hint: mise missing, no config, untrusted source,
  config differs, no source worktree
- trust via mise trust <worktree>
- hop.add.miseTrust auto|always|never (default auto);
  --mise-trust = always, --no-mise-trust = never for one run
- dry-run reports source-side decision
- source worktree shared with copy-ignored (forkSource)
- help text, help golden, docs (commands, configuration, reference, hooks)
- mise not on PATH: debug line only, no hint (add + dry-run)
- no mise config in new worktree: debug only
- dry-run: debug only when no source worktree or source has no mise config
- hint kept for actionable skips (mise present, config present, source
  untrusted / config differs / no source), with mise trust <worktree>
  command on its own hint line
- tests: missing mise + no config assert silence; preview unit tests
- help text, help golden, docs: mise optional
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant