Move the key-splitting, resource-fetching, and not-found handling into a
generic internal.NewReconciler wrapper so that each reconciler only
implements ReconcileKind(ctx, *TypedResource) — matching the Knative
generated reconciler convention. The controller setup wraps the
reconciler with internal.NewReconciler, which bridges Reconcile(ctx, key)
to ReconcileKind(ctx, *T).
This removes duplicated boilerplate from all three reconcilers (push,
sync, resolver), eliminates their Reconcile/LeaderAware methods, and
makes splitKey an unexported implementation detail.
https://claude.ai/code/session_01Eu3LyxX3G1KCcw4aDzmHvp
- Extract triplicated splitKey into shared pkg/reconciler/internal package
using strings.Cut and removing the unnecessary error return
- Fix resolver merge bug: attemptMerge was using treeA.Hash as the merge
commit tree, silently dropping all of branch B's changes. Now builds a
proper merged tree that applies B's non-conflicting changes onto A's tree
- Replace hand-rolled nestedFieldNoCopy/unstructuredNestedStringMap with
k8s.io/apimachinery's unstructured.NestedStringMap stdlib equivalent
- Hoist branch listing out of per-refspec loop in updateBranches to avoid
redundant API calls
- Add not-found handling in all three reconcilers so deleted resources
don't cause infinite requeue loops
- Fix client.Get() to use checked type assertion with a clear panic message
instead of an opaque nil-pointer dereference
- Remove dead code: unused addDefaultingFuncs wrapper, unused context
injection in push controller setup
https://claude.ai/code/session_01634JRpHEoM9FzuBjZ7qHcY
Add unit tests for all packages that previously had zero test coverage:
- pkg/apis/git/v1alpha1: defaults, deepcopy, scheme registration, constants
- pkg/client: toUnstructured/fromUnstructured round-trips, context injection
- pkg/reconciler/push: splitKey, nestedFieldNoCopy, unstructuredNestedStringMap, base64 decoding
- pkg/reconciler/sync: splitKey
- pkg/reconciler/resolver: splitKey, changeName
Add e2e test exercising the sync controller:
- Creates second Gitea repo and GitRepository CR
- Creates GitBranch CRs with headCommit set via status subresource patch
- Creates GitRepoSync CR and verifies the sync controller processes it
https://claude.ai/code/session_01QfFzqKQUsxxBsiZUhuJ3pG
The Knative reconciler.LeaderAware interface requires:
Promote(Bucket, func(Bucket, types.NamespacedName)) error
Our code had the wrong enqueue function signature using
(Bucket, string) error instead.
https://claude.ai/code/session_01QfFzqKQUsxxBsiZUhuJ3pG
Build a complete Kubernetes control plane for Git operations using Knative's
pkg framework, go-git for in-memory Git operations, and ko for builds.
Architecture:
- 4 CRDs: GitRepository, GitBranch, GitPushTransaction, GitRepoSync
- Push controller: atomic Git push via go-git with CAS (compare-and-swap)
- Sync controller: two-way sync with in-memory merge base calculation
- Resolver controller: automated 3-way merge for conflicted syncs
- In-cluster Gitea server for backing storage
- Full RBAC, ko-based deployments, and code-gen scaffolding
Note: go.sum needs generation via `go mod tidy` in an environment with
full internet access (knative.dev/pkg v0.0.0-20250520014526-44579e9ce5ed).
https://claude.ai/code/session_01QfFzqKQUsxxBsiZUhuJ3pG