GitWeave · Developer Docs GitWeave · Docs para devs

Snapshots vs Patches Snapshots vs Patches

The mathematical difference between how Git models your history and how GitWeave does it — and why it matters for deterministic merges and AI agents. La diferencia matemática entre cómo Git modela tu historial y cómo lo hace GitWeave — y por qué importa para merges determinísticos y agentes IA.

Git stores photographs Git guarda fotografías

Every Git commit is a complete snapshot of your file tree at a point in time. The diff you see in git diff is not stored — it's calculated on the fly by comparing two snapshots. The change itself doesn't exist as a first-class object. Cada commit de Git es un snapshot completo de tu árbol de archivos en un momento dado. El diff que ves en git diff no se guarda — se calcula al vuelo comparando dos snapshots. El cambio en sí no existe como objeto de primera clase.

Click through the commits to see what Git actually stores: Haz click en los commits para ver qué guarda Git realmente:

Git commit history — what's stored
S₀
init
S₁
add auth
S₂
fix routes
S₃
add tests
S₀ — complete file tree stored in .git/objects/
src/main.rsfn main() { println!("hello"); }42 bytes
Cargo.toml[package] name = "api" version = "0.1.0"38 bytes
⚠ Git stores the ENTIRE tree every commit. The "diff" in git log is computed by comparing S₀ and S₁ — it's not stored.
formal model — git History = { S₀, S₁, S₂, S₃, ... } // a sequence of complete states commit = S_prev × Δ → S_next // Δ is input, not stored diff = derived(S_n, S_{n+1}) // computed on demand
The consequence: Because the diff is derived and not stored, Git has no algebraic structure for merging. When two branches modify "the same zone," Git uses a 3-way merge heuristic that searches for a common ancestor. The result depends on the search — it's not guaranteed to be unique or correct. La consecuencia: Como el diff es derivado y no se guarda, Git no tiene estructura algebraica para hacer merge. Cuando dos ramas modifican "la misma zona", Git usa una heurística de 3-way merge que busca un ancestro común. El resultado depende de esa búsqueda — no está garantizado que sea único ni correcto.

GitWeave stores changes GitWeave guarda cambios

In GitWeave, the patch is the atom. The state of the repository at any moment is derived by composing patches together. The change is what's stored; the snapshot is computed on demand — the exact inverse of Git. En GitWeave, el patch es el átomo. El estado del repositorio en cualquier momento se deriva componiendo patches entre sí. El cambio es lo que se guarda; el snapshot se computa a demanda — el inverso exacto de Git.

A patch is a partial function over lines. "Partial" means it only touches the lines it actually changes — nothing else: Un patch es una función parcial sobre líneas. "Parcial" significa que solo toca las líneas que efectivamente cambia — nada más:

formal model — gitweave patch p : Lines → Lines // partial function, domain = lines it touches state = p₁ ∘ p₂ ∘ p₃ ∘ ... ∘ pₙ // state is DERIVED from patches patch_id = blake3(content + deps) // content-addressed, immutable

This is the critical property that changes everything — independence between patches: Esta es la propiedad clave que cambia todo — independencia entre patches:

dom(p) ∩ dom(q) = p and q are independent if their domains (lines they touch) don't intersect
dom(p) ∩ dom(q) = p ∘ q = q ∘ p Independence guarantees commutativity — order doesn't matter
Why this matters: If two patches commute, their merge is unique and deterministic — there is no choice to make. No "ours vs theirs." No heuristic. The algebra guarantees the result. Por qué importa: Si dos patches conmutan, su merge es único y determinístico — no hay elección que tomar. Sin "ours vs theirs". Sin heurística. El álgebra garantiza el resultado.

See a merge happen Ver un merge en vivo

Below is a 30-line file. Each cell represents a line. Agent A and Agent B each own a set of patches — toggle them on/off and watch whether the merge is clean or conflicted. Abajo hay un archivo de 30 líneas. Cada celda representa una línea. El Agente A y el Agente B tienen cada uno un set de patches — activa/desactiva y observa si el merge es limpio o conflictivo.

Hunk intersection visualizer
Toggle patches — watch the intersection
File lines (30 lines — each cell = 1 line)
Agent A Agent B Conflict Free
Merge result
✓ dom(A) ∩ dom(B) = ∅ — merge is instantaneous and deterministic

What is a conflict, exactly? ¿Qué es un conflicto, exactamente?

In Git, a "conflict" is whatever the 3-way merge heuristic decides is ambiguous. You can have two patches that touch "nearby" lines and get a conflict even if they're logically independent. En Git, un "conflicto" es lo que la heurística de 3-way merge decide que es ambiguo. Puedes tener dos patches que tocan líneas "cercanas" y obtener un conflicto aunque sean lógicamente independientes.

In GitWeave, a conflict has a precise mathematical definition: En GitWeave, un conflicto tiene una definición matemática precisa:

