GitRepository `.spec.ref.commit` + `.spec.ref.branch` does not shallow clone, contrary to the docs
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 42/100
Hướng nghiên cứu
Bắt đầu với pkg/git/gogit/clone.go, đặc biệt là cloneCommit, và so sánh nó với cloneBranch, cloneTag và cloneSemVer; sau đó kiểm tra gitrepository_controller.go và docs/spec/v1/gitrepositories.md. Xác nhận hành vi hiện tại và các test liên quan trước khi quyết định phạm vi chỉ giới hạn ở tài liệu hay bao gồm cả việc clone với độ sâu giới hạn và commit fast path. Công việc được xem là hoàn tất khi hành vi được chọn đã được triển khai và ghi lại chính xác, với độ bao phủ hồi quy cho path bị ảnh hưởng.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
The v1 GitRepository docs state that combining .spec.ref.commit with .spec.ref.branch performs a shallow clone. It does not — the commit clone path never sets a depth. The combination gives you --single-branch, not --depth.
Either the docs should be corrected, or a real bounded-depth mechanism should be added. I'd argue for both, plus a third fix that is probably the biggest win (see "Skipped fast path" below).
What the docs say
docs/spec/v1/gitrepositories.md, under Commit example:
This field takes precedence over all other fields. It can be combined with
.spec.ref.branchto perform a shallow clone of the branch, in which the commit must exist:spec: ref: branch: <branch> commit: "<commit SHA within branch>"
The wording appears to date back to the v1beta2 API field comment from the gitImplementation: go-git | libgit2 era (quoted in #1017):
// Commit SHA to check out, takes precedence over all reference fields.
//
// When GitRepositorySpec.GitImplementation is set to 'go-git', this can be
// combined with Branch to shallow clone the branch, in which the commit is
// expected to exist.
What the code does
In fluxcd/pkg/git/gogit, cloneBranch, cloneTag and cloneSemVer all honour opts.ShallowClone:
var depth int
if opts.ShallowClone {
depth = 1
}
cloneOpts := &extgogit.CloneOptions{ /* ... */ Depth: depth /* ... */ }
cloneCommit has no depth variable and no Depth field in its CloneOptions at all. The only effect of also setting a branch is:
if opts.Branch != "" {
cloneOpts.SingleBranch = g.singleBranch // true by default
cloneOpts.ReferenceName = plumbing.NewBranchReferenceName(opts.Branch)
}
singleBranch defaults to true in NewClient ("Default to single branch as it is the most performant option"), and Client.clone dispatches on Commit before any other ref field, so .spec.ref.commit always routes here.
So branch + commit narrows the fetch from all branches, full history to one branch, full history. That is a real improvement over commit alone, but it is --single-branch, not a shallow clone. source-controller sets ShallowClone: true unconditionally in gitrepository_controller.go, and cloneCommit silently ignores it.
Skipped fast path
cloneCommit is also the only clone path without the LastObservedCommit short-circuit that the others open with:
if lastObserved := git.TransformRevision(opts.LastObservedCommit); lastObserved != "" {
head, err := g.getRemoteHEAD(ctx, url, ref, authMethod) // ls-remote, no clone
// ...
if head != "" && shortRef == lastObserved {
return c, nil // nothing fetched
}
}
This is visible in the controller logs. A branch- or tag-pinned GitRepository logs no changes since last reconciliation; a commit-pinned one logs artifact up-to-date with remote revision — i.e. it cloned first and only then discovered the artifact was already current.
This seems like the most valuable thing to fix: a commit pin is immutable, so polling can never discover a new revision, yet every interval pays for a full-history fetch.
Impact
Observed on a production cluster, source-controller v1.9.4:
- Three commit-pinned GitRepositories (
branch+commit+sparseCheckout) against one large monorepo,interval: 1h. - Each reconcile takes 3–4 minutes and drives the container's Go heap to its 1Gi limit. Since
GOMEMLIMITis wired tolimits.memoryin the stock manifest, Go enters continuous GC at that ceiling,/healthzmisses the Kubernetes defaulttimeoutSeconds: 1, and the kubelet restarts the container. - 49 restarts in ~6 days, every one of them
Killing: Container manager failed liveness probe. The 10sterminationGracePeriodSecondsis then too short for a clean shutdown, so the container is SIGKILLed (exit 137) without releasing its leader lease, costing another ~45s of lease expiry per restart, after which everything reconciles at once and can spike again. - A tag-pinned GitRepository against the same monorepo in the same cluster returns instantly via the fast path — useful as a control.
Not filing this as "source-controller crashes"; the resource limits are ours to tune. The point is that the documented mitigation (add branch to get a shallow clone) does not exist, so there is no way to reduce the fetch cost of a commit pin.
Proposals
- Docs: correct the Commit example —
branch+commitrestricts the fetch to a single branch, it does not make the clone shallow. - Bounded, incremental deepening: give
cloneCommita real depth-limited fetch. Start at a modest depth, and deepen incrementally (git fetch --deepen-style) until the commit resolves, falling back to full history if it is never found. In a GitOps flow the pinned commit is usually close to the branch tip, so a first attempt at a small depth would hit the overwhelming majority of the time. A user-facing knob (e.g..spec.ref.depth, or a controller flag for the initial depth) would let people tune it. - Fast path for commit pins: move the artifact-up-to-date check ahead of the clone when
.spec.ref.commitis set. If the pinned commit equals the last observed revision and the artifact is present in storage, no fetch is needed at all.
(2) and (3) are independent; (3) alone would eliminate the recurring cost for anyone pinning commits, while (2) helps the first fetch and any genuine revision change.
Versions
- source-controller
v1.9.4 github.com/fluxcd/pkg/git v0.52.0(per source-controller'sgo.mod)git/gogit/clone.gois blobb59744db03f544e46e090a1fdbd7cdd0737a731con bothgit/v0.52.0andmainat time of writing, so this is current onmaintoo.
Happy to open a PR for the docs fix, and to help with (2)/(3) if the approach sounds right.
- Ngôn ngữ chính
- Go
- Star
- 283
- Fork
- 258
- Merge trung bình
- 1 ngày 17 giờ
- Pull request đã merge (30 ngày)
- 15
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của fluxcd/source-controller
-
Improve documentation on debugging the controller locallyCó thể làm lại được @Bryandero98 đã nhận 28 ngày trước và không có pull request nào đang mở. Đang mởarea/docs good first issue help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
fluxcd/source-controller#666 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area/oci enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
fluxcd/source-controller#2180 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`OCIRepository`/cosign verification: support TSA-only trusted roots (no transparency log) for private Sigstore instances like GitHub Artifact AttestationsCó thể đã có người làm @stealthybox đã nhận 142 ngày trước. Đang mởarea/oci area/security enhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 68/100
fluxcd/source-controller#2167 · 4 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
fluxcd/source-controller#2150 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Azure Bucket: anonymous access to public containers is unreachable since #1875Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
fluxcd/source-controller#2136 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của fluxcd/source-controller
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
os: RawConn methods of a closed File return internal/poll.ErrFileClosing instead of ErrClosedĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: Bedrock invoke-with-response-stream reports `stop_reason: "end_turn"` for tool-use turnsĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
oalders/clodhopper#162 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
component/server severity/minor type/bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày