package main import ( "sort" "strings" "time" ) type RepoInfo struct { Name string Path string GitDir string Description string Owner string LastUpdated time.Time Git *gitCLIBackend } type CommitInfo struct { Hash string ShortHash string Subject string Body string Author string AuthorEmail string AuthorDate time.Time Parents []string } type TreeEntryInfo struct { Name string IsDir bool Size int64 Mode string Hash string } type BlobInfo struct { Name string Size int64 IsBinary bool Lines []string Content string } type RefInfo struct { Name string Hash string ShortHash string Subject string Author string Date time.Time IsTag bool } type DiffFile struct { OldName string NewName string Status string Hunks []DiffHunk IsBinary bool Stats DiffStats } type DiffStats struct { Added int Deleted int } type DiffHunk struct { Header string Lines []DiffLine } type DiffLine struct { Type string // "context", "add", "del" Content string OldNum int NewNum int } type TreeNode struct { Name string IsDir bool Size int64 Path string Depth int IsOpen bool IsActive bool } const maxBlobDisplaySize = 1 << 20 // 1MB const diffContextLines = 5 const maxDiffFiles = 256 // max files rendered per commit func sortTreeEntries(entries []TreeEntryInfo) { sort.Slice(entries, func(i, j int) bool { if entries[i].IsDir != entries[j].IsDir { return entries[i].IsDir } return entries[i].Name < entries[j].Name }) } // collapseContext takes a flat list of diff lines and splits them into // hunks, keeping only diffContextLines of context around add/del lines. func collapseContext(lines []DiffLine) []DiffHunk { if len(lines) == 0 { return nil } // Mark which lines to keep: diffContextLines around each changed line. keep := make([]bool, len(lines)) for i, l := range lines { if l.Type == "add" || l.Type == "del" { start := i - diffContextLines if start < 0 { start = 0 } end := i + diffContextLines if end >= len(lines) { end = len(lines) - 1 } for j := start; j <= end; j++ { keep[j] = true } } } // Build hunks from contiguous kept ranges. var hunks []DiffHunk var current *DiffHunk for i, l := range lines { if keep[i] { if current == nil { current = &DiffHunk{} } current.Lines = append(current.Lines, l) } else { if current != nil { hunks = append(hunks, *current) current = nil } } } if current != nil { hunks = append(hunks, *current) } return hunks } var mimeTypes = map[string]string{ ".txt": "text/plain; charset=utf-8", ".md": "text/plain; charset=utf-8", ".go": "text/plain; charset=utf-8", ".rs": "text/plain; charset=utf-8", ".py": "text/plain; charset=utf-8", ".js": "text/plain; charset=utf-8", ".ts": "text/plain; charset=utf-8", ".c": "text/plain; charset=utf-8", ".h": "text/plain; charset=utf-8", ".css": "text/css; charset=utf-8", ".html": "text/html; charset=utf-8", ".json": "application/json", ".xml": "application/xml", ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".svg": "image/svg+xml", ".pdf": "application/pdf", } func mimeFromPath(path string) string { idx := strings.LastIndex(path, ".") if idx < 0 { return "" } ext := strings.ToLower(path[idx:]) if t, ok := mimeTypes[ext]; ok { return t } return "" }