Skip to content

Untangle lage git spaghetti - #1236

Merged
Elizabeth Craig (ecraig12345) merged 6 commits into
microsoft:mainfrom
ecraig12345:dedupe-git
Nov 5, 2026
Merged

Elizabeth Craig (ecraig12345) merged 6 commits into
microsoft:mainfrom
ecraig12345:dedupe-git

Conversation

@ecraig12345

@ecraig12345 Elizabeth Craig (ecraig12345) commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Follow-up from #1233: Probably due to various feature additions over time, the lage CLI was doing a lot of redundant git operations on startup, which could be a major startup performance hit in huge repos where git is very slow or if there are a lot of changes.

User-facing impact

  • Only do the process of getting branch and local changes from git once (shared between --since filtering and target graph creation) for run, info, and affected.
  • Combine getting staged, unstaged, and untracked changes into a single git operation.
  • Make affected use the same initial package-selection policy as run and info, including configured ignore patterns and --to handling (skips change detection).
  • Changes matching repoWideChanges now include staged, unstaged, and untracked files in addition to committed branch changes (so uncommitted repo-wide changes can expand a --since run to all packages, matching the target hashing/caching behavior).
  • Match repoWideChanges against paths returned by git, not against files on disk. This is more efficient and ensures deleted files match.
  • Avoid unnecessary git change scans for run/info with --scope/--to: only scan if --since is set and one or more staged targets is configured.

Internal changes

  • Replace getRepoChanges with getChangedFiles, collecting each branch changes and all other changes once and deduplicating paths into one snapshot.
  • Add getWorkingTreeChanges helper (used above) to get staged/unstaged/untracked files in a single git operation.
  • Use a discriminated ChangedFiles union with skipped, failed, and success statuses (success also includes file paths).
  • Update getFilteredPackages and createTargetGraph to accept a changes?: ChangedFiles option and skip git detection internally.
  • getFilteredPackages internally handles combining CLI/config ignores and normalizing --to as scope without dependents.
  • Add createFilteredTargetGraph for run and info. It checks both root pipeline and package-level lage definitions for staged configuration (to determine if git changes are needed), shares a git snapshot between filtering and graph construction when needed, and returns { packages, targetGraph }.
  • affected continues to only get the filtered packages (not a full target graph). The lage service continues building a reusable graph without staged-target optimization.
  • Consolidate run's watch and regular mode into run/action.ts to dedupe code and prevent accidental behavior differences.
  • Allow getPackagesByFiles to reuse preloaded PackageInfos. Clarify that its all-package fallback applies when any non-ignored file belongs to no package.

export async function action(options: RunCommandOptions, command: Command): Promise<void> {
if (options.watch) {
return watchAction(options, command);
const { watch } = options;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is the same content as the previous runAction and watchAction, with deduped setup and using new helpers.

@ecraig12345
Elizabeth Craig (ecraig12345) merged commit fa3d0ab into microsoft:main Nov 5, 2026
14 checks passed
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.

2 participants