-
Notifications
You must be signed in to change notification settings - Fork 773
jj commands should throw a warning when the fileset does not exist
#7693
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
base: main
Are you sure you want to change the base?
jj commands should throw a warning when the fileset does not exist
#7693
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following commits do not follow our format for subject lines:
Commits should have a subject line following the format <topic>: <description>. Please review the commit guidelines for more information.
jj status should throw an error when the fileset does not existjj status should throw a warning when the fileset does not exist
14e7bbd to
84fb867
Compare
All commits are now correctly formatted. Thank you for your contribution!
84fb867 to
bea6920
Compare
fb17003 to
d6a7b86
Compare
jj status should throw a warning when the fileset does not existjj commands should throw a warning when the fileset does not exist
0eeeaac to
0c2a608
Compare
5e3fd26 to
55ab0d8
Compare
|
IMO, you should merge the revision that changes the command and the revision that adds the test for each command. It would be easier to review. |
I want to make sure that the warning is shown in a consistent manner across all commands. That's why the commands and tests are one after another. I would be happy to split the PR in whatever way is more convenient for the reviewer when ready :)
I didn't have to add tests for all the commands. Some of them already had tests capturing this behaviour, for example, |
|
nit: Could you squash the tests into the commit they're testing? See https://jj-vcs.github.io/jj/latest/contributing/#commit-guidelines |
ccb9689 to
0d8298b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
cli/src/cli_util.rs
Outdated
| // If there are no explicit paths to show then return early. | ||
| if explicit_paths.is_empty() { | ||
| return Ok(()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the benefit of this check? That should ideally be mentioned in the commit description (if it's not obvious, and it's not obvious to me at least).
Is this just an optimization? But if explicit_paths is empty, then explicit_paths.retain() will be very cheap anyway. So I don't think it's a worthwhile optimization.
Or is it about correctness when explicit_paths is empty and trees is also empty? It makes sense to not print the warning in such cases. Are you going to add callers that may pass an empty list of trees in a later commit? Could you update the commit description to explain that that's the reason if it is?
Actually, if the second thing is what it's about, I would suggest just moving the early return out of the loop. As mentioned above, I don't think it's useful as an optimization anyway. If we move it after the loop, then it will handle the case of an empty list of trees. If you do that, I would suggest actually not making it an early return but instead make the output conditional on the list being non-empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the latter. Some scenarios when a fileset_expression may evaluate to valid explicit paths but we may not have any trees to compare them against are:
- Squashing a commit into itself.
- Running
jj log -r "none()"
I will add an explanation to the commit message.
d1ffa00 to
5ffbff5
Compare
We should not display any warning if `explicit_paths` is empty. Previously, we would by-pass this check if `trees` was empty (which was incorrect behaviour).
5ffbff5 to
bf2283f
Compare
bf2283f to
ddc8109
Compare
We inline `print_unmatched_explicit_paths` when displaying the log as graph for performance reasons.
ddc8109 to
484bd5f
Compare
| } | ||
| } | ||
|
|
||
| if explicit_paths.is_empty() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional: I don't think an early return is worth it when it's skipping just a few lines and the lines are no overly long already, so I slightly prefer this:
if !explicit_paths.is_empty() {
let ui_paths = explicit_paths
.iter()
.map(|&path| workspace_command.format_file_path(path))
.join(", ");
writeln!(
ui.warning_default(),
"No matching entries for paths: {ui_paths}"
)?;
}
Ok(())| workspace_command, | ||
| &fileset_expression, | ||
| [ | ||
| // We check the parent commit to account for delete files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "delete" -> "deleted"
| let commits: Vec<Commit> = iter.commits(store).try_collect()?; | ||
|
|
||
| let trees: Vec<MergedTree> = | ||
| commits.iter().map(|commit| commit.tree()).try_collect()?; | ||
|
|
||
| print_unmatched_explicit_paths(ui, &workspace_command, &fileset_expression, &trees)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We should be able to share the inlined version of print_unmatched_explicit_paths() instead and not have to collect all commits and tress to vectors
| let commit = store.get_commit(&key.0)?; | ||
| let tree = commit.tree()?; | ||
| // TODO: propagate errors | ||
| explicit_paths.retain(|&path| tree.path_value(path).unwrap().is_absent()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we should also remove paths that are in the parent tree. Otherwise jj log <deleted file> -r <revision where file was deleted> will print the warning. However, it's expensive to calculate the parent tree for merge commits. Perhaps we can remove paths that are in any parent tree instead. That's slightly incorrect because if a file was removed on one of the parent branches of a merge commit then we won't print the warning for the merge commit even though the file wasn't changed or present in the commit. That's probably fine because the point of the warning is to detect typos and such, and if the file did exist at some point, then it's probably not a typo.
It might be good to have tests for these two cases too. To clarify, here's the second case:
$ jj log
D (empty)
|\
C| (empty)
| |
| B delete foo
|/
A add file foo
$ jj log -r D foo
# Since foo isn't present or modified in D, we should ideally print a warning but I don't think we can because it's slow
Btw, jj log is also an exception because the user can do either jj log <fileset> or jj log -r 'files(<fileset>)' (or something more complex). We will only show the warning if the fileset was passed as a positional argument, not if it was part of the revset. Not asking for any changes here, just noting this.
| ui, | ||
| &workspace_command, | ||
| &fileset_expression, | ||
| // We check the parent commits to account for delete files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "delete" -> "deleted"
| [EOF] | ||
| "); | ||
|
|
||
| let _ = work_dir.run_jj(["new"]).success(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You should be able to remove the let _ = (same in some other commits in this PR)
|
|
||
| let repo = workspace_command.repo(); | ||
|
|
||
| let root_commits: Vec<Commit> = target_expr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "root_commits" -> "commits" since they're not just the roots
| .parse_file_patterns(ui, &args.paths)? | ||
| .to_matcher(); | ||
|
|
||
| let (root_commits, root_trees): (Vec<_>, Vec<_>) = root_commits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "root_commits" -> "commit_ids" since they're the IDs
| let (root_commits, root_trees): (Vec<_>, Vec<_>) = root_commits | ||
| .into_iter() | ||
| .map(|commit| (commit.id().clone(), commit.tree())) | ||
| .unzip(); | ||
| let root_trees: Vec<MergedTree> = root_trees.into_iter().try_collect()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: probably clearer as two separate iterators:
let commit_ids = commits.iter().map(|commit| commit.id().clone()).collect_vec();
let trees: Vec<_> = commits.iter().map(|commit| commit.tree()).try_collect()?;
Closes #6556.
Checklist
If applicable:
CHANGELOG.mdREADME.md,docs/,demos/)cli/src/config-schema.json)