Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] 探索支持 3-way merge editor 解决合并冲突的新交互 #1930

Closed
Ricbet opened this issue Nov 7, 2022 · 17 comments
Closed
Assignees
Labels
🎨 feature feature required
Milestone

Comments

@Ricbet
Copy link
Member

Ricbet commented Nov 7, 2022

背景
目前 opensumi 的解决冲突功能默认是基于 vscode 的 merge-conflict 模块
也就是最常见的在单文件上显示冲突符号 7 个 '<' '=' '>'

采用当前更改 | 采用传入的更改 | 保留双方更改 | 比较变更
<<<<<<<
code1
=======
code2
>>>>>>>

所有的操作都集中在 codelens 上执行,这对于冲突代码行数较少的情况下比较方便,任何操作反馈都能在一个窗口中看到
而对于冲突代码行数较多,冲突个数也较多的情况下就比较难看得出来差异

而 vscode 在一次版本更新中提供了 3-way merge editor 视图的解决冲突的新交互
见: 3-way-merge-editor

最新版本将复选框操作默认改为 codelens 了,只有通过设置 "mergeEditor.showCheckboxes" 才会出现复选框

示例截图:
image

视图分上下两大块区域,上面是两个冲突文件分别与 base 分支的 diff 差异结果,下面是解决冲突后的 result 结果
整体的视觉风格和 visual studio 的合并冲突有点像

👇这是 visual studio 的

image

比较不同的是解决冲突的各种操作还是以 codelens 为主,而不是复选框

相关 issue
microsoft/vscode#37350: 社区用户期望在 vscode 里也能使用像是 IntelliJ 或 WebStorm 的解决冲突工具
microsoft/vscode#146091: 3-way 合并视图的 UX 设计
microsoft/vscode#157361: 新的 3-way 视图上线后网友对这个新交互的评价似乎不太友好,较多人反馈学习曲线复杂,总结一句就是 It's not fun!
microsoft/vscode#160806: 在上一个 issue 中饱受用户强力的吐槽之后,将这一功能通过配置来默认关闭了(悲催)

但微软并没有放弃这一个大的新特性,而是作为一个开关配置项并默认关闭,同时在旧版的内联编辑器右下角提供了 resolve in merge editor 按钮来跳转到 3-way 视图模式

其实在 #157361 中用户所吐槽的大多数都是一些冲突行数较少的情况,这时肯定是旧版的内联编辑器交互更友好一些

@Ricbet Ricbet added the 🎨 feature feature required label Nov 7, 2022
@Ricbet Ricbet self-assigned this Nov 7, 2022
@Ricbet Ricbet changed the title [FEATURE] 支持 3-way merge editor 解决合并冲突的新交互 [FEATURE] 探索支持 3-way merge editor 解决合并冲突的新交互 Nov 9, 2022
@Ricbet
Copy link
Member Author

Ricbet commented Nov 9, 2022

开发计划

参考 3-way 的 UX 交互和视图设计,我们采用相同的 3-way 视图来展示,但解决冲突的操作交互我比较偏向复选框而不是 codelens

- [ ] 基础代码模块设计(3-way 原型视图)
- [ ] 分支信息的展示(base、incoming、current),commit id 和 分之名称等
- [ ] editor 滑轮滚动同步
- [ ] 复选框功能实现
- [ ] 代码冲突行的边框实现(分未解决和已解决的标识)
- [ ] next、previous 交互实现
- [ ] 兼容旧版 merge conflict 并在右下角提供跳转按钮
- [ ] git diff 的 Myers 算法实现
- [ ] accept incoming(accept current)、accept combination 和 remove incoming(current)实现

进阶
- [ ] 针对变动行数较少的 diff 采用 dynamic program 算法实现
- [ ] 解决冲突的操作提供 checkbox 和 codelens 的切换配置(或同时展示?)
- [ ] 复选框右键功能(如 accept both 等)

@Ricbet
Copy link
Member Author

Ricbet commented Nov 10, 2022

更新
对比查看了市面上多数 ide 在 merge conflict 的体验,决定暂时先放弃参考 vscode 的这种排版布局方式,优先考虑采用 左、中、右 式的布局排版

以下是各 IDE 的解决合并冲突截图

IDEA
image

Araxis Merge(收费软件)
image

VS Code
image

结论
经过这么一番对比,其实不难发现,确实 IDEA 版的更直观更友好一些,体验上也更能让开发人员喜欢
所以我们会在基于 monaco 之上设计开发区别于 vscode 的 3-way merge editor

设计图
image

@erha19
Copy link
Member

