Skip to content

Support Jujutsu conflict markersΒ #64852

Open

Description

@rf-

πŸ” Search Terms

jujutsu, jj

βœ… Viability Checklist

⭐ Suggestion

By default, the Jujutsu VCS represents conflicts using a different style than Git. The overall conflict area is still delimited by <<<<<<< and >>>>>>> lines, but the intermediate sections are separated by %, \, and + characters instead of = and |.

Because this doesn't match tsc's Git-based assumptions about conflicts, it generally causes the marker lines, the code they're enclosing, and nearby code to produce a lot of spurious errors, which is especially distracting when trying to clean up conflicted code in an editor.

The Jujutsu formats are documented hereβ€”there's a default diff style where some sections are diffs with +/- lines and others are Git-style snapshots, and there's also a snapshot style where all sides of the conflict are represented by snapshots.

I took a stab at a basic version of this support in #64750, but there are some subtleties here that need more thought.

The two biggest issues are:

  • The code for handling Git conflicts in TypeScript today works by parsing the first block of code (immediately following <<<<<<<) as normal, then consuming all non-marker content until the >>>>>>> marker. This is helpful because you still get type hints and whatnot for the first block, and you're less likely to run into errors in nearby code.

    In Jujutsu, there's always another marker line immediately following the <<<<<<< line, so a naive implementation would consume all code inside the conflict area. I think a reasonable equivalent to the Git behavior would be to process the first +++++++ block, which marks a snapshot section, and ignore other blocks.

  • If the actual text of a file contains any lines that look like a conflict marker, Jujutsu will use longer markers when representing conflicts. The scanner currently hardcodes the assumption that markers are always length 7. To be strictly correct here, we'd want to remember the length of the starting marker and then require the intermediate/ending markers to be the same length, so that we don't confuse the pseudo-marker that Jujutsu detected for a real one.

It seems to me that solving either of these problems would require the scanner to maintain state about the current conflicted area, which seems sketchy given how little state it's holding now. I'm not sure what solution would align best with the intended design of the scanner.

(There is an option that doesn't require scanner-level state, which would be for scanConflictMarkerTrivia to enforce a match between the length of the marker it's processing and the next one it's scanning to. This would require some ugly Jujutsu-specific logic for <<<<<<<, since we normally don't do any lookahead for the first marker, and it would still drop all of the code instead of preserving one block, but it would at least be better than the status quo.)

cc Jake Bailey (@jakebailey)

πŸ“ƒ Motivating Example

N/A

πŸ’» Use Cases

Using Jujutsu to manage TypeScript code without having to either use the git conflict format or deal with spurious errors when fixing conflicts.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions