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

conflicts: allow missing newlines at end of file (based on [noeol] marker) #5181

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

scott2000
Copy link
Contributor

@scott2000 scott2000 commented Dec 24, 2024

Fixes #3968 (this is an alternative to #4088). This is a rough draft of one possible solution. It's similar to what @yuja proposed with adding the "noeol" indicator to the comment part of the conflict marker, but I only added it to the <<<<<<< start marker. I think this makes the materialization and parsing easier since we don't need to handle adding markers for both the removes and adds in %%%%%%% diff sections, but I'm open to comments and other approaches.

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added tests to cover my changes

@scott2000 scott2000 force-pushed the conflict-missing-newline branch from 9c2adc1 to 44f1b0d Compare December 24, 2024 18:25
@yuja
Copy link
Contributor

yuja commented Dec 25, 2024

Another option is to reconstruct the missing eol state from the original tree. Something like, if the last parsed hunk is a conflict, check if the corresponding file content had newline at end, if not, strip newline from the parsed content.

@scott2000 scott2000 changed the title conflicts: allow missing newlines at end of file conflicts: allow missing newlines at end of file (based on [noeol] marker) Dec 25, 2024
@scott2000
Copy link
Contributor Author

Another option is to reconstruct the missing eol state from the original tree. Something like, if the last parsed hunk is a conflict, check if the corresponding file content had newline at end, if not, strip newline from the parsed content.

Yeah, that could also work. I made a separate PR with a possible implementation of that here: #5186. It's definitely a lot simpler, but it does have the downside that it's no longer possible to compare the changes to the EOL state between the sides by looking at the materialized file.

@scott2000 scott2000 force-pushed the conflict-missing-newline branch from 44f1b0d to 0c2528a Compare December 25, 2024 23:09
Using a chain of methods on `ConflictMarkerLine` will make it easier to
add a method for setting a `no_eol` flag on a conflict marker in the
next commit.
Currently, conflict markers are materialized in a format that cannot be
parsed if a conflict appears at the end of the file, and there is a
non-empty line which doesn't end with a newline character. To fix this
issue, we can add an extra newline to every term of the conflict when
this occurs and then ignore the added newlines when parsing the
conflict. To ensure unambiguous parsing, we can add a "[noeol]" tag to
the start conflict marker (`<<<<<<<`) when this occurs.

I think this is a good solution to the problem because it should remain
understandable to users even if they aren't familiar with file
encodings. Many editors represent newlines at the end of files by
showing an empty line at the end of the editor, so it should be
intuitive that a term ending with an empty line represents a newline,
while a term that doesn't end with an empty line represents the lack of
a newline. Also, adding a newline to every term of the hunk is easier
than keeping track of which terms have added newlines and which don't,
so it makes materialization/parsing easier.

For instance, a conflict with terms `["left\n", "base", "base\nright"]`
would look like:

```
<<<<<<< Conflict 1 of 1 [noeol]
+++++++ Contents of side jj-vcs#1
left

%%%%%%% Changes from base to side jj-vcs#2
 base
+right
>>>>>>>
```
@scott2000 scott2000 force-pushed the conflict-missing-newline branch from 0c2528a to af4e2d2 Compare December 26, 2024 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conflicts at the end of files that don't end in a newline are not materialized correctly
2 participants