In-Depth Document Diff And Staging Testing
This plan creates one reusable git repository that exercises document diff behavior across working tree, staging, and commit modes, plus staging behavior for snapshots and deleted files. The flow is designed so one repository can be kept and reused for regression checks after code changes.
It includes testing snapshot error scenarios, such as snapshot missing or corrupted, and how diffs behave in each.
Create one repository with these document scenarios:
| File | Scenario |
|---|---|
clean_open.FCStd | open, unchanged |
modified_parametric.FCStd | real parametric diff |
modified_binary_only.FCStd | git changed, no parametric diff |
deleted.FCStd | deleted document |
added.FCStd | new document |
missing_old_snapshot.FCStd | old YAML missing |
missing_new_snapshot.FCStd | new YAML missing |
invalid_old_snapshot.FCStd | old YAML invalid |
invalid_new_snapshot.FCStd | new YAML invalid |
Expected mode coverage:
- Working tree mode: dirty files plus open eligible docs.
- Staging mode: staged files only.
- Commit mode: files changed in selected commit.
Phase 0 - Create Manual Test Repo
Section titled “Phase 0 - Create Manual Test Repo”- Create repository:
mkdir ~/fc-history-manual-testcd ~/fc-history-manual-testgit init-
Open FreeCAD with History workbench enabled.
-
Create these documents in repo root:
clean_open.FCStdmodified_parametric.FCStdmodified_binary_only.FCStddeleted.FCStdmissing_old_snapshot.FCStdmissing_new_snapshot.FCStdinvalid_old_snapshot.FCStdinvalid_new_snapshot.FCStd- Recommended contents:
- each file should have drastically different model contents, dimensions, and object names from the others
- avoid creating near-duplicates, because when
deleted.FCStdis removed andadded.FCStdis introduced, git may detect a rename instead of separate delete and add events modified_parametric.FCStduses an obvious dimension such as Box Length10 mm- save all files
- In History workbench, run Stage Documents for all open docs.
Expected:
.history_snapshots/.../*.yamlfiles created- FCStd files staged
- YAML snapshot files staged
- Before committing, remove baseline YAML for
missing_old_snapshot.FCStdfrom index and disk:
git restore --staged .history_snapshots/missing_old_snapshot.yamlrm .history_snapshots/missing_old_snapshot.yamlUse actual generated YAML path if different.
- Corrupt baseline YAML for
invalid_old_snapshot.FCStd:
printf 'not: [valid\n' > .history_snapshots/invalid_old_snapshot.yamlgit add .history_snapshots/invalid_old_snapshot.yaml- Commit baseline:
git add .git commit -m "baseline manual history test repo"Expected baseline state:
- all FCStd committed
- most YAML committed
missing_old_snapshot.FCStdhas no committed YAMLinvalid_old_snapshot.FCStdhas invalid committed YAML
Phase 1 - Create Working Tree Changes
Section titled “Phase 1 - Create Working Tree Changes”In FreeCAD:
- Keep or open
clean_open.FCStd. Do not change it. - Open
modified_parametric.FCStd. Change real model parameter, for example Box Length10 -> 20. Save. - Open
modified_binary_only.FCStd. Save without semantic model changes. - If git does not mark it dirty, change view-only or non-parametric metadata if possible, then save again.
- Create
added.FCStd. Add simple object that is clearly different fromdeleted.FCStd. Save. - Delete
deleted.FCStdfrom disk:
rm deleted.FCStd- Open and modify
missing_old_snapshot.FCStdwith real parametric change. Save. - Open and modify
missing_new_snapshot.FCStdwith real parametric change. Save. - Open and modify
invalid_old_snapshot.FCStdwith real parametric change. Save. - Open and modify
invalid_new_snapshot.FCStdwith real parametric change. Save.
Do not stage yet.
Phase 2 - Test Working Tree Mode Before Staging
Section titled “Phase 2 - Test Working Tree Mode Before Staging”Open diff UI in Working Tree mode.
Expected rows:
| File | Expected document state | Expected issues |
|---|---|---|
clean_open.FCStd | UNCHANGED | none |
modified_parametric.FCStd | MODIFIED | none, tree diff visible |
modified_binary_only.FCStd | MODIFIED | GIT_CHANGED_NO_PARAMETRIC_DIFF, empty or no tree changes |
deleted.FCStd | DELETED | none if old snapshot valid, deleted tree diff visible |
added.FCStd | ADDED | none, full-tree added diff |
missing_old_snapshot.FCStd | MODIFIED | old snapshot MISSING, full-tree added diff from empty baseline |
missing_new_snapshot.FCStd | MODIFIED | none yet, because working snapshot exists |
invalid_old_snapshot.FCStd | MODIFIED or issue-only | old snapshot INVALID, likely no tree diff |
invalid_new_snapshot.FCStd | MODIFIED | none yet, because working snapshot exists |
Also verify:
- deleted open document warning if
deleted.FCStdis still open - deletion wins over open document state
- no working snapshot created for deleted path
- state remains
DELETED
Phase 3 - Test Stage Documents
Section titled “Phase 3 - Test Stage Documents”Use History workbench Stage Documents.
Select:
modified_parametric.FCStdmodified_binary_only.FCStdadded.FCStdmissing_old_snapshot.FCStdmissing_new_snapshot.FCStdinvalid_old_snapshot.FCStdinvalid_new_snapshot.FCStd- deleted path
deleted.FCStd
Expected:
- open docs saved before staging
- YAML snapshots written for selected snapshots
- FCStd and YAML staged
- deleted FCStd staged
- deleted YAML removed from disk and staged if tracked
- duplicate paths not staged twice
- deleted open doc not saved or resurrected
Check:
git status --shortExpected examples:
M modified_parametric.FCStdM .history_snapshots/modified_parametric.yaml
M modified_binary_only.FCStdM .history_snapshots/modified_binary_only.yaml
D deleted.FCStdD .history_snapshots/deleted.yaml
A added.FCStdA .history_snapshots/added.yamlExact YAML paths may differ.
Phase 4 - Create Staged Snapshot Issue Cases
Section titled “Phase 4 - Create Staged Snapshot Issue Cases”Before testing Staging mode, break staged content manually.
Case A - Missing New Snapshot
Section titled “Case A - Missing New Snapshot”Remove staged YAML for missing_new_snapshot.FCStd:
git restore --staged .history_snapshots/missing_new_snapshot.yamlrm .history_snapshots/missing_new_snapshot.yamlKeep FCStd staged:
git add missing_new_snapshot.FCStdExpected later:
- new snapshot
MISSING - no tree diff for modified file because new snapshot absent
Case B - Invalid New Snapshot
Section titled “Case B - Invalid New Snapshot”Corrupt and stage YAML for invalid_new_snapshot.FCStd:
printf 'not: [valid\n' > .history_snapshots/invalid_new_snapshot.yamlgit add .history_snapshots/invalid_new_snapshot.yamlExpected later:
- new snapshot
INVALID - no valid tree diff
Phase 5 - Test Staging Mode
Section titled “Phase 5 - Test Staging Mode”Open diff UI in Staging mode.
Expected rows include only staged changed files:
| File | Expected state | Expected issues |
|---|---|---|
modified_parametric.FCStd | MODIFIED | none |
modified_binary_only.FCStd | MODIFIED | GIT_CHANGED_NO_PARAMETRIC_DIFF if snapshot unchanged |
deleted.FCStd | DELETED | none if old snapshot existed |
added.FCStd | ADDED | none |
missing_old_snapshot.FCStd | MODIFIED | old snapshot MISSING, full-tree added diff |
missing_new_snapshot.FCStd | MODIFIED | new snapshot MISSING, no tree diff |
invalid_old_snapshot.FCStd | MODIFIED | old snapshot INVALID, no or issue-only diff |
invalid_new_snapshot.FCStd | MODIFIED | new snapshot INVALID, no or issue-only diff |
Verify not shown:
clean_open.FCStd, unless staged or dirty
Phase 6 - Commit All Staged Changes
Section titled “Phase 6 - Commit All Staged Changes”Commit staged state:
git commit -m "manual diff matrix commit"Save commit hash:
git rev-parse HEADPhase 7 - Test Commit Mode
Section titled “Phase 7 - Test Commit Mode”In UI, select commit manual diff matrix commit.
Expected same as Staging mode:
| File | Expected state | Expected issues |
|---|---|---|
modified_parametric.FCStd | MODIFIED | none |
modified_binary_only.FCStd | MODIFIED | GIT_CHANGED_NO_PARAMETRIC_DIFF if snapshots same |
deleted.FCStd | DELETED | none |
added.FCStd | ADDED | none |
missing_old_snapshot.FCStd | MODIFIED | old snapshot MISSING |
missing_new_snapshot.FCStd | MODIFIED | new snapshot MISSING |
invalid_old_snapshot.FCStd | MODIFIED | old snapshot INVALID |
invalid_new_snapshot.FCStd | MODIFIED | new snapshot INVALID |
Important commit-mode checks:
- results sorted by git path
- only files from selected commit appear
- deleted file loads old snapshot from parent commit
- added file uses empty old snapshot
- missing or invalid snapshots surface as side issues
Phase 8 - Test Restore Feature Reuse
Section titled “Phase 8 - Test Restore Feature Reuse”Use Restore to reset files back to baseline or selected commit.
Recommended fast loops:
- Restore
modified_parametric.FCStdto baseline. Working Tree mode should stop showing parametric diff after save and stage cleanup. - Restore
deleted.FCStdfrom baseline. Working Tree mode should change fromDELETEDto clean or unchanged if open. - Restore
added.FCStdby removing it or restoring repo to baseline. Working Tree mode should remove added row. - Restore
missing_new_snapshot.FCStd, then stage normally through workbench. Staging and commit mode should losenew snapshot MISSING. - Restore
invalid_new_snapshot.FCStd, then regenerate and stage YAML. Staging and commit mode should losenew snapshot INVALID.
Useful reset command when returning to clean baseline:
git restore --source HEAD~1 --worktree --staged .git clean -fdDo not run this if preserving later commits matters.
Extra Failure Checks
Section titled “Extra Failure Checks”Stage Conflict Rejection
Section titled “Stage Conflict Rejection”Call Stage Documents with same path in snapshot inputs and deleted path inputs.
Expected:
- failure result
- message like
Cannot stage paths as both present and deleted - no git staging after conflict
Manual path:
- keep one document open
- also mark same path as deleted in UI or action if UI allows it
Save Failure
Section titled “Save Failure”Make document read-only or simulate FreeCAD save failure.
Expected:
- Stage Documents returns failure
- no later YAML write or git staging for that document
Deleted YAML Tracked Check
Section titled “Deleted YAML Tracked Check”For deleted file with tracked YAML:
- YAML removed from disk
- YAML deletion staged
For deleted file with no tracked YAML:
- no git pathspec error
- only FCStd deletion staged
Reusable Repo Result
Section titled “Reusable Repo Result”Keep repository as fixture with these commits:
commit 1: baseline manual history test repocommit 2: manual diff matrix commitUse:
- baseline commit for restore tests
- matrix commit for Commit mode regression checks
- working tree edits on top for Working Tree and Staging mode regression checks