Skip to content

Fix: Reverse git diff direction to correctly detect renamed files with -M95#347

Open
chandprashant92 wants to merge 1 commit intodropbox:mainfrom
chandprashant92:chandprashant92/fix/git-diff-direction-rename-detection
Open

Fix: Reverse git diff direction to correctly detect renamed files with -M95#347
chandprashant92 wants to merge 1 commit intodropbox:mainfrom
chandprashant92:chandprashant92/fix/git-diff-direction-rename-detection

Conversation

@chandprashant92
Copy link

Bug: git diff HEAD..merge-base silently misses all affected modules

when a PR contains only pure file renames

Problem

GitChangedFilesSource constructs the changed-files command as:

git --no-pager diff --name-only -M95 $top..$sha

Where top = "HEAD" (the PR tip) and sha = the merge-base commit.
This produces:

git diff --name-only -M95 HEAD..merge-base

The direction is reversed. The semantically correct command for
"what changed in this PR?" is merge-base..HEAD.

Why this is silent for normal PRs (and why it was never caught)

For content-modified files, git diff A..B and git diff B..A report
the same filenames — direction doesn't affect --name-only output.

The bug only surfaces when a PR consists entirely of pure renames
(files moved via git mv with 100% content similarity). In that case,
-M95 rename detection kicks in and --name-only outputs the
destination path relative to the diff direction:

Command --name-only output
git diff merge-base..HEAD NEW paths (correct for AMD's ProjectGraph)
git diff HEAD..merge-base OLD paths (wrong — these don't exist in the current ProjectGraph)

With the reversed direction, AMD receives a list of file paths that no
longer exist in the project tree → changedProjects = 0, unknownFiles
accumulates all renamed files → the buildAllWhenNoProjectsChanged
safety net is not triggered (because unknownFiles is non-empty) →
AMD reports 0 affected modules and silently skips all tasks.

Reproduction

git mv src/foo/Bar.kt src/baz/Bar.kt
git commit -m "rename"

# AMD (broken) — shows OLD path → no module match
git diff --name-only -M95 HEAD..$(git merge-base HEAD origin/main)
# Output: src/foo/Bar.kt  ← old path, doesn't exist in current ProjectGraph

# Correct — shows NEW path → module matched
git diff --name-only -M95 $(git merge-base HEAD origin/main)..HEAD
# Output: src/baz/Bar.kt  ← new path, correctly resolved to module

Fix

Swap the argument order in GitChangedFilesSource:

// Before
"$CHANGED_FILES_CMD_PREFIX $top..$sha"

// After
"$CHANGED_FILES_CMD_PREFIX $sha..$top"

No behaviour change for content-modified files. Correctly handles
pure-rename PRs by reporting new destination paths that map to the
current project graph.

…h -M95

Fix: Reverse git diff direction to correctly detect renamed files with -M95
@CLAassistant
Copy link

CLAassistant commented Mar 18, 2026

CLA assistant check
All committers have signed the CLA.

@chandprashant92
Copy link
Author

Hi @joshafeinberg, would you mind reviewing my changes, please?

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