ifc-commit/docs/merge_native.md
2026-03-25 10:36:30 +01:00

152 lines
5.2 KiB
Markdown

# Native IFC Merging with ifcmerge
How [ifcmerge](https://github.com/brunopostle/ifcmerge) relates to the ifc-commit
pipeline, and when to use it instead of (or alongside) `ifcpatch MergeProjects`.
---
## What is ifcmerge?
ifcmerge is a **three-way merge tool for IFC/STEP files**, written by Bruno
Postle (GPLv3, 2022). It brings software-development-style branching workflows
to BIM files stored in git.
Basic usage:
```bash
ifcmerge base.ifc local_fork.ifc remote_fork.ifc merged.ifc
```
It can be registered as a git mergetool:
```bash
git config --global mergetool.ifcmerge.cmd \
'ifcmerge $BASE $LOCAL $REMOTE $MERGED'
git config --global mergetool.ifcmerge.trustExitCode true
```
Then on a merge conflict:
```bash
git merge feature-branch
git mergetool --tool=ifcmerge
```
---
## How it works
IFC files are encoded in the STEP Physical File (SPF) format. Each entity has a
numeric id (`#514`, `#819`, …). ifcmerge uses these ids as stable keys — not
line numbers — to track changes between versions.
Given three versions of the **same model**:
1. **Analysis** — identifies which entity ids were added, deleted, or modified
in each branch relative to the common ancestor.
2. **ID renumbering** — newly-added entities from one branch are renumbered to
avoid collisions with the other branch.
3. **Attribute-level merge** — if branch A changed `Name` and branch B changed
`Representation` on the same entity, both changes are applied. No conflict.
4. **List merging** — list-valued attributes (e.g. `IfcRelContainedInSpatialStructure.RelatedElements`)
support independent additions and deletions from each branch.
5. **Conflict detection** — if an entity is **deleted in one branch but modified
in the other**, ifcmerge refuses and exits non-zero. Manual resolution required.
---
## ifcmerge vs `MergeProjects`
These tools solve **different problems**:
| Aspect | ifcmerge | ifcpatch `MergeProjects` |
|--------|----------|--------------------------|
| Purpose | Reconcile two divergent edits of the **same** model | Combine two **independent** models |
| Common ancestor | Required | Not applicable |
| Conflict detection | Yes — delete/modify conflicts | None |
| ID handling | Renumbers only new entities | Renumbers all entities from one side |
| Attribute merging | Attribute-by-attribute within same entity | No concept of same-entity merging |
| Git integration | Designed as a git mergetool | No relation to version control |
| Use case | Concurrent editing by multiple contributors | Federation / composing discipline models |
**In short:**
- Use `MergeProjects` (via `ifccommit insert` or `ifccommit replace`) to **compose**
models — e.g. merging an extracted and modified space back into the original.
- Use `ifcmerge` to **reconcile** concurrent edits — e.g. two contributors
independently edited the same model on separate branches.
---
## Relevance for ifc-commit
The ifc-commit pipeline operates as:
```
extract → modify → replace
```
This is a **sequential** workflow: one person extracts a space, modifies it,
and merges it back. ifcmerge adds value when the workflow becomes **concurrent**:
```
┌── contributor A: moves furniture ──┐
base ┤ ├→ ifcmerge → merged.ifc
└── contributor B: renames spaces ──┘
```
A git-based BIM workflow combining both tools:
```bash
# Both contributors branch from the same model
git checkout -b feature/move-table
# A edits duplex.ifc (moves table)
git commit -m "move coffee table in A102"
git checkout main
git checkout -b feature/rename-spaces
# B edits duplex.ifc (renames spaces)
git commit -m "rename spaces to long names"
# Merge B's changes into A's branch
git checkout feature/move-table
git merge feature/rename-spaces
# conflict on duplex.ifc → resolve with ifcmerge
git mergetool --tool=ifcmerge
git commit -m "merge: move table + rename spaces"
```
---
## Installation
ifcmerge is **not a Python package** — it cannot be installed with `uv add`.
| Platform | Method |
|----------|--------|
| Linux / macOS | Clone repo, put the `ifcmerge` Perl script on `$PATH` |
| Windows | Download pre-built `ifcmerge.exe` from the GitHub releases page |
| Rust port | Experimental binary available in the 2025-01-26 release |
---
## Limitations
- **Native IFC required** — only works if the editing application writes IFC
with stable entity ids. Applications that regenerate all ids on export
(Revit, ArchiCAD in export mode) are incompatible.
- **Delete/modify conflicts** — cannot auto-resolve; user must abort the merge
and resolve manually.
- **No parametric logic** — IFC captures geometry, not design intent. Two
branches that drive geometry from incompatible parameter sets may produce
geometrically inconsistent results.
- **Experimental Rust port** — the Perl implementation is the stable one.
- **Large file handling** — git forges cap LFS file sizes; large projects
(> 1 GB) need a self-hosted instance.
---
## References
- [ifcmerge GitHub](https://github.com/brunopostle/ifcmerge)
- [Porto OpenBIM Hackathon 2026](http://porto.gitaec.org)
- [Git-based IFC example by Bruno Postle](https://gitaec.org/brunopostle/creative-freedom)