conflict — exact definition conflict(p, q) dom(p) ∩ dom(q) ≠ // Two patches conflict IF AND ONLY IF they touch the same lines. // No proximity heuristic. No "similar context" guessing. // Set intersection — binary, exact, reproducible.

And crucially: a conflict is itself a valid patch. It's an object that represents the state of indetermination. The system doesn't break — it produces a precise description of what needs resolving: Y crucialmente: un conflicto es en sí mismo un patch válido. Es un objeto que representa el estado de indeterminación. El sistema no se rompe — produce una descripción precisa de qué hay que resolver:

conflict as patch conflict_patch = { id: blake3(p.id || q.id), hunks: dom(p) ∩ dom(q), // exactly the contested lines state: Unresolved { a: p, b: q } } // A conflict tells you: "lines {5,6,7} are claimed by both p and q." // Nothing more, nothing less.
Git conflictConflicto en Git
"These changes are near each other and I can't decide which is correct. Here are both versions separated by <<<< markers." "Estos cambios están cerca entre sí y no puedo decidir cuál es correcto. Aquí tienes ambas versiones separadas por marcadores <<<<."
Ambiguous. Heuristic. Non-reproducible. Ambiguo. Heurístico. No reproducible.
GitWeave conflictConflicto en GitWeave
"Patches p3 and q2 both modify lines {12, 13, 14}. Intersection is non-empty. Here is the exact set." "Los patches p3 y q2 modifican las líneas {12, 13, 14}. La intersección no es vacía. Aquí tienes el conjunto exacto."
Precise. Mathematical. Always reproducible. Preciso. Matemático. Siempre reproducible.

The pushout — why merge works El pushout — por qué funciona el merge

The formal foundation comes from category theory (Mimram & Di Giusto, 2013). A merge of two patches is a pushout in the category of repository states. El fundamento formal viene de la teoría de categorías (Mimram & Di Giusto, 2013). Un merge de dos patches es un pushout en la categoría de estados del repositorio.

Pushout diagram — merge as categorical construction
A base state B after patch p C after patch q D merged state p q q' p' pushout exists & is unique ⟺ dom(p) ∩ dom(q) = ∅
The pushout D exists and is unique when p and q are independent. Unique = no ambiguity = deterministic merge. If the pushout doesn't exist, there's a genuine conflict. El pushout D existe y es único cuando p y q son independientes. Único = sin ambigüedad = merge determinístico. Si el pushout no existe, hay un conflicto genuino.
category theory summary Objects: repository states (A, B, C, D) Morphisms: patches between states (p: A→B, q: A→C) Merge(p, q) = pushout(p, q) pushout exists & unique no conflict deterministic pushout does not exist genuine conflict resolve explicitly

The complete comparison La comparación completa

ConceptConcepto Git (snapshots)Git (snapshots) GitWeave (patches)GitWeave (patches)
First-class objectObjeto de primera clase State (snapshot)Estado (snapshot) Change (patch)Cambio (patch)
Derived objectObjeto derivado Diff (computed on demand)Diff (computado a demanda) State (composed from patches)Estado (compuesto desde patches)
Identity of a changeIdentidad del cambio Commit hash (includes tree, parent, metadata) Hash del commit (incluye árbol, padre, metadata) blake3(content + deps) — content-addressed blake3(contenido + deps) — identificado por contenido
Merge modelModelo de merge 3-way merge heuristic (find common ancestor) Heurística 3-way (busca ancestro común) Set intersection of domains — algebraic Intersección de dominios — algebraico
CommutativityConmutatividad Not guaranteed — merge(A,B) ≠ merge(B,A) No garantizada — merge(A,B) ≠ merge(B,A) Guaranteed when dom(p)∩dom(q) = ∅ Garantizada cuando dom(p)∩dom(q) = ∅
Conflict definitionDefinición de conflicto Heuristic ambiguity near common ancestor Ambigüedad heurística cerca del ancestro común dom(p) ∩ dom(q) ≠ ∅ — exact set of contested lines dom(p) ∩ dom(q) ≠ ∅ — conjunto exacto de líneas en disputa
Parallel agentsAgentes en paralelo Must serialize through branch/merge ceremony Serialización obligatoria via ceremonia de ramas/merge N WorkSlots — independent by construction N WorkSlots — independientes por construcción
Theoretical basisBase teórica None (operational, designed by Torvalds) Ninguna (operacional, diseñado por Torvalds) Category theory pushouts (Mimram & Di Giusto 2013) Pushouts de teoría de categorías (Mimram & Di Giusto 2013)
The one-line takeaway: Git asks "what does the file look like now?" — and derives changes from that. GitWeave asks "what changed?" — and derives the current state from that. The inversion gives you algebraic merges, deterministic results, and an API that AI agents can operate safely without human supervision. La idea en una línea: Git pregunta "¿cómo se ve el archivo ahora?" — y deriva los cambios desde eso. GitWeave pregunta "¿qué cambió?" — y deriva el estado actual desde eso. Esa inversión te da merges algebraicos, resultados determinísticos, y una API que los agentes IA pueden operar de forma segura sin supervisión humana.