shithub: furgit

Download patch

ref: 474b047cd065bb2cc45153636123ea0812507ef2
parent: 0a8c2632d02d19dc986f34f6ea457e4994977002
author: Runxi Yu <me@runxiyu.org>
date: Wed Mar 4 04:55:13 EST 2026

diff/trees: Split

--- a/diff/trees/diff.go
+++ b/diff/trees/diff.go
@@ -20,173 +20,3 @@
 
 	return out, nil
 }
-
-func diffRecursive(a, b *object.Tree, prefix []byte, readTree func(objectid.ObjectID) (*object.Tree, error), out *[]Entry) error {
-	if a == nil && b == nil {
-		return nil
-	}
-
-	if a == nil {
-		for i := range b.Entries {
-			entry := &b.Entries[i]
-			full := joinPath(prefix, entry.Name)
-
-			*out = append(*out, Entry{Path: full, Kind: EntryKindAdded, Old: nil, New: entry})
-			if entry.Mode != object.FileModeDir {
-				continue
-			}
-
-			sub, err := readTree(entry.ID)
-			if err != nil {
-				return err
-			}
-
-			err = diffRecursive(nil, sub, full, readTree, out)
-			if err != nil {
-				return err
-			}
-		}
-
-		return nil
-	}
-
-	if b == nil {
-		for i := range a.Entries {
-			entry := &a.Entries[i]
-			full := joinPath(prefix, entry.Name)
-
-			*out = append(*out, Entry{Path: full, Kind: EntryKindDeleted, Old: entry, New: nil})
-			if entry.Mode != object.FileModeDir {
-				continue
-			}
-
-			sub, err := readTree(entry.ID)
-			if err != nil {
-				return err
-			}
-
-			err = diffRecursive(sub, nil, full, readTree, out)
-			if err != nil {
-				return err
-			}
-		}
-
-		return nil
-	}
-
-	i := 0
-
-	j := 0
-	for i < len(a.Entries) && j < len(b.Entries) {
-		left := &a.Entries[i]
-		right := &b.Entries[j]
-
-		cmp := object.TreeEntryNameCompare(
-			left.Name,
-			left.Mode,
-			right.Name,
-			right.Mode == object.FileModeDir,
-		)
-		switch {
-		case cmp < 0:
-			full := joinPath(prefix, left.Name)
-
-			*out = append(*out, Entry{Path: full, Kind: EntryKindDeleted, Old: left, New: nil})
-			if left.Mode == object.FileModeDir {
-				sub, err := readTree(left.ID)
-				if err != nil {
-					return err
-				}
-
-				err = diffRecursive(sub, nil, full, readTree, out)
-				if err != nil {
-					return err
-				}
-			}
-
-			i++
-		case cmp > 0:
-			full := joinPath(prefix, right.Name)
-
-			*out = append(*out, Entry{Path: full, Kind: EntryKindAdded, Old: nil, New: right})
-			if right.Mode == object.FileModeDir {
-				sub, err := readTree(right.ID)
-				if err != nil {
-					return err
-				}
-
-				err = diffRecursive(nil, sub, full, readTree, out)
-				if err != nil {
-					return err
-				}
-			}
-
-			j++
-		default:
-			full := joinPath(prefix, left.Name)
-
-			modified := left.Mode != right.Mode || left.ID != right.ID
-			if modified {
-				*out = append(*out, Entry{Path: full, Kind: EntryKindModified, Old: left, New: right})
-			}
-
-			if left.Mode == object.FileModeDir && right.Mode == object.FileModeDir && left.ID != right.ID {
-				leftSub, err := readTree(left.ID)
-				if err != nil {
-					return err
-				}
-
-				rightSub, err := readTree(right.ID)
-				if err != nil {
-					return err
-				}
-
-				err = diffRecursive(leftSub, rightSub, full, readTree, out)
-				if err != nil {
-					return err
-				}
-			}
-
-			i++
-			j++
-		}
-	}
-
-	for ; i < len(a.Entries); i++ {
-		left := &a.Entries[i]
-		full := joinPath(prefix, left.Name)
-
-		*out = append(*out, Entry{Path: full, Kind: EntryKindDeleted, Old: left, New: nil})
-		if left.Mode == object.FileModeDir {
-			sub, err := readTree(left.ID)
-			if err != nil {
-				return err
-			}
-
-			err = diffRecursive(sub, nil, full, readTree, out)
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	for ; j < len(b.Entries); j++ {
-		right := &b.Entries[j]
-		full := joinPath(prefix, right.Name)
-
-		*out = append(*out, Entry{Path: full, Kind: EntryKindAdded, Old: nil, New: right})
-		if right.Mode == object.FileModeDir {
-			sub, err := readTree(right.ID)
-			if err != nil {
-				return err
-			}
-
-			err = diffRecursive(nil, sub, full, readTree, out)
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
--- /dev/null
+++ b/diff/trees/diff_recursive.go
@@ -1,0 +1,176 @@
+package trees
+
+import (
+	"codeberg.org/lindenii/furgit/object"
+	"codeberg.org/lindenii/furgit/objectid"
+)
+
+func diffRecursive(a, b *object.Tree, prefix []byte, readTree func(objectid.ObjectID) (*object.Tree, error), out *[]Entry) error {
+	if a == nil && b == nil {
+		return nil
+	}
+
+	if a == nil {
+		for i := range b.Entries {
+			entry := &b.Entries[i]
+			full := joinPath(prefix, entry.Name)
+
+			*out = append(*out, Entry{Path: full, Kind: EntryKindAdded, Old: nil, New: entry})
+			if entry.Mode != object.FileModeDir {
+				continue
+			}
+
+			sub, err := readTree(entry.ID)
+			if err != nil {
+				return err
+			}
+
+			err = diffRecursive(nil, sub, full, readTree, out)
+			if err != nil {
+				return err
+			}
+		}
+
+		return nil
+	}
+
+	if b == nil {
+		for i := range a.Entries {
+			entry := &a.Entries[i]
+			full := joinPath(prefix, entry.Name)
+
+			*out = append(*out, Entry{Path: full, Kind: EntryKindDeleted, Old: entry, New: nil})
+			if entry.Mode != object.FileModeDir {
+				continue
+			}
+
+			sub, err := readTree(entry.ID)
+			if err != nil {
+				return err
+			}
+
+			err = diffRecursive(sub, nil, full, readTree, out)
+			if err != nil {
+				return err
+			}
+		}
+
+		return nil
+	}
+
+	i := 0
+
+	j := 0
+	for i < len(a.Entries) && j < len(b.Entries) {
+		left := &a.Entries[i]
+		right := &b.Entries[j]
+
+		cmp := object.TreeEntryNameCompare(
+			left.Name,
+			left.Mode,
+			right.Name,
+			right.Mode == object.FileModeDir,
+		)
+		switch {
+		case cmp < 0:
+			full := joinPath(prefix, left.Name)
+
+			*out = append(*out, Entry{Path: full, Kind: EntryKindDeleted, Old: left, New: nil})
+			if left.Mode == object.FileModeDir {
+				sub, err := readTree(left.ID)
+				if err != nil {
+					return err
+				}
+
+				err = diffRecursive(sub, nil, full, readTree, out)
+				if err != nil {
+					return err
+				}
+			}
+
+			i++
+		case cmp > 0:
+			full := joinPath(prefix, right.Name)
+
+			*out = append(*out, Entry{Path: full, Kind: EntryKindAdded, Old: nil, New: right})
+			if right.Mode == object.FileModeDir {
+				sub, err := readTree(right.ID)
+				if err != nil {
+					return err
+				}
+
+				err = diffRecursive(nil, sub, full, readTree, out)
+				if err != nil {
+					return err
+				}
+			}
+
+			j++
+		default:
+			full := joinPath(prefix, left.Name)
+
+			modified := left.Mode != right.Mode || left.ID != right.ID
+			if modified {
+				*out = append(*out, Entry{Path: full, Kind: EntryKindModified, Old: left, New: right})
+			}
+
+			if left.Mode == object.FileModeDir && right.Mode == object.FileModeDir && left.ID != right.ID {
+				leftSub, err := readTree(left.ID)
+				if err != nil {
+					return err
+				}
+
+				rightSub, err := readTree(right.ID)
+				if err != nil {
+					return err
+				}
+
+				err = diffRecursive(leftSub, rightSub, full, readTree, out)
+				if err != nil {
+					return err
+				}
+			}
+
+			i++
+			j++
+		}
+	}
+
+	for ; i < len(a.Entries); i++ {
+		left := &a.Entries[i]
+		full := joinPath(prefix, left.Name)
+
+		*out = append(*out, Entry{Path: full, Kind: EntryKindDeleted, Old: left, New: nil})
+		if left.Mode == object.FileModeDir {
+			sub, err := readTree(left.ID)
+			if err != nil {
+				return err
+			}
+
+			err = diffRecursive(sub, nil, full, readTree, out)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	for ; j < len(b.Entries); j++ {
+		right := &b.Entries[j]
+		full := joinPath(prefix, right.Name)
+
+		*out = append(*out, Entry{Path: full, Kind: EntryKindAdded, Old: nil, New: right})
+		if right.Mode == object.FileModeDir {
+			sub, err := readTree(right.ID)
+			if err != nil {
+				return err
+			}
+
+			err = diffRecursive(nil, sub, full, readTree, out)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
--