martinvonz / jj

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

FR: Support `.ignore`/`.jjignore`, a Git Independent way to ignore files. #3525

Open PhilipMetzger opened 5 months ago

PhilipMetzger commented 5 months ago

Is your feature request related to a problem? Please describe.

At some point we won't have Git as a base system anymore, which means we'll some way to migrate to a new .ignore file. It either could be a custom .jjignore or .ignore if it doesn't conflict with other tools you're using.

Describe the solution you'd like Add support for a .jjignore/.ignore file which can be adjacent to the .gitignore and a way to migrate the .gitignore to it (should be hopefully just a name change).

Describe alternatives you've considered Support .gitignore forever, which also could work, but I'd really like Git to be gone.

joyously commented 5 months ago

While adjacent, the jj one would have .git in it while the git one would have .jj in it.

FYI, I tried (but was unsuccessful) to get Pijul's file to change from .ignore to something specific to Pijul. I think all of the meta info for a tool should be able to be addressed with a glob.

A plain .ignore is not as future proof.

thoughtpolice commented 5 months ago

While adjacent, the jj one would have .git in it while the git one would have .jj in it.

Note that you don't need to add .jj to a .gitignore today because when jj automatically adds .jj/* to the special .git/info/exclude file.

ilyagr commented 5 months ago

Note that you don't need to add .jj to a .gitignore today...

+1

...because when jj automatically adds .jj/* to the special .git/info/exclude file.

This actually changed slightly. jj now creates a .jj/.gitignore instead.

necauqua commented 5 months ago

A plain .ignore is not as future proof.

I kind of.. did not understand your message here. Why?

I've mentioned previously that creator of the ignore crate (and ripgrep) is pushing for a unified .ignore (which is just a .gitignore that's not specific to git) file that's recognized by various tools and I like the idea a lot. So I'd be in favor of .ignore file compliant with that instead of making yet another .somethingignore file.

joyously commented 5 months ago

I've mentioned previously that creator of the ignore crate (and ripgrep) is pushing for a unified .ignore

I haven't seen that remark. I suppose it doesn't matter that all the VCSs would be listed in one file. That's what would be intended anyway. I haven't thought about it as much as the crate author, but when I wrote that about future proofing, I was thinking in terms of a future maintainer that doesn't really know the old tool so wouldn't know that generic .ignore goes with it, and also mixing ignore files from VCS and some other kind of tool like backups or encryption or something else not written yet.

dbarnett commented 1 month ago

I see two possible approaches here:

  1. jj only respects .ignore in its own operations
  2. jj attempts to bridge the gap with git and other backends to help them ignore the same files it's ignoring

Option 1 is easy but seems like it'll just tend to infuriate users in cases like colocated repos, where different VCS tools have to be taught separately to ignore files. Option 2 seems nicer but really finicky to get right.

PhilipMetzger commented 1 month ago

I think the second approach is the right one, as it allows a seamless transition from the Git backend to the future native backend, or any custom one if there's one downstream.

dbarnett commented 1 month ago

SGTM, but does that imply that a .ignore file in jj's store would get reflected with a different filename in a git workspace? And would colocated repos end up with .ignore and .gitignore side-by-side?

Also FYI might require some changes in the ignore crate to support more involved inspection/reflection of the ignore specs.

PhilipMetzger commented 1 month ago

SGTM, but does that imply that a .ignore file in jj's store would get reflected with a different filename in a git workspace?

I don't think so, as for Git it just is a auxiliary file, in the worst case it could get added to the .gitignore itself, like how we exclude the .jj in colocated repositories.

And would colocated repos end up with .ignore and .gitignore side-by-side?

Probably, that means there should be a repo level config knob to prioritize one of them. Although we should give our .ignore priority by default.

joyously commented 1 month ago

I think we should do away with the ambiguous states of tracked/ignored and untracked/not ignored.

it could be that you keep ignores as is, but make the track and untrack command update the ignore file.

could you expand on it?

The docs were stating that with a new config to disable auto-track, you have to edit the ignore file after using track or untrack. What are these commands doing if the ignore file is unchanged, and is it different with or without auto-track? Are there really valuable states with the combination of "tracked", "untracked", and "ignored", or is it just one variable with two states: ignored/tracked ? There is a race condition when you have to store the state in two places. It seems to me that the command should bring up the ignore file in the editor, so the user can edit it. I think you have to define what "ignore" means first (see below). My concern with the disabling of auto-track is the file deletion on undo. If a file is ignored, it should never be touched. (What if the file in question is the .gitignore?)

Here are some links to Git and Breezy docs for their ignore handling: Git has add and the index, clean removes untracked files, gc can affect files, rm removes files, and config to set options. In the doc for gitignore, it says

A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected; see the NOTES

Breezy has add (no index), clean-tree removes unknown files, ignore to update ignore list (creates .bzrignore if doesn't exist), ignored to list ignored files, remove to remove files, and config to set options. In the doc for ignoring, it says

Note that ignore patterns are only matched against non-versioned files, and control whether they are treated as “unknown” or “ignored”. If a file is explicitly added, it remains versioned regardless of whether it matches an ignore pattern.

I don't know Mercurial, but here's a page on file handling, with Permanently ignoring unwanted files near the bottom.

PhilipMetzger commented 1 month ago

I thought a bit more about unifying untracked/ignored file states the last two days and think that the only option for it is in a VFS, where in each workspace only has the current files available.

What are these commands doing if the ignore file is unchanged, and is it different with or without auto-track?

The only semantic difference for jj is that track will allow the snapshotting of otherwise ignored files. Ideally there should be no difference between untracked/ignored but future and current users will need to adapt to it.

Are there really valuable states with the combination of "tracked", "untracked", and "ignored", or is it just one variable with two states: ignored/tracked ?

I think this assessment is correct, that it only should be one state and the third state is here for broader adoption. I'd still like to remove it at some point when the world gets used to having a clean repository.