Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# AGENTS.md

This file provides guidance to AI coding agents (Claude Code, etc.) when working with code in this repository. CLAUDE.md is a symlink to this file.

Source-Trace (`source-trace`, AGPL-3.0) is an internal Ultralytics tool that clones two Git repositories and reports lines of code that appear in both, to surface potential cross-repository code duplication. It is run from a checkout rather than installed from PyPI.

## Core Principles (CRITICAL)

**Less is more. The simplest solution is the best solution.** The action hierarchy for every change: **Delete > Replace > Add**.

1. **Solve at the owner**: Put behavior in the code path that owns or observes it. For fixes, never guard a symptom with a staleness check, initialization flag, skip-first-call branch, or `try/except` around broken logic; relocate the trigger and delete the wrong path. For features, extend the existing owner rather than creating a parallel abstraction.
2. **Search and reuse first**: Search the whole repository before creating a feature, component, helper, workflow, or utility. Reuse or adapt what exists, consolidate in-scope duplication in the shared owner, and delete duplicate paths. Three similar lines beat a helper nobody else calls.
3. **Delete and modify existing code before creating new code**: Bugfixes are net-negative by default unless deletion and relocation are demonstrably impossible. A new file must first prove it cannot fit cleanly in an existing owner.
4. **Keep scope minimal**: Implement only the simplest complete solution. Avoid impossible-state handling, speculative flags, compatibility shims, policy scaffolding, and unrelated cleanup. Tests are out of scope by default β€” rely on existing coverage and focused validation; only an uncovered, high-risk regression path justifies minimal new test code.
5. **Ship zero-regression, production-ready changes**: Understand what you remove instead of retaining broken code as insurance. Remove unused imports, functions, types, files, and comments; run relevant cleanup checks; and thoroughly debug and validate the changed owner. Do not break existing features or workflows unless the PR intentionally removes them with evidence.

**Review gate:** for every addition, the reviewer decides whether deleting or changing existing code would have fixed the problem instead β€” if it would, that is a blocking finding. A missing or thin PR description is never itself a finding.

NEVER push to `main`. NEVER force push. Always start work in a new git worktree (`git worktree add`) on a feature branch and open a PR β€” never edit the primary checkout directly, it may hold in-flight work.

## PR Workflow

After opening a PR:

1. Wait for the automated PR review and auto-format commit from Ultralytics Actions (`format.yml`), then pull and address every finding.
2. Review the full diff in-session against the Core Principles, performance, and the review gate above, then batch the fixes into one commit and push. After each round of bot or human commits, pull and resume the same reviewer on `<last-reviewed-sha>..HEAD` plus anything that delta could have invalidated. Repeat until the local head matches the live head.
3. Hand off or merge only on a clean final pass: one cold full-diff review returning LGTM with no findings, on a head that is still live at merge time.
4. Never fight other commits: Ultralytics Actions pushes auto-format and header commits, and multiple users may work on the same PR. `git pull --rebase` before pushing; never reset or revert commits you did not author.
5. After the PR merges, clean up: remove local worktrees and branches for it, then `git checkout main && git pull`.

## Commands

```bash
# Editable install (deps: gitpython, pandas, numpy)
uv pip install -e .

# Run a comparison β€” edit the constants at the top of source/run_repo.py first
python source/run_repo.py
```

- There is no test suite and no test CI. The only workflows are `format.yml` (Ultralytics Actions autoformat, labels, PR summaries) and `cla.yml`; neither runs the tool.
- A run clones both repositories in full into `github.com/<org>/<repo>` under the repository root and reuses that directory on later runs, so delete it to force a fresh clone.

## Architecture

Everything lives in `source/run_repo.py`; `source/__init__.py` only exposes `__version__` and `ROOT`. The tool is configured by editing module-level constants rather than by CLI flags: `SOURCE_REPO`, `DEST_REPO`, `SUFFIXES`, `IGNORE_START`, and `IGNORE_LINES`.

The pipeline is four functions called in order by `main(repo_a, repo_b, local_dir)`:

- `clone_repository()` clones a repository URL into `local_dir/<org>/<repo>`, skipping the clone when the directory already exists.
- `extract_file_contents()` reads every non-binary file in a clone and returns `{relative_path: [stripped_lowercased_lines]}`, skipping files that fail to decode as UTF-8.
- `compare_repos()` intersects the line sets of each source/destination file pair whose source suffix is in `SUFFIXES`, keeping only lines longer than 20 characters that do not start with an `IGNORE_START` prefix and do not exactly match an `IGNORE_LINES` entry. It returns `(source_file, dest_file, line)` tuples.
- `calculate_statistics()` reduces those tuples to the duplicated-line count and the number of distinct files on each side.

Matching is line-level and set-based, so it detects identical lines rather than moved blocks, and it reports each distinct line once per file pair regardless of how often it repeats. No Git history is read: authorship and commit dates are not collected.

## Conventions

- Every Python file starts with `# Ultralytics πŸš€ AGPL-3.0 License - https://ultralytics.com/license` β€” Ultralytics Actions adds headers automatically; don't add or revert them manually.
- Google-style docstrings and Ruff formatting at line length 120 (`[tool.ruff]` in pyproject.toml), applied automatically by `format.yml` on PRs.
- `docs/` holds a plain README describing usage; there is no MkDocs site or `mkdocs.yml`, so keep usage docs in `README.md` and `docs/README.md` in sync with the constants in `source/run_repo.py`.
- There is no release workflow and the package is not on PyPI; leave `__version__` in `source/__init__.py` alone.
1 change: 1 addition & 0 deletions CLAUDE.md
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Welcome to the `ultralytics/source-trace` repository! This specialized tool from

## ✨ Features

- **Detailed Comparison**: Generates comprehensive reports highlighting lines of code from one repository found within another.
- **Comprehensive Statistics**: Provides valuable [metrics](https://www.ultralytics.com/glossary/accuracy) detailing the extent of code duplication, broken down by file and author.
- **Metadata Tracking**: Captures essential metadata for each duplication instance, including the author and commit date.
- **Detailed Comparison**: Prints every line of code from the source repository that also appears in the destination repository, after filtering out short lines and common boilerplate.
- **Summary Statistics**: Reports the file and line totals for each repository, the number of duplicated lines found, and how many distinct files on each side those lines came from.
- **Provenance Pairs**: Records the source file and destination file alongside each duplicated line, so every match can be traced back to both repositories.

## πŸš€ Getting Started

Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ classifiers = [# Optional, for a list of valid classifiers, see https://pypi.org
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Software Development",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
Expand Down