Some checks failed
Build and Test / build (pull_request) Failing after 2m2s
Add Category column to Phase 2 cherry-pick table: - 16 × Category 1 (Extension points) — KEEP - 16 × Category 2 (Branding/theming) — KEEP, minimize - 4 × Category 3 (Bug fixes) — UPSTREAM candidates Add upstream verification for Category 3 patches: - #26/#27 (Wayland scaling, menu icon size): partially upstream, menu pref not contributed - #31 (window flickering): not upstream, good PR candidate - #33 (ToolBarItem/reportException): Kindred-internal only Update Assembly fixes with verified upstream status: - All 4 patches still needed (joint flip, SIGSEGV, datum plane/point handling) - App::Line handling fixed upstream via FreeCAD PR#20026 Closes #254.
292 lines
17 KiB
Markdown
292 lines
17 KiB
Markdown
# Upstream Merge Plan: FreeCAD 1.0.0 → 1.2.0-dev
|
||
|
||
**Date:** February 2026
|
||
**Status:** Planning
|
||
|
||
## Overview
|
||
|
||
Kindred Create (`origin/main`) is based on FreeCAD 1.0.0 with ~193 Kindred-specific commits layered on top. The upstream fork (`upstream/main` at `github.com/Kindred-Systems/FreeCAD`) tracks FreeCAD development and is currently at **1.2.0-dev**. The two repositories diverged early and have ~45k commits each from a very old merge base — a traditional `git merge` is not feasible.
|
||
|
||
**Goal:** Forward-port all Kindred customizations onto the latest `upstream/main` (FreeCAD 1.2.0-dev) to pick up bug fixes and new features while preserving all Kindred functionality.
|
||
|
||
## Strategy: Diff-Based Forward Port
|
||
|
||
1. Create a new branch from `upstream/main`
|
||
2. Copy Kindred-only files/directories wholesale (no conflicts)
|
||
3. Cherry-pick or manually re-apply the ~36 C++ source patches
|
||
4. Build, test, and validate
|
||
|
||
---
|
||
|
||
## Remotes
|
||
|
||
| Remote | URL | Role |
|
||
|--------|-----|------|
|
||
| `origin` | `git.kindred-systems.com/kindred/create` | Kindred Create (current main) |
|
||
| `upstream` | `github.com/Kindred-Systems/FreeCAD` | FreeCAD fork tracking upstream development |
|
||
| `internal` | `gitea.kindred.internal:kindred/create-0070` | Internal mirror |
|
||
|
||
---
|
||
|
||
## Phase 1: Copy Kindred-Only Files (No Conflicts)
|
||
|
||
These files/directories exist only in Kindred Create and can be copied directly onto `upstream/main` without conflict.
|
||
|
||
### New directories (copy wholesale)
|
||
|
||
| Directory | Description |
|
||
|-----------|-------------|
|
||
| `icons/kindred/` | 1444 Catppuccin Mocha SVG icon overrides |
|
||
| `mods/silo/` | Silo workbench submodule (`silo-mod`) |
|
||
| `mods/ztools/` | ZTools workbench submodule |
|
||
| `src/Mod/Create/` | Kindred Create workbench (InitGui.py, kc_format.py, update_checker.py, version.py.in) |
|
||
| `package/` | rattler-build packaging recipe |
|
||
| `docs/` | Kindred documentation (architecture, specifications, guides) |
|
||
| `.gitea/` | CI workflows, issue templates, runner configs |
|
||
|
||
### New files in existing directories
|
||
|
||
| File | Description |
|
||
|------|-------------|
|
||
| `src/Gui/FileOrigin.cpp/.h` | Origin abstraction layer |
|
||
| `src/Gui/FileOriginPython.cpp/.h` | Python bridge for origins |
|
||
| `src/Gui/OriginManager.cpp/.h` | Origin manager singleton |
|
||
| `src/Gui/OriginManagerDialog.cpp/.h` | Origin management dialog |
|
||
| `src/Gui/OriginSelectorWidget.cpp/.h` | Toolbar origin selector |
|
||
| `src/Gui/CommandOrigin.cpp` | PLM origin commands (Commit/Pull/Push/Info/BOM) |
|
||
| `src/Gui/BreadcrumbToolBar.cpp/.h` | Breadcrumb navigation bar |
|
||
| `src/Gui/EditingContext.cpp/.h` | Editing context system |
|
||
| `src/Gui/Icons/kindred-create.svg` | App icon |
|
||
| `src/Gui/Icons/kindredcreateabout.png` | About dialog image |
|
||
| `src/Gui/Icons/kindredcreatesplash*.png` | Splash screen images |
|
||
| `src/Gui/Icons/silo-*.svg` | Silo command icons (6 files) |
|
||
| `src/Gui/PreferencePacks/KindredCreate/` | Theme preference pack |
|
||
| `src/Gui/Stylesheets/KindredCreate.qss` | QSS stylesheet |
|
||
| `src/Gui/Stylesheets/parameters/KindredCreate.yaml` | Theme parameters |
|
||
| `src/Gui/Stylesheets/images_dark-light/branch_*_dark.svg` | Tree branch line SVGs (7 files) |
|
||
| `resources/kindred-create.*` | Platform file associations (ico, icns, xml, desktop) |
|
||
| `banner-logo-light.png` | Repository banner |
|
||
| `CONTRIBUTING.md` | Contribution guidelines |
|
||
|
||
---
|
||
|
||
## Phase 2: Cherry-Pick Core Changes (Conflict Risk)
|
||
|
||
36 Kindred commits touch core FreeCAD C++ files. Of those, **38 files** also changed on `upstream/main`, creating potential conflicts. Listed in chronological order (oldest first) for cherry-pick sequence.
|
||
|
||
### Category legend
|
||
|
||
| Category | Meaning | Long-term plan |
|
||
|----------|---------|----------------|
|
||
| **1 — Extension** | Platform extension points for Python addons. Core differentiator. | KEEP — maintain and isolate |
|
||
| **2 — Branding** | Branding and theming. Unavoidable in a fork. | KEEP — minimize surface area |
|
||
| **3 — Bug fix** | Bug fixes and polish applicable to upstream FreeCAD. | UPSTREAM — contribute and eliminate |
|
||
|
||
### Commit sequence
|
||
|
||
| # | Hash | Summary | Category | Conflict Risk | Files |
|
||
|---|------|---------|----------|---------------|-------|
|
||
| 1 | `316d4f4b524` | Initial branding (CMakeLists, splash, about, theme, icons, QRC) | 2 — Branding | **HIGH** — CMakeLists.txt, DlgAbout.cpp, SplashScreen.cpp, resource.qrc all changed upstream | 14 files |
|
||
| 2 | `8c6837cc152` | Theme padding/clipping fixes | 2 — Branding | LOW — KindredCreate.qss is new file | 1 file |
|
||
| 3 | `bb3f3ac6d6c` | Dock task panel right, remove non-Kindred themes | 2 — Branding | **MEDIUM** — MainWindow.cpp, PreferencePacks CMakeLists changed upstream | 8 files |
|
||
| 4 | `e85162947b7` | Startup theme selector fix | 2 — Branding | **MEDIUM** — StartupProcess.cpp changed upstream | 4 files |
|
||
| 5 | `eb80c07f57a` | Theme QSS refinements | 2 — Branding | LOW — Kindred-only files | 4 files |
|
||
| 6 | `8639b6fd8ab` | Resolve unknown command/style token errors | 2 — Branding | **MEDIUM** — StartupProcess.cpp | 5 files |
|
||
| 7 | `fea1280fa90` | Theme alternate-background-color | 2 — Branding | LOW | 2 files |
|
||
| 8 | `b3fedfb19fb` | Theme tree item padding | 2 — Branding | LOW | 2 files |
|
||
| 9 | `0d4545b7d67` | Tree branch line SVGs | 2 — Branding | LOW — new files | 8 files |
|
||
| 10 | `434ae797a43` | Theme selector cleanup | 2 — Branding | **MEDIUM** — StartupProcess.cpp | 4 files |
|
||
| 11 | `224feda4ad6` | Catppuccin icon override infrastructure | 2 — Branding | **MEDIUM** — BitmapFactory.cpp, CMakeLists.txt | 2 files |
|
||
| 12 | `7535a48ec4c` | Origin abstraction layer | 1 — Extension | **HIGH** — Application.cpp, ApplicationPy.cpp/.h, CMakeLists.txt | 6 files (4 new) |
|
||
| 13 | `38358e431d2` | LocalFileOrigin and Std_* delegation | 1 — Extension | **HIGH** — CommandDoc.cpp, FileOrigin.cpp/.h | 3 files |
|
||
| 14 | `79c85ed2e5d` | FileOriginPython interactive methods | 1 — Extension | LOW — Kindred-only files | 3 files |
|
||
| 15 | `deeb6376f71` | OriginSelectorWidget | 1 — Extension | **HIGH** — Action.cpp/.h, CommandStd.cpp, Workbench.cpp, CMakeLists.txt | 8 files |
|
||
| 16 | `679aaec6d49` | Origin commands (Commit/Pull/Push) | 1 — Extension | **MEDIUM** — Application.cpp, Command.h, Workbench.cpp | 5 files |
|
||
| 17 | `db85277f262` | OriginManagerDialog | 1 — Extension | LOW — new files + OriginSelectorWidget.cpp | 3 files |
|
||
| 18 | `015df38328c` | Document-origin tracking in window title | 1 — Extension | **MEDIUM** — MDIView.cpp | 3 files |
|
||
| 19 | `a6e84552da5` | Cross-origin detection in SaveAs | 1 — Extension | **MEDIUM** — CommandDoc.cpp | 1 file |
|
||
| 20 | `84b69b935b2` | Build fix: remove SelectModule.h include | 1 — Extension | LOW | 1 file |
|
||
| 21 | `2f594dac0a5` | Use Python API for viewDefaultOrientation | 1 — Extension | **MEDIUM** — CommandDoc.cpp | 1 file |
|
||
| 22 | `724440dcb75` | Build fixes for OriginSelectorWidget/Manager | 1 — Extension | LOW — Kindred files | 2 files |
|
||
| 23 | `c858706d480` | Add silo icons to QRC | 2 — Branding | LOW — resource.qrc (additive) | 6 files |
|
||
| 24 | `d95c850b7b1` | Widen origin selector widget | 1 — Extension | LOW | 1 file |
|
||
| 25 | `10b5c9d584f` | Wire OriginManagerDialog to Silo_Settings | 1 — Extension | LOW | 1 file |
|
||
| 26 | `cc5ba638d1f` | UI polish — Wayland scaling, menu icon size | 3 — Bug fix | **HIGH** — DlgSettingsGeneral.cpp/.h/.ui changed upstream | 6 files |
|
||
| 27 | `4bf74cf3391` | Build fix for DlgSettingsGeneral | 3 — Bug fix | **MEDIUM** — DlgSettingsGeneral.h, StartupProcess.cpp | 2 files |
|
||
| 28 | `6773ca0dfd8` | Eliminate QSS/CFG duplication | 2 — Branding | LOW — Kindred files | 3 files |
|
||
| 29 | `977fa3c9347` | QGroupBox indicator, hyperlink color | 2 — Branding | LOW — KindredCreate.qss | 1 file |
|
||
| 30 | `8b2ce4b73a4` | Native Qt start panel + kindred:// URL | 1 — Extension | **MEDIUM** — MainWindow.cpp | 1 file |
|
||
| 31 | `bf637af4e45` | Window flickering and icon clipping fix | 3 — Bug fix | **MEDIUM** — MainWindow.cpp/.h | 3 files |
|
||
| 32 | `70118201b02` | MDI pre-document tab for Silo new item | 1 — Extension | **HIGH** — ApplicationPy, BreadcrumbToolBar, EditingContext, MainWindow, Workbench | 11 files |
|
||
| 33 | `1f49e3fa6da` | Build fix: ToolBarItem incomplete type, reportException | 3 — Bug fix | **LOW** — Kindred-specific build fix | 2 files |
|
||
| 34 | `f71decca089` | Splash screen: skip runtime draw, mantle bg | 2 — Branding | **MEDIUM** — SplashScreen.cpp | 3 files |
|
||
| 35 | `2b0c6774c07` | Dev build defaults, skip version migration | 2 — Branding | **MEDIUM** — CMakeLists.txt, DlgVersionMigrator.cpp | 2 files |
|
||
| 36 | `ab71902a4c2` | Forward visibility arg in appendToolbar() | 1 — Extension | LOW — FreeCADGuiInit.py | 1 file |
|
||
|
||
### Category summary
|
||
|
||
| Category | Count | Commits |
|
||
|----------|-------|---------|
|
||
| 1 — Extension | 16 | #12–22, #24–25, #30, #32, #36 |
|
||
| 2 — Branding | 16 | #1–11, #23, #28–29, #34–35 |
|
||
| 3 — Bug fix | 4 | #26–27, #31, #33 |
|
||
|
||
### Category 3 — Upstream status (verified Feb 2026)
|
||
|
||
| # | Summary | Upstream Fixed? | FreeCAD Issues | Notes |
|
||
|---|---------|-----------------|----------------|-------|
|
||
| 26 | Wayland scaling, menu icon size pref | PARTIAL | [#25448](https://github.com/FreeCAD/FreeCAD/issues/25448), [#23830](https://github.com/FreeCAD/FreeCAD/issues/23830), [#23396](https://github.com/FreeCAD/FreeCAD/issues/23396) | Upstream has some HiDPI C++ fixes but Wayland fractional scaling still open. Menu icon size pref is a Kindred-added feature, not yet contributed. |
|
||
| 27 | Build fix for DlgSettingsGeneral | NO | — | Companion to #26. `setMenuIconSize()` in StartupProcess is Kindred-added. |
|
||
| 31 | Window flickering and icon clipping | NO | [#12917](https://github.com/FreeCAD/FreeCAD/issues/12917), [#18481](https://github.com/FreeCAD/FreeCAD/issues/18481) | Upstream still uses `setStyleSheet()` on statusBar causing repaint cascade. Good upstream PR candidate — replace with `setPalette()`. |
|
||
| 33 | ToolBarItem incomplete type, reportException | N/A | — | Kindred-internal build fix. The `ToolBarItem` forward-decl issue only manifests with Kindred modifications to Workbench.h. The `reportException` typo is in Kindred-only editing context code. |
|
||
|
||
### HIGH conflict files (need manual attention)
|
||
|
||
These files are modified by both Kindred and upstream. They will almost certainly require manual conflict resolution:
|
||
|
||
| File | Kindred Changes | Upstream Risk |
|
||
|------|----------------|---------------|
|
||
| `CMakeLists.txt` | Kindred version vars, build config | Upstream version bumps, new modules |
|
||
| `src/Gui/Application.cpp` | Origin system registration | Core refactoring |
|
||
| `src/Gui/ApplicationPy.cpp/.h` | `addFileOrigin()`, MDI tab API | API changes |
|
||
| `src/Gui/CommandDoc.cpp` | Origin delegation, cross-origin SaveAs, viewDefaultOrientation | Save/open refactoring |
|
||
| `src/Gui/Action.cpp/.h` | OriginSelectorWidget toolbar action | Toolbar system changes |
|
||
| `src/Gui/MainWindow.cpp/.h` | Task panel docking, start panel, flicker fix | UI restructuring |
|
||
| `src/Gui/Workbench.cpp/.h` | Origin selector, toolbar visibility, ToolBarItem include | Workbench changes |
|
||
| `src/Gui/SplashScreen.cpp` | Kindred branding, skip runtime draw | Splash updates |
|
||
| `src/Gui/StartupProcess.cpp/.h` | Theme selector, menu icon size | Startup flow changes |
|
||
| `src/Gui/CMakeLists.txt` | New source files (Origin*, BreadcrumbToolBar, EditingContext) | New upstream sources |
|
||
| `src/Gui/DlgSettingsGeneral.cpp/.h/.ui` | Menu icon size preference | Settings UI changes |
|
||
|
||
---
|
||
|
||
## Phase 3: Module-Level Changes
|
||
|
||
### Assembly fixes (verified Feb 2026)
|
||
|
||
| Hash | Summary | Upstream Status | Action |
|
||
|------|---------|-----------------|--------|
|
||
| `316d4f4b524` | Joint flip overconstrain fix (91° rotation guard) | **NOT fixed** — upstream has basic grounded-object validation only. [FreeCAD#20377](https://github.com/FreeCAD/FreeCAD/issues/20377) open. | KEEP — re-apply |
|
||
| `9dc50cef727` | SIGSEGV during document restore (`isRestoring()` guard) | **NOT fixed** — upstream `onChanged()` has no restore guard. [FreeCAD#18225](https://github.com/FreeCAD/FreeCAD/issues/18225) closed via different path. | KEEP — re-apply |
|
||
| `ddefb236521` | Solver ignoring datum plane refs (`PartDesign::Plane`/`Point`) | **NOT fixed** — upstream `findPlacement()` lacks these types. | KEEP — re-apply, upstream candidate |
|
||
| `b7374d7b1fc` | findPlacement() datum/origin handling (`App::Plane`/`Point`) | **PARTIAL** — `App::Line` fixed upstream via [PR#20026](https://github.com/FreeCAD/FreeCAD/pull/20026). `App::Plane`/`App::Point` still missing. | KEEP — re-apply the `Plane`/`Point` parts only |
|
||
|
||
Files touched: `src/Mod/Assembly/App/AssemblyObject.cpp`, `src/Mod/Assembly/UtilsAssembly.py`, `src/Mod/Assembly/InitGui.py`
|
||
|
||
### FreeCADInit.py
|
||
|
||
| Hash | Summary |
|
||
|------|---------|
|
||
| (Layer 1 `.kc`) | `addImportType` includes `*.kc` |
|
||
|
||
### FreeCADGuiInit.py
|
||
|
||
| Hash | Summary |
|
||
|------|---------|
|
||
| `ab71902a4c2` | Forward visibility arg in `appendToolbar()` |
|
||
|
||
---
|
||
|
||
## Phase 4: Build System and Packaging
|
||
|
||
| Item | Action |
|
||
|------|--------|
|
||
| `CMakeLists.txt` | Re-apply Kindred version variables on top of upstream 1.2.0-dev |
|
||
| `package/rattler-build/recipe.yaml` | Update for new version, verify dependency pins |
|
||
| `.gitea/workflows/` | Verify CI still works with updated source |
|
||
| Submodule pins | Re-add `mods/silo`, `mods/ztools` submodules |
|
||
| `src/3rdParty/OndselSolver` | Verify our fork is still needed or if upstream fixed the issues |
|
||
|
||
---
|
||
|
||
## Phase 5: Validation
|
||
|
||
1. **Build**: Full CMake configure + build succeeds
|
||
2. **Launch**: Application starts without errors, splash and about dialogs show Kindred branding
|
||
3. **Theme**: KindredCreate theme loads correctly, QSS applies
|
||
4. **Icons**: icon override system works (BitmapFactory loads from icons/kindred/)
|
||
5. **Origin system**: FileOrigin, OriginManager, OriginSelectorWidget functional
|
||
6. **Silo integration**: Auth panel, activity panel, save/commit/pull all work
|
||
7. **File format**: `.kc` files open/save with silo/ directory preserved
|
||
8. **Assembly**: Verify assembly fixes aren't regressed (or confirm upstream fixed them)
|
||
9. **Start panel**: Native Qt start panel loads
|
||
10. **URL scheme**: `kindred://` URL handling works
|
||
|
||
---
|
||
|
||
## Execution Steps
|
||
|
||
```bash
|
||
# 1. Ensure upstream is fetched
|
||
git fetch upstream
|
||
|
||
# 2. Create forward-port branch from upstream/main
|
||
git checkout -b kindred-on-upstream-1.2 upstream/main
|
||
|
||
# 3. Copy Kindred-only directories
|
||
git checkout origin/main -- icons/ mods/ src/Mod/Create/ package/ docs/ \
|
||
.gitea/ resources/kindred* banner-logo-light.png CONTRIBUTING.md .gitmodules
|
||
|
||
# 4. Copy new Kindred source files (no conflicts)
|
||
git checkout origin/main -- \
|
||
src/Gui/FileOrigin.cpp src/Gui/FileOrigin.h \
|
||
src/Gui/FileOriginPython.cpp src/Gui/FileOriginPython.h \
|
||
src/Gui/OriginManager.cpp src/Gui/OriginManager.h \
|
||
src/Gui/OriginManagerDialog.cpp src/Gui/OriginManagerDialog.h \
|
||
src/Gui/OriginSelectorWidget.cpp src/Gui/OriginSelectorWidget.h \
|
||
src/Gui/CommandOrigin.cpp \
|
||
src/Gui/BreadcrumbToolBar.cpp src/Gui/BreadcrumbToolBar.h \
|
||
src/Gui/EditingContext.cpp src/Gui/EditingContext.h \
|
||
src/Gui/Icons/kindred-create.svg src/Gui/Icons/kindredcreateabout.png \
|
||
src/Gui/Icons/kindredcreatesplash.png src/Gui/Icons/kindredcreatesplash_2x.png \
|
||
src/Gui/Icons/silo-bom.svg src/Gui/Icons/silo-commit.svg \
|
||
src/Gui/Icons/silo-info.svg src/Gui/Icons/silo-pull.svg \
|
||
src/Gui/Icons/silo-push.svg \
|
||
src/Gui/PreferencePacks/KindredCreate/ \
|
||
src/Gui/Stylesheets/KindredCreate.qss \
|
||
src/Gui/Stylesheets/parameters/KindredCreate.yaml \
|
||
src/Gui/Stylesheets/images_dark-light/
|
||
|
||
# 5. Cherry-pick core changes (oldest to newest)
|
||
# Resolve conflicts as they arise
|
||
git cherry-pick 316d4f4b524 # Initial branding
|
||
git cherry-pick 8c6837cc152 # Theme padding
|
||
# ... (continue through all 36 commits)
|
||
git cherry-pick ab71902a4c2 # appendToolbar visibility
|
||
|
||
# 6. Apply .kc format Layer 1 changes
|
||
# (These were written against 1.0.0, re-apply on 1.2.0-dev)
|
||
|
||
# 7. Build and test
|
||
cmake -B build -S . && cmake --build build
|
||
|
||
# 8. Push and create PR
|
||
git push -u origin kindred-on-upstream-1.2
|
||
```
|
||
|
||
---
|
||
|
||
## Risk Mitigation
|
||
|
||
- **Checkpoint after each cherry-pick**: Commit progress so partial work isn't lost
|
||
- **Build after each batch**: Group related commits (e.g., all theme commits) and build after each group
|
||
- **Skip already-fixed commits**: Some bug fixes (Assembly, build errors) may already be resolved upstream — check before cherry-picking
|
||
- **Test incrementally**: Don't wait until all 36 commits are applied to test
|
||
|
||
## Estimated Effort
|
||
|
||
| Phase | Effort |
|
||
|-------|--------|
|
||
| Phase 1 (copy wholesale) | ~30 min |
|
||
| Phase 2 (cherry-pick 36 commits) | ~4-8 hours (conflict resolution) |
|
||
| Phase 3 (module changes) | ~1 hour |
|
||
| Phase 4 (build system) | ~1-2 hours |
|
||
| Phase 5 (validation) | ~2-3 hours |
|
||
|
||
## Future: Staying in Sync
|
||
|
||
After this merge, establish a recurring upstream sync process:
|
||
1. Track `upstream/main` with periodic merges (weekly or per-release)
|
||
2. Keep Kindred changes as isolated as possible (separate files > modifying upstream files)
|
||
3. Consider upstreaming non-Kindred-specific fixes to the FreeCAD fork
|