GitDiffInfo returns comprehensive diff information for the repo
(root, ref string)
| 17 | |
| 18 | // GitDiffInfo returns comprehensive diff information for the repo |
| 19 | func GitDiffInfo(root, ref string) (*DiffInfo, error) { |
| 20 | info := &DiffInfo{ |
| 21 | Changed: make(map[string]bool), |
| 22 | Untracked: make(map[string]bool), |
| 23 | Stats: make(map[string]DiffStat), |
| 24 | } |
| 25 | |
| 26 | // Get modified files vs ref with stats |
| 27 | cmd := exec.Command("git", "diff", "--numstat", ref) |
| 28 | cmd.Dir = root |
| 29 | output, err := cmd.Output() |
| 30 | if err != nil { |
| 31 | return nil, err |
| 32 | } |
| 33 | |
| 34 | for _, line := range strings.Split(strings.TrimSpace(string(output)), "\n") { |
| 35 | if line == "" { |
| 36 | continue |
| 37 | } |
| 38 | parts := strings.Fields(line) |
| 39 | if len(parts) >= 3 { |
| 40 | var added, removed int |
| 41 | if parts[0] != "-" { |
| 42 | fmt.Sscanf(parts[0], "%d", &added) |
| 43 | } |
| 44 | if parts[1] != "-" { |
| 45 | fmt.Sscanf(parts[1], "%d", &removed) |
| 46 | } |
| 47 | filename := strings.Join(parts[2:], " ") |
| 48 | info.Changed[filename] = true |
| 49 | info.Stats[filename] = DiffStat{Added: added, Removed: removed} |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | // Get untracked files (new files) |
| 54 | cmd2 := exec.Command("git", "ls-files", "--others", "--exclude-standard") |
| 55 | cmd2.Dir = root |
| 56 | output2, _ := cmd2.Output() |
| 57 | for _, line := range strings.Split(strings.TrimSpace(string(output2)), "\n") { |
| 58 | if line != "" { |
| 59 | info.Changed[line] = true |
| 60 | info.Untracked[line] = true |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | return info, nil |
| 65 | } |
| 66 | |
| 67 | // GitDiffFiles returns files changed between current HEAD and the given branch/ref |
| 68 | // Also includes untracked files (new files not yet committed) |
no outgoing calls