martinvonz / jj

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

Annoying executable reporting on NTFS drives in Linux #3949

Open wrzian opened 3 months ago

wrzian commented 3 months ago

I have a shared NTFS drive between Linux and Windows. In Linux I mount the NTFS drive with the 'exec' option (as default) so I can compile and run binaries. However 'exec' makes all files within the drive executable.

When I try to colocate a git repo on this drive, jj reports every file as being modified to be executable. While they all are executable, I don't want this represented as a change in the repo. Running jj chmod normal <some_file> does nothing because the drive is mounted with all files executable, and jj continues to report everything as modified to be executable.

Git has an option for this as core.fileMode.

Here is git's documentation: https://git-scm.com/docs/git-config#Documentation/git-config.txt-corefileMode

core.fileMode

Tells Git if the executable bit of files in the working tree is to be honored.

Some filesystems lose the executable bit when a file that is marked as executable is checked out, or checks out a non-executable file with executable bit on. git-clone[1] or git-init[1] probe the filesystem to see if it handles the executable bit correctly and this variable is automatically set as necessary.

A repository, however, may be on a filesystem that handles the filemode correctly, and this variable is set to true when created, but later may be made accessible from another environment that loses the filemode (e.g. exporting ext4 via CIFS mount, visiting a Cygwin created repository with Git for Windows or Eclipse). In such a case it may be necessary to set this variable to false. See git-update-index[1].

The default is true (when core.filemode is not specified in the config file).

I'm not sure how an option like this might integrate with JJ's use of executable bits in windows, but it would be nice to add some solution for filesystems on Linux that can't easily control the executable bit.

ilyagr commented 3 months ago

I think it's probably feasible to have a mode where jj ignores the executable bit of files in the worktree and jj chmod (newly renamed to jj file chmod) is the only way to set/remove the executable bit. It could be specified with jj config set --repo.

I'm surprised this is not more of a problem, actually. I'm guessing this might show up when using WSL as well. I can't decide whether this deserves a Windows tag, but I guess it ultimately does since it's Windows filesystems that don't have an executable bit.

martinvonz commented 3 months ago

Sounds like we should replace the current compile-time switches between Windows and Unix by a runtime switch, which would then always be false on Windows and read from config on Unix.

@wrzian, if you're interested in implementing it, see how it's currently done in https://github.com/martinvonz/jj/blob/main/lib/src/local_working_copy.rs. Just search for "executable" there. We would probably want to pass the config into LocalWorkingCopyFactory.

martinvonz commented 3 months ago

We would probably want to pass the config into LocalWorkingCopyFactory.

Actually, that will make it harder to initialize it because we typically don't have the settings available when we want to initialize the LocalWorkingCopyFactory. So maybe we'll need to pass &UserSettings to init_working_copy() and load_working_copy() instead.

glencbz commented 1 week ago

FYI @ilyagr you're right, it is a big problem in WSL because the canonical way to access Windows OS files from WSL is via /mnt/, which is all executable by default, so this is super annoying when the repo lives in Windows but you open it in WSL.

My guess is that most users don't mix WSL and Windows on a single repo. I certainly don't.