* Get list of files changed between a commit and the working tree. * Uses `git diff ` which compares to working directory (includes uncommitted changes). * This is the same approach used by workTreeDiffPatch for snapshots.
(params: GetChangedFilesParams)
| 1733 | * This is the same approach used by workTreeDiffPatch for snapshots. |
| 1734 | */ |
| 1735 | async function handleGetChangedFiles(params: GetChangedFilesParams): Promise<GetChangedFilesResponse> { |
| 1736 | const startTime = Date.now() |
| 1737 | logger.info("[Git:getChangedFiles] Getting changed files", JSON.stringify({ |
| 1738 | workDir: params.workDir, |
| 1739 | from: params.fromTreeish, |
| 1740 | to: params.toTreeish, |
| 1741 | })) |
| 1742 | |
| 1743 | try { |
| 1744 | // Use `git diff <commit>` to compare against working tree (includes uncommitted changes) |
| 1745 | // This matches the behavior of workTreeDiffPatch used for snapshots |
| 1746 | const result = await execGit( |
| 1747 | ["diff", "--name-status", "-M", params.fromTreeish], |
| 1748 | params.workDir |
| 1749 | ) |
| 1750 | |
| 1751 | if (!result.success) { |
| 1752 | logger.error("[Git:getChangedFiles] Failed to get diff", JSON.stringify({ stderr: result.stderr })) |
| 1753 | throw new Error(`Failed to get changed files: ${result.stderr}`) |
| 1754 | } |
| 1755 | |
| 1756 | const files = parseNameStatusOutput(result.stdout) |
| 1757 | const seenPaths = new Set(files.map((file) => file.path)) |
| 1758 | |
| 1759 | // Also include untracked files (new files not yet added to git) |
| 1760 | const untrackedResult = await execGit( |
| 1761 | ["ls-files", "--others", "--exclude-standard"], |
| 1762 | params.workDir |
| 1763 | ) |
| 1764 | |
| 1765 | if (untrackedResult.success) { |
| 1766 | const untrackedLines = untrackedResult.stdout.trim().split("\n").filter(Boolean) |
| 1767 | for (const filePath of untrackedLines) { |
| 1768 | if (!seenPaths.has(filePath)) { |
| 1769 | files.push({ path: filePath, status: "added" }) |
| 1770 | } |
| 1771 | } |
| 1772 | } |
| 1773 | |
| 1774 | logger.info("[Git:getChangedFiles] Found changed files", JSON.stringify({ |
| 1775 | count: files.length, |
| 1776 | duration: Date.now() - startTime, |
| 1777 | })) |
| 1778 | |
| 1779 | return { |
| 1780 | files, |
| 1781 | fromTreeish: params.fromTreeish, |
| 1782 | toTreeish: params.toTreeish, |
| 1783 | } |
| 1784 | } catch (error: any) { |
| 1785 | logger.error("[Git:getChangedFiles] Error:", JSON.stringify({ error: error.message, duration: Date.now() - startTime })) |
| 1786 | throw error |
| 1787 | } |
| 1788 | } |
| 1789 | |
| 1790 | // Max file size for diff display (1MB) |
| 1791 | const MAX_FILE_SIZE_FOR_DIFF = 1024 * 1024 |
no test coverage detected