Documentation
¶
Overview ¶
Package merge provides three-way merge with pluggable strategies.
Register strategies at init time via Register, then look them up by name with StrategyByName. The built-in strategies are:
- ThreeWayText: line-level LCS-based merge with conflict markers
- Binary: treats any difference as a conflict
- LastWriterWins: always picks the remote side
- ConflictFork: creates a fork instead of merging
FindCommonAncestor walks the plink DAG to locate the merge base for two divergent checkins. DetectForks identifies open forks in a repository.
Index ¶
- func EnsureConflictTable(r *repo.Repo) error
- func FindCommonAncestor(r *repo.Repo, ridA, ridB libfossil.FslID) (libfossil.FslID, error)
- func ListConflictForks(r *repo.Repo) ([]string, error)
- func RecordConflictFork(r *repo.Repo, filename string, baseRID, localRID, remoteRID int64) error
- func Register(s Strategy)
- func ResolveConflictFork(r *repo.Repo, filename string) error
- type Binary
- type Conflict
- type ConflictFork
- type Fork
- type LastWriterWins
- type PatternRule
- type Resolver
- type Result
- type Strategy
- type ThreeWayText
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EnsureConflictTable ¶
EnsureConflictTable creates the conflict table if it doesn't exist. Follows Fossil conventions: REFERENCES blob for rids, julianday REAL for timestamps.
func FindCommonAncestor ¶
FindCommonAncestor walks the plink DAG backwards from two checkin rids to find their most recent common ancestor via bidirectional BFS.
func ListConflictForks ¶
ListConflictForks returns all unresolved conflict-fork entries.
func RecordConflictFork ¶
RecordConflictFork inserts a conflict-fork entry.
Types ¶
type Binary ¶
type Binary struct{}
Binary always returns a conflict. Binary files cannot be auto-merged.
type ConflictFork ¶
type ConflictFork struct{}
ConflictFork preserves all divergent versions without merging. Used for offline-first scenarios where conflicts accumulate. Stores references in a conflict table (Fossil-idiomatic schema).
func (*ConflictFork) Merge ¶
func (c *ConflictFork) Merge(base, local, remote []byte) (*Result, error)
func (*ConflictFork) Name ¶
func (c *ConflictFork) Name() string
type LastWriterWins ¶
type LastWriterWins struct{}
LastWriterWins picks the newer version. The caller passes the newer content as remote. Always clean — no conflicts possible.
func (*LastWriterWins) Merge ¶
func (l *LastWriterWins) Merge(base, local, remote []byte) (*Result, error)
func (*LastWriterWins) Name ¶
func (l *LastWriterWins) Name() string
type PatternRule ¶
PatternRule maps a glob pattern to a strategy name.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver picks the merge strategy for a given filename.
func LoadResolver ¶
LoadResolver reads the .libfossil-merge file from the repo at the given version, plus the merge-strategy config key as fallback.
type Result ¶
type Result struct {
Content []byte // merged output (may contain conflict markers)
Conflicts []Conflict // unresolved conflict regions
Clean bool // true if no conflicts
}
Result of a merge operation.
type Strategy ¶
Strategy merges three versions of content.
func StrategyByName ¶
StrategyByName returns a strategy implementation by name.
type ThreeWayText ¶
type ThreeWayText struct{}
ThreeWayText implements line-level 3-way merge.
Example ¶
package main
import (
"fmt"
"github.com/danmestas/libfossil/internal/merge"
)
func main() {
base := []byte("line 1\nline 2\nline 3\n")
local := []byte("line 1\nlocal change\nline 3\n")
remote := []byte("line 1\nline 2\nline 3\nremote addition\n")
result, err := (&merge.ThreeWayText{}).Merge(base, local, remote)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("clean:", result.Clean)
fmt.Print(string(result.Content))
}
Output: clean: true line 1 local change line 3 remote addition
func (*ThreeWayText) Merge ¶
func (t *ThreeWayText) Merge(base, local, remote []byte) (*Result, error)
func (*ThreeWayText) Name ¶
func (t *ThreeWayText) Name() string