
uv sync 默认不会自动更新 Git 依赖的远程代码;需结合 --upgrade 标志触发锁文件升级与依赖重同步,才能确保本地安装的 Git 包(如 git+https://...)拉取最新提交并生效。
`uv sync` 默认不会自动更新 git 依赖的远程代码;需结合 `--upgrade` 标志触发锁文件升级与依赖重同步,才能确保本地安装的 git 包(如 `git+https://...`)拉取最新提交并生效。
在 Python 项目中通过 Git URL 声明依赖(例如 git+https://github.com/PowerInsight/quantstats.git)是一种常见且灵活的做法,尤其适用于尚未发布到 PyPI 的内部库、正在积极开发的上游组件,或需要定制化分支/提交的场景。然而,一个关键误区是:uv sync 本身并不“感知”远程 Git 仓库的变化——它严格遵循 uv.lock 文件中记录的精确 commit hash 或 ref(如 branch、tag),仅做“一致性同步”,而非“动态更新”。
? 为什么 uv sync 不会自动 git pull?
uv 的设计哲学强调可重现性(reproducibility):uv.lock 是权威来源,它固化了每个依赖的完整解析结果,包括 Git 依赖的精确 commit SHA(即使你声明的是 --branch main)。当你执行 uv add git+... --branch main 时,uv 实际会在 uv.lock 中记录该分支当前 HEAD 对应的 commit,而非一个持续跟踪的“活引用”。因此:
- 后续
uv sync仅校验并安装uv.lock中指定的 commit; - 即使远程
main已推进新提交,uv.lock不变 →uv.sync不会拉取新代码; - 手动修改
pyproject.toml中的 Git URL 或添加cache-keys等配置,无法绕过锁文件机制,因为uv的同步行为完全由uv.lock驱动。
✅ 正确做法:两步走,保障 Git 依赖实时生效
要让本地环境反映 Git 仓库的最新变更,必须显式触发锁文件更新,再同步:
步骤 1:升级锁文件(获取最新 commit)
uv lock --upgrade-package quantstats
或全局升级所有 Git 依赖:
uv lock --upgrade
✅
uv lock --upgrade会重新解析所有依赖,对 Git 源执行git fetch并更新uv.lock中对应的 commit hash(例如将main分支解析为最新的 SHA)。这是唯一可靠的方式。
步骤 2:同步环境(安装新 commit)
uv sync
✅ 此时
uv.lock已含新 commit,uv sync将卸载旧版本、克隆/检出新 commit,并重新安装(支持增量,速度快)。
? 快捷方案:一步完成
直接使用 uv sync --upgrade,它等价于先运行 uv lock --upgrade 再执行 uv sync:
uv sync --upgrade-package quantstats # 仅升级 quantstats # 或 uv sync --upgrade # 升级所有可升级依赖(含 Git)
⚠️ 注意事项与最佳实践
-
不要手动编辑
uv.lock:Git 依赖的 commit 字段由uv lock自动生成和维护,手动修改易导致哈希校验失败或行为不一致。 -
避免
--reinstall替代--upgrade:uv sync --reinstall会强制重装所有包,但不会更新uv.lock中的 commit,因此 Git 依赖仍指向旧版本。 -
分支 vs. Commit vs. Tag:
- 使用
--branch main→ 锁定当前mainHEAD,需--upgrade更新; - 使用
--rev <commit-sha></commit-sha>→ 锁定特定 commit,永不自动更新(最稳定); - 使用
--tag v1.2.0→ 锁定 tag,需--upgrade才能切到新 tag。
- 使用
-
CI/CD 场景建议:在自动化流程中,始终将
uv lock --upgrade作为前置步骤(配合--upgrade-package精准控制),再执行uv sync,确保构建环境与最新源码一致。
? 验证是否生效
同步完成后,检查 uv.lock 中 quantstats 条目是否已更新 commit:
[[package]]
name = "quantstats"
version = "0.0.0"
source = { git = "https://github.com/PowerInsight/quantstats.git", subdirectory = "", rev = "a1b2c3d4..." } # ← 新的 SHA
同时确认 .venv/Lib/site-packages/quantstats/ 下的文件内容已同步至最新提交。
总之,uv sync --upgrade 是解锁 Git 依赖动态更新的关键指令——它既保持了 uv 对可重现性的坚守,又提供了开发者所需的敏捷性,真正实现“声明即同步,升级即生效”。











