-
Notifications
You must be signed in to change notification settings - Fork 14k
Modify the pre-push githook to run Tidy on only committed changes. #147084
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
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
src/etc/pre-push.sh
Outdated
| if [ -n "$(git status --porcelain)" ]; then | ||
| echo "Stashing local uncommitted changes before running Tidy." | ||
| # Stash uncommitted changes so that tidy only checks what you are going to push. | ||
| git stash push -u -q |
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.
I think that doing anything with untracked files might be a bit dangerous. I personally wouldn't want these scripts ever touching anything untracked by git.
|
So I think the best way to avoid stashing untracked files would probably be to have I did a little bit of digging anyways, and don't really think stashing untracked is extra dangerous though. Stash is basically all or nothing so on failure the working dir won't be affected. And once stashed it's still a commit under the hood so it's recoverable even if you explicitly drop the stash. But it is still stored locally, so there's always some risk I suppose. Just a note that Another option that could work well is throwing in a prompt asking if you want to stash changes before continuing. So if you're really worried you can back out and handle it manually if you prefer. I think it'd still have to include untracked unless you changed |
|
☔ The latest upstream changes (presumably #147118) made this pull request unmergeable. Please resolve the merge conflicts. |
|
I think there are two approaches that we could do here:
I would very much prefer the second solution, if we figure out that it's doable. |
|
So I looked into this a bit and option 2 seems doable. There's already a I think setting tidy to ignore untracked files as the default and adding an optional flag to include untracked is an option and a bit more user-friendly but adds some complexity. It's plausible people want to check untracked files and having to I think keeping the stash in the bash script makes sense and just remove the |
|
I agree that ignoring untracked files by default is a good idea, I often run into tidy errors because I have a bunch of crap laying on my disk in the source root 😆 When we do that, we might as well ignore uncommitted files in the git index, but this only makes sense in the pre-push hook. Still unsure about the stashing though, I think that some people (myself included) might be unhappy about the hook messing with their git state. I asked about this on our Zulip. |
added error handling for git stash and apply fix tidy err abort if stash push fails fix tidy errors... again
72aaf67 to
5bb1bc3
Compare
|
The list of allowed third-party dependencies may have been modified! You must ensure that any new dependencies have compatible licenses before merging.
This PR modifies If appropriate, please update |
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
|
A bit of an explanation for some of this. I ended up taking some advice from this Zulip thread to get file content from git for running the pre-push tidy check on content from the latest commit. So basically if you pass the Changed tidy to only run on tracked files. But added a flag I consolidated Previously for How would I go about testing something like this? I could add some unit tests, but I'm more worried about something like the CI generating files that should be checked but are untracked. I'd just like to know that no checks are being skipped unexpectedly, but not sure how I could get that kind of info. |
|
And seeing the CI fail because I modified the walk function signature makes me wonder if maybe there's a better way. Can use the filter for untracked, but it's pretty tedious to manually update for every check and in the case of Quick fix would be to make |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I merged the I'm struggling a bit to find a good way to test some of this stuff. I thought I could do tempfiles to basically check the I also ran into an issue I'm not quite sure about. When using |
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.
Whoa, that's a lot of changes! Could you please split this into:
- A PR that only adds the tidy flags (that would only store
blessfor now), and propagate the tidy context through tidy? That is most of the mechanical changes in the PR. - A PR that adds
--include-untracked?
I'm less sure about the pre-push thing, but we can do that in a third PR.
I don't think that we need to test this in some special way, because tidy already doesn't have a lot of tests. We have some infra in bootstrap to run tests with mocked git contents, but it wouldn't be trivial to add tidy support for that, I think.
|
|
||
| let untracked; | ||
| if let Ok(Some(untracked_files)) = get_git_untracked_files(Some(root_path)) { | ||
| untracked = format!("--exclude={}", untracked_files.join(",")); |
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.
Does this also work with directories?
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.
Yeah, this does work with directories. There's already a big ignore list in tidy/config/ruff.toml
|
|
||
| #[derive(Clone, Default, Debug)] | ||
| pub struct TidyFlags { | ||
| pub bless: bool, |
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.
Could you please add doc comments on top of these fields to explain what do they do?
| _ => HashSet::new(), | ||
| }; | ||
|
|
||
| flags.pre_push_content = pre_push_content; |
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.
Umm, I don't like storing these things in the flags. If we want to cache them, I'd put them into the tidy context.
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.
So one issue here is other tools using tidy's walk function. The new TidyCtx (old DiagCtx) cannot be very neatly initialized to pass into functions using walk outside of tidy. Going back to an Option<&TidyCtx> would be the easiest. So would look like:
struct TidyCtx {
diag_ctx: ...
tidy_flags: TidyFlags,
tidy_git_ctx: TidyGitCtx,
}| pub struct DiagCtx(Arc<Mutex<DiagCtxInner>>); | ||
| pub struct TidyCtx { | ||
| diag_ctx: Arc<Mutex<DiagCtx>>, | ||
| pub tidy_flags: TidyFlags, |
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.
Let's make that a method accessor to avoid changing the flags after being created.
I think this is a fairly simple solution for #125654. The basic idea is just to stash local changes, run tidy, and then pop the changes back after Tidy runs for the pre-push git hook. It sort of got a bit more complicated with the error handling, but still seems like a reasonable solution.
A few things to note:
I opted to fail the whole check if
git stash push -ufails instead of continuing to run Tidy on the unstashed changes. My thinking isgit stashdoesn't really fail easily so if it does something is probably pretty wrong and this way there's no inconsistency on what is being checked.In general I think it's unlikely for
git stash applyto fail because Tidy does not actually change files during its checks so there shouldn't be any risk of merge conflicts. If it does fail, it's a bit of a pain for the user, but handled and nothing is lost.