feat(windows): add merge, rebase, and conflict resolution UI - #107
Merged
1lck merged 11 commits intoAug 16, 2026
Conversation
…ispatcher - translate git_merge and git_rebase into git.write with qualified refs/heads references, mirroring the checkout translations - add git_integration_preflight, git_operation_state, git_operation_continue/abort/skip, and git_conflict_markers translations so the frontend can drive the shared core's conflict machinery
- map git.operationState responses into a UI-ready shape and collapse the no-operation case to null, matching the macOS model - pass through integration preflight blocking paths and conflict marker paths for the upcoming banner and commit guard
- add git-integration-api with preflight-first merge/rebase that distinguishes conflict stops from real failures via operation state - store operationState in the workspace git store and refresh it on every status pass so banner state stays true to the repository
- mirror the macOS banner: in-progress title, rebase step counters, conflict count, and Continue/Skip/Abort actions - keep Continue disabled while conflicts remain and re-run resolution through the shared core, refreshing state after every attempt
- add a per-branch action menu with Merge into Current Branch and Rebase Current Branch onto This behind one confirmation each - surface clean, conflict-stop, blocked-by-dirty, and failure outcomes with the shared core's preflight and operation state
- refuse to commit while the operation state still lists conflicted paths or staged files contain conflict markers, with the file names surfaced instead of Git's raw refusal
The action wrapper only stopped pointer-down propagation, so the click that opened the menu also bubbled to the row's checkout handler, which disabled the trigger and closed the menu instantly. Stop click propagation like the retired delete button did.
…menu Button wraps itself in a Tooltip component when given a tooltip prop, so Base UI's render prop attached the menu trigger handlers to the tooltip wrapper instead of the real button and clicks never opened the menu. Pass only aria-label, like the working diff header trigger.
1lck
reviewed
Aug 16, 2026
| // A conflict stop exits non-zero like a real failure; the authoritative | ||
| // distinction is whether Git left an operation state behind. | ||
| const state = await getOperationState(repoPath); | ||
| if (state && state.kind === operation && state.conflictedPaths.length > 0) { |
Owner
There was a problem hiding this comment.
Important: 这里不能用 conflictedPaths.length > 0 判断操作是否仍在进行。Rust Core 会独立报告 operation kind 和当前未合并路径;例如 rebase 因空提交、编辑器或 hook 失败而暂停时,operation state 仍存在但冲突列表可以为空。当前逻辑会返回普通 error 且不触发刷新,导致 Continue / Skip / Abort 横幅不出现。建议任何 kind 匹配的非空 state 都按 stopped/in-progress 处理并触发刷新,最好增加独立的 stopped outcome,并补一个空冲突列表的回归测试。
| return await tauriInvoke<GitOperationState | null>("git_operation_state", { | ||
| repoPath: resolvedRepoPath, | ||
| }); | ||
| } catch { |
Owner
There was a problem hiding this comment.
Important: 查询失败不能转换成 null。调用方会把 null 写回 store,当 Core 调用瞬时失败或仓库暂时不可访问时,这会把仍在进行的 merge/rebase 当作 idle 并隐藏恢复按钮。请传播结构化错误,或至少让刷新失败时保留最后一次已知 operation state。
| repoPath: resolvedRepoPath, | ||
| }); | ||
| return result.paths; | ||
| } catch { |
Owner
There was a problem hiding this comment.
Important: 这里返回空数组会让冲突标记保护 fail-open:调用方把 [] 当作安全并继续 commit。已经 stage 的 <<<<<<< 等文本不再是 unmerged index,Git 自身不会阻止提交。请把查询失败传播给提交面板并显示可重试错误;检查失败时不要执行 commit,同时补充 Core 查询失败的测试。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
功能
为 Windows 端补齐 merge / rebase / 冲突处理的完整工作流,对齐 macOS 参考端(其设计仿 IntelliJ IDEA)。此前 Windows 端没有任何 merge/rebase 入口与冲突界面,Core 侧全部能力(
git.write merge/rebase、git.integrationPreflight、git.operationState、operationContinue/Abort/Skip、git.conflictMarkers)未被使用。实现(8 个提交)
git_merge/git_rebase/git_integration_preflight/git_operation_state/git_operation_continue|abort|skip/git_conflict_markers七组翻译,分支引用统一走local_branch_reference补全git_operation_state(空 kind → null)、git_integration_preflight、git_conflict_markers结果适配git-integration-api(preflight 先行、以 operationState 区分"冲突停止"与"真失败"、操作后无条件触发刷新);git.store增加operationState,挂入现有事件驱动刷新管线——终端发起的 merge 同样能被横幅如实反映验证
cargo test(src-tauri): 19/19(新增 4 组翻译测试)bun test: 41/41(新增 operationState/preflight/markers 适配测试)tsc --noEmit: 通过已知边界(与 macOS 参考端行为一致或属既有课题)
M)时 Continue 即启用——与 macOS 相同;Core 侧merge --continue会拒绝并回显 git 报错,无误操作风险关联