git_tools: add rename detection and proper handling of moved files
Enhance GitRawDiff to properly handle file renames and moves by:
1. Add -M flag to git diff commands to enable rename detection
2. Update parseRawDiff to handle the different output format for renames:
- Rename format: :oldmode newmode oldhash newhash R100 old_path new_path
- Split rename operations into separate delete and add entries
- This allows Monaco diff view to display both old and new files
3. Update DiffFile comment to document rename/copy status codes
The fix addresses GitHub issue #120 where Monaco diff view would error
when displaying files that were both modified and renamed. By splitting
renames into delete/add pairs, the existing UI can handle moved files
without requiring frontend changes.
Fixes #120
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s172724445cadbd68k
diff --git a/webui/src/web-components/sketch-diff-file-picker.ts b/webui/src/web-components/sketch-diff-file-picker.ts
index eb94a5f..cadafae 100644
--- a/webui/src/web-components/sketch-diff-file-picker.ts
+++ b/webui/src/web-components/sketch-diff-file-picker.ts
@@ -205,7 +205,8 @@
formatFileOption(file: GitDiffFile): string {
const statusSymbol = this.getFileStatusSymbol(file.status);
const changesInfo = this.getChangesInfo(file);
- return `${statusSymbol} ${file.path}${changesInfo}`;
+ const pathInfo = this.getPathInfo(file);
+ return `${statusSymbol} ${pathInfo}${changesInfo}`;
}
/**
@@ -231,6 +232,18 @@
}
/**
+ * Get path information for display, handling renames and copies
+ */
+ getPathInfo(file: GitDiffFile): string {
+ if (file.old_path && file.old_path !== "") {
+ // For renames and copies, show old_path -> new_path
+ return `${file.old_path} → ${file.path}`;
+ }
+ // For regular files, just show the path
+ return file.path;
+ }
+
+ /**
* Get a short symbol for the file status
*/
getFileStatusSymbol(status: string): string {
@@ -244,6 +257,14 @@
case "R":
return "R";
default:
+ // Handle copy statuses like C096, C100, etc.
+ if (status.toUpperCase().startsWith("C")) {
+ return "C";
+ }
+ // Handle rename statuses like R096, R100, etc.
+ if (status.toUpperCase().startsWith("R")) {
+ return "R";
+ }
return "?";
}
}
@@ -262,6 +283,14 @@
case "R":
return "Renamed";
default:
+ // Handle copy statuses like C096, C100, etc.
+ if (status.toUpperCase().startsWith("C")) {
+ return "Copied";
+ }
+ // Handle rename statuses like R096, R100, etc.
+ if (status.toUpperCase().startsWith("R")) {
+ return "Renamed";
+ }
return "Unknown";
}
}