lazygit icon indicating copy to clipboard operation
lazygit copied to clipboard

3-way merge conflict editor

Open mrjones2014 opened this issue 3 years ago • 12 comments

Is your feature request related to a problem? Please describe.

Merge conflicts suck. Resolving them can get really confusing. Sometimes you're not sure what you're looking at when the changes are stacked on top of each other like that, and sometimes you want some parts of both changes.

Describe the solution you'd like

A 3-way merge conflict editor UI. Basically, it shows the local file on the left, the remote file on the right, and the merged result preview in the middle (which is also manually editable so you can make minor tweaks to the merged result if needed). Here's an example of what the one built into JetBrains products looks like:

3 way merge editor from JetBrains

Note that you can manually edit the file in the middle view. Not sure if this is possible/feasible in lazygit though.

Describe alternatives you've considered

  • Using a GUI merge conflict resolution tool 🙁
  • Using the simple merge conflict resolution tool already built into lazygit

mrjones2014 avatar Aug 24 '22 13:08 mrjones2014

Using a GUI merge conflict resolution tool :slightly_frowning_face:

Well, until we support such a feature within lazygit itself, at least launching a merge tool isn't far (M opens an external merge tool)

Would you be interested in adding support for 3 way merging?

mark2185 avatar Aug 24 '22 13:08 mark2185

Would you be interested in adding support for 3 way merging?

I might need some help but I can give it a shot!

mrjones2014 avatar Aug 24 '22 13:08 mrjones2014

Well I'm guessing it would require planning and a discussion of what it should look like for which we need Jesse.

But if I were to guess of what we should discuss beforehand:

  • similar to the partial staging panel, but having 3 splits instead of 2 ( maybe the third one could be below )
  • all should be editable, which we don't currently have (at least not of that specific use, e.g. existing text with multiple lines filling an editable buffer)
  • we'd need to work how to switch between them
  • mappings for accepting changes from one, the other, or both of the panels

mark2185 avatar Aug 24 '22 13:08 mark2185

Well I'm guessing it would require planning and a discussion of what it should look like for which we need Jesse.

But if I were to guess of what we should discuss beforehand:

  • similar to the partial staging panel, but having 3 splits instead of 2 ( maybe the third one could be below )
  • all should be editable, which we don't currently have (at least not of that specific use, e.g. existing text with multiple lines filling an editable buffer)
  • we'd need to work how to switch between them
  • mappings for accepting changes from one, the other, or both of the panels

I got a few questions since I've been using LazyGit for months and the one thing I dislike is how it handles merge conflicts.

  1. What is the partial staging panel ?
  2. You mentioned mappings for accepting changes from one or the other or both panels - i feel like functionality is already there just needs to be implemented to support this behaviour ?
  3. Would lazygit ever support the option to show a totally different view strictly for merge conflicts?

hsheikhali1 avatar Aug 24 '22 14:08 hsheikhali1

  1. You can partially stage files by pressing Enter on a file and staging/unstaging lines with Space.
  2. Well since this is a specific scenario, where one would have 3 panels, so it is mostly familiar, but not completely.
  3. Jesse would know

mark2185 avatar Aug 24 '22 14:08 mark2185

Do note that if we would implement separate editable buffers, 0.01s after its merge to master, there would be a request for it to support {vim,emacs,kakoune,somethingelse}-bindings. I'm not sure we want to open that particular door.

mark2185 avatar Aug 25 '22 08:08 mark2185

Is there maybe a way we could just embed a TUI editor within the TUI? Idk if that’s possible, haven’t worked much with TUI, but I know Neovim at least is designed to be embeddable.

mrjones2014 avatar Aug 25 '22 10:08 mrjones2014

Is there a point in doing that when the user could just run the TUI editor externally?

mark2185 avatar Aug 25 '22 10:08 mark2185

Hm, I suppose not actually.

mrjones2014 avatar Aug 25 '22 11:08 mrjones2014

So, what would we gain by adding a 3-way merge conflict editor that has the most basic editing capabilities, namely moving around using arrow keys and typing and deleting?

On the other hand, one could just use the desired merge tool one is used to, e.g. emerge, vimdiff, kdiff3, meld etc. by launching it from lazygit when the need arises.

mark2185 avatar Aug 25 '22 11:08 mark2185

Good point. After a little more tinkering I've found that installing the vim-fugitive Vim plugin, then setting my mergetool like so:

[merge]
  tool = nvim
[mergetool "nvim"]
  cmd = nvim -f -c \"Gdiffsplit!\" \"$MERGED\"
[mergetool]
  prompt = false

works well enough for me. Being able to launch this directly from lazygit too is nice.

I'm good to close this issue. I'll use vim with the vim-fugitive 3 way merge conflict editor and launch it from lazygit when needed.

mrjones2014 avatar Aug 25 '22 12:08 mrjones2014

If you really so desire, I guess it's possible to use IntelliJ as a mergetool as well (that's what you listed as an example in the original issue)

Someone tried it.

mark2185 avatar Aug 25 '22 12:08 mark2185

Really like lazygit. But struggling with one thing - when you are doing resolving of merge conflicts what is the best flow to pick only part from merge hunk, bot not whole hunk ? Usually in VSCode I'm able to manually adjust what I want to pick in this situation.

Screenshot 2022-10-12 at 11 52 46

kuzyo avatar Oct 12 '22 09:10 kuzyo

I don't think there's a way to do that other than opening it up in an external mergetool, which you can use VScode for.

mark2185 avatar Oct 12 '22 09:10 mark2185

@mark2185 Thank you.

kuzyo avatar Oct 12 '22 10:10 kuzyo

@kuzyo You can open a VSCode from the conflict panel using editCommand(e) or openCommand(o).

os:
  openCommand: 'code --goto -- {{filename}}:{{line}}'
  editCommand: 'code'

Ryooooooga avatar Oct 13 '22 09:10 Ryooooooga