GetUncommittedRenames returns staged renames that git itself detected, as a map of old absolute path -> new absolute path. Git reports these as status "R" ("old -> new"); using its result avoids re-deriving the match and handles renames with edits, which content hashing would miss.
(repoPath string)
| 78 | // "R" ("old -> new"); using its result avoids re-deriving the match and handles |
| 79 | // renames with edits, which content hashing would miss. |
| 80 | func GetUncommittedRenames(repoPath string) (map[string]string, error) { |
| 81 | if _, err := os.Stat(repoPath); os.IsNotExist(err) { |
| 82 | return nil, fmt.Errorf("repository path does not exist: %s", repoPath) |
| 83 | } |
| 84 | if !isGitRepository(repoPath) { |
| 85 | return nil, fmt.Errorf("%s is not a git repository (use 'git init' to initialize)", repoPath) |
| 86 | } |
| 87 | |
| 88 | repoRoot, err := GetRepositoryRoot(repoPath) |
| 89 | if err != nil { |
| 90 | return nil, fmt.Errorf("failed to get repository root: %w", err) |
| 91 | } |
| 92 | |
| 93 | stdout, stderr, err := runGitCommand(repoPath, "status", "--porcelain", "--untracked-files=all") |
| 94 | if err != nil { |
| 95 | return nil, gitCommandError(err, stderr) |
| 96 | } |
| 97 | |
| 98 | renames := make(map[string]string) |
| 99 | for _, line := range strings.Split(string(stdout), "\n") { |
| 100 | if len(line) < 3 { |
| 101 | continue |
| 102 | } |
| 103 | // Porcelain "XY old -> new"; a rename is R in the index or working tree. |
| 104 | if line[0] != 'R' && line[1] != 'R' { |
| 105 | continue |
| 106 | } |
| 107 | parts := strings.Split(strings.TrimSpace(line[3:]), " -> ") |
| 108 | if len(parts) != 2 { |
| 109 | continue |
| 110 | } |
| 111 | oldPath := filepath.Join(repoRoot, strings.TrimSpace(parts[0])) |
| 112 | newPath := filepath.Join(repoRoot, strings.TrimSpace(parts[1])) |
| 113 | renames[oldPath] = newPath |
| 114 | } |
| 115 | if len(renames) == 0 { |
| 116 | return nil, nil |
| 117 | } |
| 118 | return renames, nil |
| 119 | } |
| 120 | |
| 121 | // GetCommitRenames returns git's own rename detection for a single commit (old |
| 122 | // path -> new path, absolute), mirroring `git diff -M`. Old content lives in the |
no test coverage detected