fix(git): handle non-tracked files gracefully in diff operations
- Return empty line ranges when git diff fails for non-tracked files - Prevents hook failures on .claude/settings.local.json and similar files - Improves robustness when processing files outside git tracking
This commit is contained in:
+3
-19
@@ -9,8 +9,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func DetectRepo() (*GitStatus, error) {
|
||||
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
||||
output, err := cmd.Output()
|
||||
@@ -25,7 +23,6 @@ func DetectRepo() (*GitStatus, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
func GetStagedChanges() ([]FileChange, error) {
|
||||
|
||||
cmd := exec.Command("git", "diff", "--cached", "--name-only")
|
||||
@@ -45,7 +42,6 @@ return []FileChange{}, nil
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
lineRanges, err := getLineRangesFromDiff(file, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get line ranges for %s: %v", file, err)
|
||||
@@ -61,11 +57,9 @@ return []FileChange{}, nil
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
|
||||
func GetUnstagedChanges() ([]FileChange, error) {
|
||||
var changes []FileChange
|
||||
|
||||
|
||||
cmd := exec.Command("git", "diff", "--name-only")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
@@ -78,7 +72,6 @@ func GetUnstagedChanges() ([]FileChange, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
lineRanges, err := getLineRangesFromDiff(file, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get line ranges for %s: %v", file, err)
|
||||
@@ -91,7 +84,6 @@ func GetUnstagedChanges() ([]FileChange, error) {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
cmd = exec.Command("git", "ls-files", "--others", "--exclude-standard")
|
||||
output, err = cmd.Output()
|
||||
if err != nil {
|
||||
@@ -104,7 +96,6 @@ func GetUnstagedChanges() ([]FileChange, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
changes = append(changes, FileChange{
|
||||
Path: file,
|
||||
Status: StatusUntracked,
|
||||
@@ -115,7 +106,6 @@ LineRanges: []LineRange{},
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
|
||||
func getLineRangesFromDiff(file string, staged bool) ([]LineRange, error) {
|
||||
var cmd *exec.Cmd
|
||||
if staged {
|
||||
@@ -126,18 +116,17 @@ func getLineRangesFromDiff(file string, staged bool) ([]LineRange, error) {
|
||||
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
|
||||
return []LineRange{}, nil
|
||||
}
|
||||
|
||||
return ParseDiffUnified(string(output))
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ParseDiffUnified(diff string) ([]LineRange, error) {
|
||||
var ranges []LineRange
|
||||
|
||||
|
||||
headerRegex := regexp.MustCompile(`@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@`)
|
||||
|
||||
scanner := bufio.NewScanner(strings.NewReader(diff))
|
||||
@@ -162,7 +151,6 @@ newCount = 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if newCount > 0 {
|
||||
ranges = append(ranges, LineRange{
|
||||
Start: newStart,
|
||||
@@ -175,7 +163,6 @@ newCount = 1
|
||||
return ranges, scanner.Err()
|
||||
}
|
||||
|
||||
|
||||
func IsInLineRanges(lineNum int, ranges []LineRange) bool {
|
||||
for _, r := range ranges {
|
||||
if lineNum >= r.Start && lineNum <= r.End {
|
||||
@@ -185,18 +172,15 @@ func IsInLineRanges(lineNum int, ranges []LineRange) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
func GetChangesOnly() ([]FileChange, error) {
|
||||
var allChanges []FileChange
|
||||
|
||||
|
||||
staged, err := GetStagedChanges()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get staged changes: %v", err)
|
||||
}
|
||||
allChanges = append(allChanges, staged...)
|
||||
|
||||
|
||||
unstaged, err := GetUnstagedChanges()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get unstaged changes: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user