martinvonz / jj

A Git-compatible VCS that is both simple and powerful
https://martinvonz.github.io/jj/
Apache License 2.0
9.07k stars 317 forks source link

Allow conflicts to be materialized in Git style #823

Open chooglen opened 1 year ago

chooglen commented 1 year ago

Description

This improves interop with tools that only understand Git-style conflict markers, e.g. IDEs, npm.

We would probably make a config option for this, but it might also be nice to have a command that explicitly re-materializes the conflicted file (e.g. a user who prefers jj-style conflict markers and occasionally needs Git-style conflict markers for tooling).

martinvonz commented 1 year ago

Some things to keep in mind when implementing this (would probably become obvious for anyone who tries):

martinvonz commented 1 year ago

Btw, in addition to this git style, we could also have a snapshot style that would look like this:

<<<<<<<
+++++++
A
-------
B
+++++++
C
-------
D
+++++++
E
>>>>>>>

That would correspond to our usual style (let's call it diff) that looks like this:

<<<<<<<
+++++++
A
%%%%%%%
-B
+C
%%%%%%%
-D
+E
>>>>>>>

The snapshot style would make it easier to keep one of the sides unchanged.

ilyagr commented 2 months ago

Instead of solving the problem of supporting different conflict formats in the working copy, a possible simpler compromise would be to have a jj file edit command that allows you to edit a file from an arbitrary revision in a text editor (jj would save it to a temporary dir, and re-read it after the editor quits).

Such a command could support different conflict formats with a --conflict-format argument. This would still require implementing parsing the other conflict format. Unlike a more general implementation of conflict formats, however, it wouldn't require the command to figure out which conflict format is being used, and we wouldn't have to store that in the working copy.

Another possible name for this, suggested by @martinvonz a long time ago, would be jj resolve --edit. While the command is mostly useful for conflicted files, it could also be useful for viewing an arbitrary file in another revision, so jj file edit seems reasonable to me, but we could use either or have both as synonyms.

One possible set of names for conflict formats are jj, diff3, and diff3+ for diff3 format extended to conflicts with more sides. The last two could also have aliases git and git+, though that might also be questionable. Strictly speaking, git supports several conflict formats, but IMO the diff3 format is the only reasonable one. The zdiff3 format is particularly confusing, though some of the confusion in that discussion was my own misunderstanding.

ilyagr commented 2 months ago

Separately, there was a discussion of this on Discord. It's not mandatory reading (especially if you don't have an account), but I'd like to keep a link to it. It's unrelated to the idea I shared above.

sheremetyev commented 1 month ago

Just for reference, here is parsing of conflict markers in VSCode: https://github.com/microsoft/vscode/blob/main/extensions/merge-conflict/src/mergeConflictParser.ts

Note that it supports multiple blocks separated by |||||||, which could be used to represent multi-side conflicts