Commit Graph
5 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 106b31a407 Harden remote API security boundaries 2026-06-12 18:24:07 +03:00
jwcrystal 291d00de8b fix: remove shell-specific \&\& operators for non-POSIX shell compat (#870) (#888)
Replace shell `\&\&` and `||` operators in execCommand calls with
TypeScript control flow. This fixes re-integrate commits failing when
the user's default shell is Nushell, which does not support `\&\&`.

Changes:
- createTempWorktree: split `mkdir \&\& mktemp` into two calls
- ensureLocalBranch: use isOk() instead of `echo ok || echo missing`
- isCherryPickInProgress: use isOk() instead of `echo yes || echo no`

Closes #870
2026-04-11 23:43:57 +03:00
jwcrystal aa071556bf fix(worktree): fix worktree detection and state reset when switching (#779)
* fix(worktree): reset IntegrateCommitsSection state when switching worktrees

Three fixes for the re-integrate commits panel getting stuck:

1. Add `key={worktreeMetadata.path}` to IntegrateCommitsSection so React
   fully remounts it when switching to a different worktree, clearing any
   stale `ui` state (conflict, loading, ready) from the previous session.

2. Add `cancelled` flag to the conflict-restore effect so that an async
   callback started for session A cannot overwrite session B's state after
   the user switches sessions. Without this guard the stale callback could
   restore the old session's conflict state on top of the new session's
   computed-ready state.

3. Fix off-by-one in continueIntegrate: `moved` was returning
   `remaining.length` (N-1, after shifting currentCommit out) instead of
   `state.remainingCommits.length` (N), undercounting the commit that was
   moved by `cherry-pick --continue`.

* fix(worktree): add git-based fallback detection when store metadata is missing

Root cause: the existing worktreeMetadata resolution relies entirely on
cached store state (worktreeMap + availableWorktrees). When the store
lookup fails—due to hydrateSessionWorktreeMetadata deleting entries on
API failure, availableWorktrees being stale, or worktrees created
externally via CLI—the "Re-integrate commits" section permanently shows
"Available in worktree mode." with no way to recover.

Fix: add useDetectedWorktreeMetadata hook that performs a lightweight
git probe (`git rev-parse --absolute-git-dir --abbrev-ref HEAD`) when
the store-based lookup returns undefined. If the current directory is a
secondary git worktree, a minimal WorktreeMetadata is synthesised with
the correct projectDirectory and branch, allowing IntegrateCommitsSection
and other worktree features to function regardless of store state.

The store-based lookup remains the primary fast path; the git probe only
runs as a fallback and caches its result per directory.

* fix(worktree): fix detection command and pass current branch from git status

Two bugs in the fallback worktree detection hook:

1. `git rev-parse --absolute-git-dir --abbrev-ref HEAD` combines two
   independent rev-parse options whose combined output is unreliable –
   the two-line assumption (`lines.length < 2`) caused silent null
   returns, meaning the fallback never actually set worktreeMetadata.
   Now uses only `git rev-parse --absolute-git-dir` (single-line,
   deterministic output) for worktree detection.

2. The hook was called before `useGitStatus`, so no branch was
   available. Move the call to after `const status = useGitStatus(...)`
   and pass `status?.current` as `currentBranch`, eliminating the need
   for a second git command and keeping the branch in sync with the
   already-polled git status.

Also removes `detected` from the useEffect deps array – it was an
unnecessary dep that triggered a re-run on every detected state change.

* fix(worktree): use worktree toplevel path and reset stale metadata immediately

Two bugs in useDetectedWorktreeMetadata:

1. path was set from currentDirectory (the active sub-folder) instead of the
   worktree root. git rev-parse --show-toplevel now provides the actual
   worktree toplevel, so operations like `git worktree remove` receive a valid
   root path regardless of which sub-directory is open.

2. When currentDirectory changed with no storeMetadata, the hook kept
   returning the prior detected value until the async git probe finished.
   Calling setDetected(undefined) before launching the async task eliminates
   the stale-metadata window.
2026-04-01 18:33:49 +03:00
Bohdan Triapitsyn 5c8c02fd00 feat: sync clean target worktrees during integration 2026-01-28 14:41:25 +02:00
Bohdan Triapitsyn 84e9391871 feat: add integrate commits to parental branch section and wired UI
Introduce IntegrateCommitsSection to plan and apply commits from source to target branch
Wire the integration panel into GitView so users can run integrate flow from the current worktree
2026-01-28 02:10:40 +02:00