Skip to content

Fix shallow file scans when merge base objects are missing#4900

Open
lawrence3699 wants to merge 1 commit intotrufflesecurity:mainfrom
lawrence3699:fix/shallow-file-merge-base
Open

Fix shallow file scans when merge base objects are missing#4900
lawrence3699 wants to merge 1 commit intotrufflesecurity:mainfrom
lawrence3699:fix/shallow-file-merge-base

Conversation

@lawrence3699
Copy link
Copy Markdown

@lawrence3699 lawrence3699 commented Apr 19, 2026

Description:

Fixes #4895.

When trufflehog git file://... --since-commit <base> --branch <head> runs against a shallow local clone, normalizeConfig can fail while resolving the merge base because the common ancestor object is not present locally.

In that case, Git can still enumerate the head-side commits to scan, so this change keeps the resolved base ref instead of aborting the scan when MergeBase returns plumbing.ErrObjectNotFound.

The new regression test covers the shallow file:// path end to end and asserts that the scan still reports the feature-side change without pulling in the main-only commit.

Checklist:

  • Tests passing (go test ./pkg/sources/git -run TestScanRepo_ShallowLocalCloneWithBranchBaseRef -count=1, go test ./pkg/sources/git -run 'Test(GitConfigSanitization|ScanRepo_ShallowLocalCloneWithBranchBaseRef|GitConfigSanitizationWithBareRepo|GitConfigSecurityIsolation|GitConfigSanitizationWithStagedChanges|PrepareRepoErrorPaths|NormalizeFileURI|PrepareRepoWithNormalization|PrepareRepoWithNormalizationBare)$' -count=1, go test ./pkg/sources/git -run 'TestSource_Chunks_Integration/remote repo, main ahead of branch' -count=1)
  • Lint passing (./scripts/lint.sh)

Note

Medium Risk
Changes commit-range normalization for --since-commit scans: shallow clones that can’t load merge-base objects will now continue with the resolved base ref, which could subtly affect which commits are included/excluded. Covered by a new end-to-end regression test for shallow file:// clones.

Overview
Fixes shallow local file:// scans where normalizeConfig previously aborted if MergeBase failed with plumbing.ErrObjectNotFound; it now treats this as non-fatal and proceeds using the resolved base ref.

Adds TestScanRepo_ShallowLocalCloneWithBranchBaseRef to reproduce the CI-style shallow clone scenario and assert the scan still reports feature-branch content without pulling in main-only commits.

Reviewed by Cursor Bugbot for commit 5c91e5a. Bugbot is set up for automated code reviews on this repo. Configure here.

@lawrence3699 lawrence3699 requested review from a team and Copilot April 19, 2026 07:25
@lawrence3699 lawrence3699 requested a review from a team as a code owner April 19, 2026 07:25
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes failures when scanning shallow local file:// git clones with --since-commit <base> --branch <head> by not aborting when the merge-base object is missing locally (but commit enumeration from head is still possible).

Changes:

  • Treat plumbing.ErrObjectNotFound from MergeBase during normalizeConfig as non-fatal and continue with the resolved base ref/hash.
  • Add an end-to-end regression test that builds a shallow local clone scenario and asserts scanning finds feature-branch content without pulling in main-only content.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
pkg/sources/git/git.go Continue scanning when merge-base resolution fails due to missing objects in shallow clones.
pkg/sources/git/git_test.go Add regression coverage for shallow local file:// clone scanning with base/head branch refs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +724 to +745
func TestScanRepo_ShallowLocalCloneWithBranchBaseRef(t *testing.T) {
ctx := context.Background()

sourceRepoPath := setupTestRepo(t, "source-repo")
assert.NoError(t, exec.Command("git", "-C", sourceRepoPath, "branch", "-M", "main").Run())
addTestFileAndCommit(t, sourceRepoPath, "base.txt", "base one")
addTestFileAndCommit(t, sourceRepoPath, "base.txt", "base two")

assert.NoError(t, exec.Command("git", "-C", sourceRepoPath, "checkout", "-b", "feature").Run())
addTestFileAndCommit(t, sourceRepoPath, "feature.txt", "feature secret\nsecret: AKIA1234567890123456\n")
assert.NoError(t, exec.Command("git", "-C", sourceRepoPath, "checkout", "main").Run())
addTestFileAndCommit(t, sourceRepoPath, "main.txt", "main only")

originRepoPath := filepath.Join(t.TempDir(), "origin.git")
assert.NoError(t, exec.Command("git", "clone", "--bare", sourceRepoPath, originRepoPath).Run())

ciRepoPath := filepath.Join(t.TempDir(), "ci-repo")
assert.NoError(t, exec.Command("git", "clone", "--depth=1", "--branch", "feature", "file://"+originRepoPath, ciRepoPath).Run())
assert.NoError(t, exec.Command("git", "-C", ciRepoPath, "fetch", "--depth=1", "origin", "main:main").Run())

preparedRepoPath, _, err := prepareRepoSinceCommit(ctx, "file://"+ciRepoPath, "", "main", false, false)
assert.NoError(t, err)
Comment thread pkg/sources/git/git.go
Comment on lines 1217 to +1221
// If baseCommit is an ancestor of headCommit, update c.BaseRef to be the common ancestor.
mergeBase, err := headCommit.MergeBase(baseCommit)
if err != nil {
// Shallow local clones can omit the common ancestor object even when git can still
// enumerate the head-side commits to scan. In that case, keep the resolved base ref
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

git (on gitlab) fails with "error chunking dir \"/tmp/trufflehog-79-1064351127\": unable to resolve merge base: object not found"

3 participants