Skip to content

[Unpolished prototype] 3 way merge for Git#150388

Closed
Mingpan wants to merge 2 commits intomicrosoft:mainfrom
Mingpan:3wm-unpolished-prototype
Closed

[Unpolished prototype] 3 way merge for Git#150388
Mingpan wants to merge 2 commits intomicrosoft:mainfrom
Mingpan:3wm-unpolished-prototype

Conversation

@Mingpan
Copy link
Copy Markdown
Contributor

@Mingpan Mingpan commented May 25, 2022

This PR is a prototype of 3 way merge with basic Git integration. The original issues are #37350 and #146091.

The purpose of this PR is only to share ideas & code. The code is not polished.

Summary

The prototype adds an inline icon to the “Merge changes'' group in the source control view provided by Git extension. When clicked, it opens up a 3 way merge editor.

Screencast

3wm.Git.prototype.mp4

Details about the prototype

Directions when prototyping

  • Follow the existing pattern of side-by-side diff editor wherever possible
    • Reuse existing computeDiff API from editor (web) worker for heavy lifting
  • Minimize the dependency on different source control systems (e.g. Git)

Key design choices

  • Rely only on the resource URIs - To use the feature, an extension (or contribution) only needs to provide the URIs pointing to each of the merge participants: common ancestor, left, right. We do not rely on conflict markers provided by source control systems. As a result it has little dependency on the source control system, all together <20 lines of code in the above Git example.
  • In each of the 3 sub-editors, show diff with the common ancestor version - We think it’s important to be clear about what has changed since the common ancestor, in each branch.
  • Minimize computational cost when editing - When the content is changed, only the diff between the middle editor and the common ancestor needs to be re-computed. The cost (and responsiveness) is therefore comparable with a normal diff editor.
  • For now, only the 3 column layout with arrows is implemented, because it was used in our former IDE, and is by far the most preferred version to our users. We have also developed a way to accept both (simple changes only) using arrows with some visual cues.
    • Any manual changes to a conflict region will make all arrows of the current region disappear. Undo (Ctrl+Z) can bring those back.
    • We didn’t have the bandwidth to implement the mixed / horizontal layouts. But they can be added later.
    • Checkboxes can be a configurable future work, especially for mixed layout.

Alternative considered

Nothing fundamental. Most of the alternatives should be covered above.

Current limitations

  • Merge navigator - This should provide the functionality to navigate between conflicts / diffs in the file easily. It may also allow users to jump to the first conflict when they open the editor. It’s not implemented yet (but is in the plan), but users can see the regions in the overview on the right.
  • View zones due to line wrapping - When the user enables line wrapping (instead of horizontal scrollbar), one code line may take up several actual lines. View zones need to be adjusted so that the versions are correctly aligned in this case. It’s not implemented yet (but is in the plan).
  • Branched / Deleted / Adding files - In this Git example we didn’t consider alternative file operations like branching / deleting / adding.
  • Editor banner - In our version, we show details about each branch on top of the sub-editors (e.g. commit message, author, link, etc.). This Git prototype does not have it, but should be easily available via IMergeEditor.updateBanner API in the code shared above.

User feedback

  • Our users like the 3 column layout the most, probably also because our former IDE uses it.
  • Discoverability issue - The merge view and merge actions from the source control view on the sidebar / bottom are not very discoverable. Users want to have more visible ways (e.g. buttons) to review and perform merge changes.
  • Users would like to have better ways to navigate inside the merge editor (diffs, merges), possibly also via keyboard shortcuts.
  • Users like the detailed information about each branch shown on the banner on top of the sub-editors.
  • Users would like to see the view automatically expanded when opening a merge editor, since it requires a lot of horizontal real estate.
    • Mixed layout could solve this as well.
  • Users would like to have the ability to bulk resolve conflicts by accepting all ours / all theirs.

Next steps

  • (If required) Change from exposing a command to a proposed API.
  • (If required) Support branching / deleting / adding files.
  • (If required) Get rid of the “confirm to replace” dialog when saving the merge result.
    • The dialog is theoretically accurate (since the merge editor is a layer on top of the current file), but nevertheless an additional step for users, so we can allow users to configure to skip it.
  • Bulk resolving conflicts.
  • Merge navigator with keyboard shortcuts.
  • View zones due to line wrapping.
  • Intra-region code line alignment - It’s not implemented yet (but is in the plan). Currently the code is only aligned up to the level of conflict regions. Within each conflict region, the prototype does not try to align code lines further.
  • Toolbar buttons to navigate, accept, and mark the file as resolved - Our experience shows that source control view on the sidebar / bottom is not very discoverable by users unfamiliar with the tool. We think the highly visible toolbar buttons can help. Of course we can make this configurable in settings.
  • Design an API that simplifies for most source control users (e.g. Git). Currently there’s still work to do to add banners to the editor.
  • Allow partially resolved states to be saved, so that one can resolve part of a file, save, close, then come back later.
  • Smart merge feature - We can look into providing some suggested resolve ways to users, e.g. when they hover over / put the cursor in a conflict region, and provide ways to accept / reject them.

Mingpan and others added 2 commits May 25, 2022 17:19
…like with git extension in VS Code. The code is not polished.

It opens up a 3 column editor for comparing branches. One can use the arrows to accept simple changes from left/right/both branches, or manually edit the output.
@isidorn
Copy link
Copy Markdown
Collaborator

isidorn commented May 26, 2022

@Mingpan thank you very much for this PR, we appreciate your openness to collaborate and share ideas.

As we have discussed we already started on the 3 way merge implementation, and we have an initial version that we just merged yesterday. It lacks tests and probably does not cover all the corner-cases for viewzones, so there is still a lot of work to be done. This work is captured in this PR #150391

Having said that, we have tried out your great PR and there are definitely things we can learn from. The best next step would be for @hediet to meet with @Mingpan so you can go into technical details. I will try to setup something for next week.

Apart from that I really appreciate that you shared the User Feedback, we take this very seriously fyi @daviddossett

I am very excited about this collaboration and am looking forward to bring the 3-way merge editor to all our users out there.

@isidorn
Copy link
Copy Markdown
Collaborator

isidorn commented Sep 29, 2022

Thank you again for the PR 👏 I know that you and @hediet have synced on this approach and it inspired our implementation.
I will go ahead and close this PR since as we agreed we do not have plans to merge it in directly.

@isidorn isidorn closed this Sep 29, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Nov 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants