feat: show git diff in reverted messages

This commit is contained in:
adamdotdevin
2025-07-29 13:11:38 -05:00
parent c0ee6a6d05
commit a129e122aa
2 changed files with 91 additions and 0 deletions

View File

@@ -5,6 +5,8 @@ import (
"fmt"
"log/slog"
"slices"
"sort"
"strconv"
"strings"
tea "github.com/charmbracelet/bubbletea/v2"
@@ -14,6 +16,7 @@ import (
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/commands"
"github.com/sst/opencode/internal/components/dialog"
"github.com/sst/opencode/internal/components/diff"
"github.com/sst/opencode/internal/components/toast"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
@@ -569,6 +572,36 @@ func (m *messagesComponent) renderView() tea.Cmd {
hint += revertedStyle.Render(" (or /redo) to restore")
content += "\n" + hint
if m.app.Session.Revert.Diff != "" {
t := theme.CurrentTheme()
s := styles.NewStyle().Background(t.BackgroundPanel())
green := s.Foreground(t.Success()).Render
red := s.Foreground(t.Error()).Render
content += "\n"
stats, err := diff.ParseStats(m.app.Session.Revert.Diff)
if err != nil {
slog.Error("Failed to parse diff stats", "error", err)
} else {
var files []string
for file := range stats {
files = append(files, file)
}
sort.Strings(files)
for _, file := range files {
fileStats := stats[file]
display := file
if fileStats.Added > 0 {
display += green(" +" + strconv.Itoa(int(fileStats.Added)))
}
if fileStats.Removed > 0 {
display += red(" -" + strconv.Itoa(int(fileStats.Removed)))
}
content += "\n" + display
}
}
}
content = styles.NewStyle().
Background(t.BackgroundPanel()).
Width(width - 6).

View File

@@ -0,0 +1,58 @@
package diff
import (
"bufio"
"fmt"
"strings"
)
type DiffStats struct {
Added int
Removed int
Modified int
}
func ParseStats(diff string) (map[string]DiffStats, error) {
stats := make(map[string]DiffStats)
var currentFile string
scanner := bufio.NewScanner(strings.NewReader(diff))
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "---") {
continue
} else if strings.HasPrefix(line, "+++") {
parts := strings.SplitN(line, " ", 2)
if len(parts) == 2 {
currentFile = strings.TrimPrefix(parts[1], "b/")
}
continue
}
if strings.HasPrefix(line, "@@") {
continue
}
if currentFile == "" {
continue
}
fileStats := stats[currentFile]
switch {
case strings.HasPrefix(line, "+"):
fileStats.Added++
case strings.HasPrefix(line, "-"):
fileStats.Removed++
}
stats[currentFile] = fileStats
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("error reading diff string: %w", err)
}
for file, fileStats := range stats {
fileStats.Modified = fileStats.Added + fileStats.Removed
stats[file] = fileStats
}
return stats, nil
}