Resolve vendor/ conflicts during a merge, rebase, or dependency upgrade on main or release branches
Use this skill when resolving conflicts in vendor/ during a merge, rebase, or dependency upgrade.
Ask the user: are you working on the main branch or a release branch? The answer changes what kinds of fixes are acceptable (see below).
Guides the process of diagnosing and resolving vendor directory conflicts caused by dependency changes — whether a direct bump or a transitive cascade.
Never patch vendor/ files manually. CI runs go mod vendor and will overwrite any manual patches. All fixes must come from upgrading or pinning the upstream dependency to a version that has the fix already.
Always run the pre-commit checklist before committing anything:
go mod tidy
go mod vendor
go build -mod vendor ./...
go test -mod vendor -run ^$ ./...
go run pkg/docsgen/generate_manifest.go
All must pass with no errors. If generate_manifest.go produces changes, commit them:
git add docs/sources/tempo/configuration/manifest.md && git commit -m "manifest.md"
go build catches compile errors in production code; go test -run ^$ catches compile errors in test and integration files. Run these after every change — dependency upgrades, cherry-picks, and manual fixes alike — before staging and committing.
git diff go.mod
Note which module(s) were bumped. A single bump (e.g. grpc) often cascades into failures in transitive dependencies.
Main branch has almost always already solved the problem. Find relevant commits:
git log --oneline main | grep -i "<module-name>"
# Check what dependency versions main used at a given commit
git show <commit-sha>:go.mod | grep -E "<module-name>|<related-module>"
# Inspect a specific vendor file at a commit
git show <commit-sha>:vendor/<path/to/file.go>
Use main as the source of truth for what versions to target and what code changes are needed.
go mod tidy
This will either succeed or tell you exactly what is missing or mismatched. Read the error trace carefully — it shows the import chain that led to the conflict.
For each error go mod tidy surfaces:
Always check main at the relevant commit before writing new code:
git show <commit-sha> -- <path/to/file.go>
go mod tidy
go mod vendor
Both must exit 0. If go mod vendor fails with a missing package, try go mod download first, then re-run vendor.
After vendoring, confirm that your fixes are present in vendor/ as real upstream code — not patches:
grep -A5 "<relevant symbol>" vendor/<path/to/file.go>
If you only see a stub or Unimplemented* type, the module version is too old. Upgrade to a newer one.
go build -mod vendor ./...
This compiles every package in the repo, not just the main binary entrypoint. make tempo only builds cmd/tempo and will miss compile errors in other packages (e.g. modules/distributor). Always use ./... to catch issues across the full project.
go build does not compile _test.go files. Run this to catch errors in test code too:
go test -mod vendor -run ^$ ./...
The -run ^$ flag matches no test names, so no tests execute — it only compiles. Test files often contain mock types that implement interfaces, and a dependency upgrade that adds a method to an interface will break those mocks without showing up in go build.
If new failures appear, find the commit on main that introduced the fix and evaluate whether to cherry-pick or fix manually (see below).
Also run this specifically for integration test directories, which are often missed:
go test -mod vendor -run ^$ ./integration/...
Ask the user if they want to run broader test coverage (e.g. make test, make test-e2e). These take a long time and are not required for every commit, so only run them if the user confirms.
If new errors appear after any step, loop back to step 3 (go mod tidy) and work through the errors again. Cascading dependency conflicts often require multiple passes.
Prefer cherry-pick when:
Prefer a manual fix when:
When making a manual fix on a release branch, keep it to the absolute minimum needed to satisfy the compiler. This only applies to test mock types in _test.go files — never to production code. Typically a stub that panics, matching the pattern of other unimplemented methods in the same mock type:
func (r mockRing) GetSubringForOperationStates(_ ring.Operation) ring.ReadRing {
panic("implement me if required for testing")
}
If you cherry-picked a commit and later discover it brought in too much, revert cleanly and apply the manual fix instead:
git revert --no-commit <cherry-pick-sha> [<follow-up-sha> ...]
git commit -m "revert: undo cherry-pick of <sha> (<reason>)"
# then apply the minimal fix manually
After all changes are in, regenerate the configuration manifest so the docs stay in sync with the actual config:
go run pkg/docsgen/generate_manifest.go
This updates docs/sources/tempo/configuration/manifest.md. Commit the result if anything changed:
git add docs/sources/tempo/configuration/manifest.md && git commit -m "manifest.md"
When one module is bumped, look for these patterns:
replace directive in go.mod pins a fork to an old version that's incompatible with the new dep → update the replace directivego mod tidy resolves test dependencies too; a module's tests may import an internal package that was removed in a newer version → upgrade that module to a version where its tests no longer import the removed packageManual code changes are acceptable — if a dependency upgrade requires updating an interface implementation, a function signature, or call sites in this repo, go ahead and make those changes directly.
Do not make manual production code changes. A release branch should only receive targeted backports, not new hand-written source changes driven by dependency upgrades. Instead, find the commit on main that already contains the fix and cherry-pick the relevant source file changes from it.
The one exception is a minimal test-only compatibility stub in a _test.go file when no suitable fix exists on main and the change is required solely to satisfy the compiler for test code. Keep it to the absolute minimum — avoid changing runtime behavior.
For each module that requires a code fix:
Identify which module is causing the issue and what version change triggered it (e.g. github.com/grafana/gomemcache v0.0.0-20250228 → v0.0.0-20251008 added ctx to GetMulti).
Use git log -L to trace commits on main that touched that module's line in go.mod:
git log --oneline -L '/github.com\/grafana\/gomemcache/,+1:go.mod' main
Walk backwards through the commits. The most recent commit touching that line may not have the fix — go one or two commits earlier. Look for a commit whose description mentions an interface or signature change (not just a version bump).
Verify the commit has the fix you need:
git show <commit-sha> -- <path/to/file.go>
Commit the go.mod/vendor changes first, then do a regular git cherry-pick (no --no-commit). This preserves the original commit message and author, making it clear to PR reviewers that the source code changes were cherry-picked from main rather than written manually.
# 1. Commit all the go.mod, go.sum, and vendor/ changes first
git add -A && git commit -m "chore(deps): update <modules>"
# 2. Cherry-pick — this will pause on conflicts
git cherry-pick <commit-sha>
The cherry-pick will conflict on go.mod, go.sum, and vendor/ — because we already have the newer versions from step 1. Keep ours for all of those. The source file changes (interface implementations, call sites) will usually auto-merge cleanly.
For any new doc or config files added by the dep upgrade (e.g. a generated config manifest), take theirs — these reflect the new capabilities of the upgraded dependency.
# Keep our go.mod/vendor (already up to date)
git checkout --ours go.mod go.sum vendor/modules.txt vendor/<affected-module>/
# Take theirs for any newly added doc/config files
git checkout --theirs docs/sources/tempo/configuration/manifest.md
# Stage the resolved files
git add go.mod go.sum vendor/modules.txt vendor/<affected-module>/ docs/...
# Verify no conflicts remain, then continue
git diff --name-only --diff-filter=U # should be empty
git cherry-pick --continue --no-edit
The resulting commit will carry the original message and author from main, e.g.:
Update dskit and adjust memcached interface signature (#5604)
Author: Zach Leslie <[email protected]>
go mod tidy error trace is the best guide to what needs fixing — read it fully before acting