Repository navigation
[rush] rush git-hooks edge case #3816
Description
Summary
Background: our team is migrating husky to rush git-hooks, and we found an edge case with current rush git hooks implementation. So, this PR reports the edge case and proposes a alternative git hooks implementation.
Repro steps
Assuming the repo maintainer wants to add a "rush prettier" to "pre-commit" git hooks. So the maintainer follows the official doc:
- Add a
rush prettiercustom command - Use
rush prettierincommon/git-hooks/pre-commit.
Ok. Push and merge it to the main branch. Everything seems fine now.
Actually, users may run into an issue that the following issue throws:
rush: error: argument "<command>": Invalid choice: prettier (choose from ....
Details
Let's say we got the following git branches with their commit history:
- branch
main: A -> B(rush prettier + pre-commit) - branch
feat-1: B -> C (checkout from main when the latest commit is B) - branch
feat-2: A -> D (checkout from main when the latest commit is A)
And B is the commit for rush prettier in pre-commit.
Now. Users checkout to feat-1, rush update to sync the git hooks to .git folder and correctly run pre-commit with rush prettier
And then, checkout to feat-2, modify a readme file, and run git commit -m 'xxx', which triggers pre-commit hooks. BOOM, there is no rush prettier defined in branch feat-2.
Possible solution
Instead of syncing files from common/git-hooks to .git/hooks, how about setting core by running git config core.hooksPath common/git-hooks
Similar logic in Husky at https://github.com/typicode/husky/blob/9efb720c165ffcfec774b4584aa61f59dae774c7/src/index.ts#L49
Standard questions
Please answer these questions to help us investigate your issue more quickly:
| Question | Answer |
|---|---|
@microsoft/rush globally installed version? |
5.86.0 |
rushVersion from rush.json? |
5.86.0 |
useWorkspaces from rush.json? |
Yes |
| Operating system? | Mac |
| Would you consider contributing a PR? | Yes |
Node.js version (node -v)? |
14 |
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsClosed
Activity
[-][rush] [/-][+][rush] rush git-hooks edge case[/+]stekycz commentedon Dec 16, 2022
We have the same case in our repo. We have solved it by using script like the following to refer to actual implementation. This file lives in
common/git-hooks/pre-commit.I am sure it can be improved and generalized. However, I would expect this layer to be handled by Rush.js instead of making all Rush.js user do it on their own.
Faithfinder commentedon Dec 19, 2022
Relevant: #3004
Personally, I don't like the idea of tools configuring each other. Rush configuring git feels wrong.
iclanton commentedon Dec 21, 2022
Martin Štekl (@stekycz) - That seems like a good approach. It feels safer than overriding
core.hooksPathbecause that would blow away hooks not handled by Rush.Would you or Cheng Liu (@chengcyber) be interested in putting that together? It probably wouldn't be too difficult.
stekycz commentedon Jan 5, 2023
Ian Clanton-Thuon (@iclanton) I have just created the PR
chengcyber commentedon Jan 11, 2023
I think the solution from Martin Štekl (@stekycz) covers the case when a new git hook file introduced in Monorepo. but there are cases that the repo maintainer introduces a new rush command in the existing git hook(such as pre-commit).
Like the edge case i described in the issue content, the error actually is
rush: error: argument "<command>": Invalid choice: prettier (choose from ..... User syncs.git/hooks/pre-commitfrom the master branch, and later he/she checkout to the branch whererush prettieris not introduced. In this branch, runninggit committhrows the error.stekycz commentedon Jan 11, 2023
Cheng Liu (@chengcyber) I do not think that is a problem. The script installed to yours
.git/hooks/pre-commitwill refer the script in your repo version. Therefore, when you change a branch in which the prettier is missing, it should be missing in the hook script as well.chengcyber commentedon Jan 12, 2023
That's not always true. because developer needs to run
rush updateorrush installto sync the script into.git/hooks/pre-commit.What if one checkout to the branch and modify readme file, so he/she doesn't need to run
rush updateto install deps.stekycz commentedon Jan 12, 2023
Cheng Liu (@chengcyber) You will not need to run
rush installorrush updateanymore to get updated Git hooks. The Git hook script installed in.git/hooksis the dummy one. So it remains the same among all revisions no matter what (possibly except update of the script template in Rush.js itself). It will execute the target script only. The target script will change accordingly to Git revision.chengcyber commentedon Jan 12, 2023
Yes. I check your proposal again. and i misunderstood it. You solution cover my edge case 👍