martinvonz / jj

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

`jj split` of a newly added executable file does not commit file as executable #3846

Open spectral54 opened 3 months ago

spectral54 commented 3 months ago

Description

Steps to Reproduce the Problem

$ jj git init
$ echo hi > executable_file && chmod +x executable_file
$ echo hi > other_file
$ jj split        # pick only executable_file
$ jj status
Working copy changes:
M executable_file
A some_other_file
Working copy : ysmvmwqx edefcfd6 (no description set)
Parent commit: zosvqltr 1fca1963 Commit executable file
$ jj diff
Non-executable file became executable at executable_file:
Added regular file some_other_file:
        1: hi

Expected Behavior

Files committed via jj split should also commit their metadata changes (such as +x).

Actual Behavior

The file contents are committed, but not the metadata

Specifications

martinvonz commented 3 months ago

@arxanas: What are we supposed to pass into scm-record in this case? We currently don't add a mode section if the file was absent on one side because we intended for the mode from the other side to be preserved, but that does happen here. Is File::file_mode supposed to indicate the file mode on the "before" side of the diff (i.e. absent in this case)? In that case we'll have to keep track of the new mode in the integration in jj-cli. Or are we supposed to set File::file_mode to the "after" state (i.e. executable in this case)?

arxanas commented 2 months ago

Here is the documentation for File::file_mode:

The Unix file mode of the file (before any changes), if available. This may be rendered by the UI.

This value is not directly modified by the UI; instead, construct a Section::FileMode and use the [FileState::get_file_mode] function to read a user-provided updated to the file mode function to read a user-provided updated to the file mode.

@martinvonz I think it's the "before" case you're describing, so the file mode doesn't appear in the "after" version.

What the caller was "supposed" to do is always have a FileMode section for newly-created (or newly-deleted) files. The user could choose to include the file mode change in their selection or not.

Maybe scm_record should support certain implication rules, or maybe there's a better design that I haven't thought of. One possibility is to not allow line-wise selection for newly-added or newly-deleted files (which might be what hg crecord does?).

Also, maybe scm_record trying really hard to preserve/maintain the "before" file mode is misguided anyways 🙃. It might be better to include only opaque caller-supplied metadata, or just force the caller to handle it out-of-band.