[rush] Managed Git LFS hooks conflict with reused Azure Pipelines workspaces
Los mantenedores suelen responder en 1 día
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Summary
Rush's managed Git-hook installation has two incompatible failure modes when a repository also uses Git LFS:
- If the repository does not declare the Git LFS hook names under
common/git-hooks,rush install/rush updateempties.git/hooksand removes Git LFS's canonical hooks. A latergit pushcan push LFS pointer commits without uploading the corresponding LFS objects. - If the repository does declare an LFS hook name so Rush adds its built-in LFS delegation, Rush leaves a noncanonical wrapper in
.git/hooks. Azure Pipelines checkout runsgit lfs install --local; on a reused self-hosted agent, Git LFS rejects the existing Rush wrapper and the checkout fails before repository code can run.
This is not a recent regression. I verified the same installation logic in locally available Rush versions 5.172 through 5.180.
Related history
- #3816 and #4132 introduced the current delegate-hook approach and its Git LFS chaining.
- A comment on #1042 describes intentionally ignoring
git lfs installerrors after Rush ownspre-push. That works in a setup script, but Azure Pipelines treats the same error as a fatal checkout failure. - #4247 fixed error propagation from a managed
pre-pushhook, but does not cover hook installation interoperability.
I did not find an existing issue for the combination of hook-folder clearing, missing LFS uploads, and Azure's repeated git lfs install --local.
Reproduction A: Rush removes Git LFS's upload hook
-
Create a Rush repository with at least one managed hook, for example:
common/git-hooks/pre-commit -
Configure Git LFS:
git lfs install --local.git/hooks/pre-pushis now Git LFS's canonical hook. -
Run:
rush update -
Inspect
.git/hooks.
Actual result
Rush calls ensureEmptyFolder(hookDestination) and recreates only hook names represented under common/git-hooks. The canonical pre-push, post-checkout, post-commit, and post-merge hooks are removed.
A later normal git push does not invoke git lfs pre-push, so new LFS objects are not uploaded.
Expected result
Installing Rush-managed hooks should not silently remove hooks owned by another tool, especially Git LFS's upload hook.
Reproduction B: Rush's LFS wrapper breaks Azure checkout
-
Add a placeholder such as:
common/git-hooks/pre-pushRush recognizes the name and generates a wrapper that delegates to the repository hook and then invokes:
git lfs pre-push "$@" -
Use an Azure Pipelines self-hosted agent with checkout configured for LFS.
-
Run a build job that executes
rush installorrush update. -
Reuse the same agent workspace for a later job or pipeline checkout.
Azure's checkout task runs:
git lfs install --local
Actual result
Git LFS rejects Rush's noncanonical wrapper:
Hook already exists: pre-push
#!/usr/bin/env bash
set -e
SCRIPT_DIR="..."
SCRIPT_IMPLEMENTATION_PATH=".../common/git-hooks/pre-push"
...
git lfs pre-push "$@"
To resolve this, either:
1: run `git lfs update --manual` for instructions on how to merge hooks.
2: run `git lfs update --force` to overwrite your hook.
##[error]Git-lfs installation failed with exit code: 2
The checkout fails before any repository script can repair the hook.
This was observed with Azure Pipelines agent checkout using Git LFS 3.4.1 on Linux. The repository's developer machine used Git LFS 3.7.1 and reproduced the same git lfs install --local conflict.
Expected result
A hook arrangement produced by Rush's documented installation flow should remain compatible with common checkout tooling that initializes Git LFS, or Rush should explicitly document and validate the incompatibility.
Why this is difficult to work around
- Omitting the placeholder avoids Azure's conflict but lets Rush remove LFS's upload hook.
- Adding the placeholder preserves LFS behavior during
git pushbut leaves a wrapper thatgit lfs install --localrejects. git lfs install --local --forceafter every Rush install restores canonical hooks and works when the repository has no custom implementation for those hook names, but it would overwrite legitimate custom Rush-managed hooks.- A stale wrapper on a reused self-hosted agent can break unrelated branches before they have checked out a corrective commit.
Possible direction
The most general fix may be for Rush to stop emptying the complete hooks directory:
- Track which hooks were generated by Rush.
- Replace or remove only Rush-generated hooks.
- Preserve unmanaged hooks, including canonical Git LFS hooks, when there is no same-name repository hook.
- Define and document collision behavior when both Rush and another tool manage the same hook.
- Add integration coverage for:
git lfs install --localfollowed byrush updaterush updatefollowed bygit lfs install --local- repeated Azure-style checkout/install cycles in one worktree
At minimum, the Git-hooks documentation should state that Rush empties .git/hooks, explain the special LFS-hook-name behavior, and discuss checkout tools that invoke git lfs install.
Standard questions
| Question | Answer |
|---|---|
@microsoft/rush globally installed version? |
Version selector; tested with Rush 5.180.0 |
rushVersion from rush.json? |
5.180.0 |
useWorkspaces? |
true |
| Package manager | pnpm 10.34.6 |
| Operating system | Linux |
| Node.js version | 24.18.0 |
| Git LFS versions | 3.7.1 locally; 3.4.1 in Azure Pipelines |
| Would you consider contributing a PR? | Yes |
- Lenguaje dominante
- TypeScript
- Estrellas
- 6.5k
- Forks
- 710
- Merge medio
- 1 d 13 h
- PR fusionados (30 d)
- 45
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Sin guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/rushstack
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
[rush] Upgrade the pnpm-sync-lib dependency to 0.3.5.Posiblemente ocupada @martinnaj la tomó hace 12 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
microsoft/rushstack#5971 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
microsoft/rushstack#5902 · 1 reacción ·
Los mantenedores suelen responder en 1 día
Todos los issues de microsoft/rushstack
Issues similares
-
Bayern feature:Application ready web
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
digitalfabrik/entitlementcard#3176 ·
Los mantenedores suelen responder en 7 días
-
[BUG] 运行位置的分支列表不自动刷新,外部新建的分支看不到Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
NanmiCoder/cc-haha#1533 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
🐛 Bug: Calendar work items cannot be opened on mobilePosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100