erha19 commented Nov 10, 2022

@Ricbet 对于每个编辑器(Pre,Current,Result)感觉少了一些标识。

另外编辑器间的引导线有啥方案吗?如果 1,2 编辑器滚动不对齐的情况是不是不太理想

@Ricbet
Copy link
Member Author

Ricbet commented Nov 10, 2022

@erha19 标示都会有的,会在编辑器的头部展示。
滚动的话是三个视图一起滚动的,应该不会出现不对齐的情况,其实更大的问题应该是引导线不好画

@Ricbet
Copy link
Member Author

Ricbet commented Nov 11, 2022

@Ricbet
Copy link
Member Author

Ricbet commented Nov 14, 2022

默认使用 Myers Diff 算法计算 3 个 editor 文本之间的差异,相关 commit
其中左边与中间作 diff、中间再与右边作 diff,并将有差异的部分用 decoration 绘制

原型图
image

@erha19 erha19 added this to the 2.22 milestone Nov 14, 2022
@Ricbet
Copy link
Member Author

Ricbet commented Nov 17, 2022

  • 实现 line widget e76d1c4
  • 渲染 3 个不同状态的颜色(insert、modify、remove)10786f0
  • 实现 scroll change 同步 41d18c5
  • 代码重构

现有效果
image

@Ricbet
Copy link
Member Author

Ricbet commented Nov 17, 2022

@Ricbet
Copy link
Member Author

Ricbet commented Nov 28, 2022

现有效果

Kapture.2022-11-28.at.14.12.22.mp4

@Ricbet
Copy link
Member Author

Ricbet commented Dec 1, 2022

当前整体进度在 75% 左右
还有以下几个事项待解决


feature

optimization

final

  • 与 git scm 插件相结合

@Ricbet
Copy link
Member Author

Ricbet commented Dec 1, 2022

色值也会有所调整,在等设计出效果图

@bytemain
Copy link
Member

bytemain commented Dec 1, 2022

amazing, real amazing.

@Ricbet
Copy link
Member Author

Ricbet commented Dec 12, 2022

conflict action 执行后的 undo 和 redo 处理暂时放在第二期搞

@Ricbet
Copy link
Member Author

Ricbet commented Dec 13, 2022

编辑代码动态绘制 diff 区域还存在以下几个问题待修复

  • accept current 如果是删减代码,执行 revoke 时高度少一行
  • accept current 如果是新增代码,执行 revoke 时高度多一行
  • 在某一块 diff 区域删减代码,删到剩一行时,再删除应该是变成 line widget 而不是往上移动

@Ricbet
Copy link
Member Author

Ricbet commented Dec 13, 2022

conflict action 各种操作的测试反馈记录

  • accept combination 操作后执行撤回,diff 颜色状态没有变回去
  • 多个 merge range 在执行某一个 accept current 操作后,另一边视图的 accept current 图标应该发生改变,如
    image
    表示"追加"变更,与"新增"还不一样,"追加" 不会覆盖中间视图的文本,而是在 diff 区域底部追加代码

@Ricbet
Copy link
Member Author

Ricbet commented Dec 15, 2022

结合 Git 插件问题记录

相关 issue: #2094

  1. 需要升级 Git(built-in) 插件到 1.68.1(目前适配版本是 1.62.3)

    • 丝滑升级,没有未实现的 API
    • 需要自己编译 VS Code 1.68.1 分支下的 extension/git 插件并上传到插件市场
    • 升级后需要修改 git.experimental.mergeEditor 配置项为 true
  2. 代理执行 _open.mergeEditor 内置命令

  3. 打开一个冲突文件,代理的命令参数会是以下格式

{
 ancestor: URI, // base 分支代码,也就是两个冲突分支的共同祖先分支,直接 open 即可
 input1: { // current
    description: string, // commit
    detail: string, // 分支名
    title: string, // 标题
    uri: URI
 },
 input2: 同上👆 // incoming
 output: URI // 冲突文件的磁盘文件
}

所以,result view editor 视图加载的 monaco model 会有所调整,改为加载 ancestor

  1. 目前链路已打通,但还有以下几个问题需要处理 feat: show title head info & implement the apply actions #2095
    • 切换 tab 后,decoration 绘制没有重置,仍保留着上一个文件的 decoration
    • 上下滚动视图的钝感很明显
    • 点击 conflict action 操作后页面视图会滚动

效果预览

default.mp4

@erha19
Copy link
Member

erha19 commented Dec 30, 2022

Closed by #1960.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎨 feature feature required
Projects
None yet
Development

No branches or pull requests

4 participants