TurtleGit for Mac

View Markdown source ↗

Stash preparation, completion and ownership

Pinned source: TortoiseGit 7338078f8ddd924b8cddee35f512f2286072136d. This extends the existing Stash audit; IDD_STASH and the connected Save/Pop/Apply/Drop workflows remain partial family mappings, not a whole-port completion claim.

Source mapping and preserved behavior

Pinned source Native implementation
AppUtils.cpp:106–112, CAppUtils::StashSave, CheckUserData User Save prepares the configured author/committer identity before enabling its form; missing data opens an owned Git Settings sheet. Cancel aborts preparation. Accepted Settings rereads effective identity, including source environment precedence. Submission rereads, and Core checks once more immediately before stash push.
StashSave.cpp:39–124, IDD_STASH (TortoiseProcENG.rc:1812–1827) Single-line optional message, include-untracked and --all mutual exclusion, OK/Cancel/Help, horizontal resize and Continue-only warning suppression remain. Controls capture form identity and reject writes from retired, disabled or deferred-Quit presentations.
AppUtils.cpp:114–156, Save command and completion Keeps stash push, enabled flags, unchanged message bytes through -m, and old/new refs detection. Pull and Merge precede created-only Pop/Apply, with existing source icons and follow-up values. Successful no-change Save can still offer Pull/Merge.
AppUtils.cpp:161–207, StashApply Selected entries remain hash-pinned; Apply keeps the stash. Success/conflict questions and quiet notices retain source showChanges behavior.
AppUtils.cpp:210–258, StashPop Latest-stash Pop, independent remembered clean/conflict answers, showChanges modes and conflict-retained stash behavior remain.
RefLogDlg.cpp, stash deletion; Core ReferenceLog.swift Existing explicit Drop/Clear confirmation, positional-stack snapshot validation, oldest-first deletion and per-item failure handling remain intact. This batch adds no new Drop identity requirement.

Identity and operation contract

StashSaveOptions.requireIdentity defaults false. Source user Save sets it true; internal Rebase/Bisect saves keep Git's existing requirements. Core refusal uses StashFailure.identity before the mutating command. No Merge-only active-replay restriction is imposed: upstream Stash Save does not call IsTGitRebaseActive.

Preparation owns its cancellation token, repository grant and static StashWindowModel.activePreparations count until the read/Settings workflow actually returns, even after forced owner closure. A late or noncooperative read cannot enable a retired form or launch Git. Closing a pending preparation cancels its token and retires the Settings sheet, then closes the owner after return. Submission captures the options and follow-up request. The Core command has its own final identity recheck; an earlier accepted Settings result is not an authority to mutate later.

Save progress consumes a chosen post-action once and drains its actual AppKit sheet before closing progress/options and dispatching the follow-up. A retained button or duplicate reply cannot dispatch a second operation. Restore similarly drains the result question and closes the Restore window before View Changes. Ordinary result Close and forced closure also retain actual detach ownership. StashWindowController.activeChildReleases includes both Save and Restore child transitions; the shared release helper is retained until AppKit reports the child is detached.

Owned include-untracked, process cancellation and result sheets pass the parent's alpha and appearance before presentation. A result that arrives while a Cancel question remains attached drains the old question before presenting the result. Forced closure retires replies and queued presentations. Settings retains its existing owned sheet release implementation. No automated child should appear visibly when its owner is hidden.

Save, Save Progress and Restore expose confirmingQuit. Deferred Quit refuses new form/command/post-action transitions. Root Quit checks include preparations, pending warnings/Settings, progress/result prompts and child-release counters; actual Git execution retains LocalGitCommandProgress/Restore operation counts. An accepted Restore answer already delivered during deferred Quit waits for that state to end, then is consumed once.

Grouped verification

Implementation completed before the grouped checkpoint. The related Core and native cases passed; actual failures, focused repairs and remaining limits are recorded in the batch evidence below.

The new receiver owns private preferences and repositories, keeps all windows and sheets hidden, closes every owned controller and drains held operations on success and failure. It does not invoke network, Keychain, a credential helper, or the user pasteboard.

Remaining acceptance and limits

Physical light/dark layout and keyboard/accessibility review of every upstream control, signed/App Store folder grants, installed helper behavior and complete Finder integration remain separate acceptance work. Existing Git cancellation can retain mutations already completed; no rollback is promised. Windows message-box and system-progress presentation uses native sheets/windows while preserving its result choices. Drop/Clear behavior is retained from its existing family audit; this batch does not certify every Reflog menu or every stash/replay combination.

Grouped execution outcomes and repairs are recorded in batch evidence.