Skip to content

Harvester first run fails when no checkpoint exists #1128

Open

Description

@Adarsh-9182

Issue

What is the issue?

The no-checkpoint branch of _harvest_repository() cannot bootstrap a new repository. It passes a hardcoded empty-tree ID to ChangeDetector.get_modified_files_since(), but:

  1. The configured ID (4b825dc642cb6eb9a060e54bf8d6927bf442cfb4) is incorrect. The SHA-1 empty-tree ID is 4b825dc642cb6eb9a060e54bf8d69288fbee4904.
  2. Correcting the ID alone still fails: _resolve_commit() verifies every input with ^{commit}, which rejects a tree object before git diff runs.

On main fbacf559, the code is at pipeline.py:139 and change_detector.py:14.

Expected Behaviour

A repository with no checkpoint should discover tracked files at HEAD, apply existing include/exclude rules, and process initial security documents. Subsequent checkpoint-based runs should continue comparing commits normally.

Actual Behaviour

The first-run branch raises CalledProcessError (Git exit 128) before filtering or document processing. Using the correct empty-tree ID changes the error to "expected commit type, but the object dereferences to tree type".

Steps to reproduce

From the repo root with Python dependencies installed, run this with the project's Python interpreter. This uses the actual detector and a temporary real Git repository; it does not alter the OpenCRE checkout or database.

import subprocess
import tempfile
from pathlib import Path
from application.utils.harvester.change_detector import ChangeDetector
from application.utils.harvester.git_repository_client import GitRepositoryClient

with tempfile.TemporaryDirectory() as directory:
    root = Path(directory)

    def git(*args, input_text=None):
        return subprocess.run(
            ["git", "-C", str(root), "-c", "core.hooksPath=/dev/null", *args],
            input=input_text, check=True, capture_output=True, text=True,
        ).stdout.strip()

    git("init", "--object-format=sha1")
    (root / "requirement.md").write_text("# Auth\nUse MFA.\n")
    git("add", "requirement.md")
    git("-c", "user.name=Fixture", "-c", "user.email=fixture@example.invalid",
        "-c", "commit.gpgsign=false", "commit", "-m", "Fixture")
    head = git("rev-parse", "HEAD")
    empty_tree = git("hash-object", "-t", "tree", "-w", "--stdin", input_text="")
    print("Direct git diff:", git("diff", "--name-only", empty_tree, head))
    detector = ChangeDetector(GitRepositoryClient("LOCAL", "fixture", local_path=root))
    for base in ("4b825dc642cb6eb9a060e54bf8d6927bf442cfb4", empty_tree):
        try:
            print(detector.get_modified_files_since(base, head))
        except subprocess.CalledProcessError as error:
            print(error.returncode, error.stderr.strip())

Observed: the direct Git diff lists requirement.md; both detector calls fail. A separate two-commit control succeeds, isolating this to bootstrap input.

This reproduction isolates the per-repository first-run branch. The separate configuration-validation mismatch in run_harvester() is addressed by #1115; that patch does not alter this branch. The path parsing fix in #1032 / #1056 concerns DiffParser, a different component.

Proposed direction

Enumerate tracked files at the verified HEAD commit using git ls-tree -r --name-only -z for the no-checkpoint case, then retain the existing include/exclude filtering. This avoids a hardcoded empty-tree object and keeps commit-only verification for incremental history operations.

Regression coverage should use real Git fixtures for bootstrap and incremental runs, with nested/space/non-ASCII paths, excluded files, and an empty committed tree. No dependency or schema change is needed.

I checked existing issue/PR searches for the incorrect ID and empty-tree/first-run harvester failures and did not find a dedicated pending fix. Would this scoped fix be useful, and is anyone already working on it?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions