Skip to content

feat!: add Git version control for editing projects - #2164

Merged
yuto-trd merged 10 commits into
mainfrom
yuto-trd/project-git-version-control
Sep 8, 2026
Merged

feat!: add Git version control for editing projects#2164
yuto-trd merged 10 commits into
mainfrom
yuto-trd/project-git-version-control

Conversation

@yuto-trd

@yuto-trd yuto-trd commented Jul 31, 2026

Copy link
Copy Markdown
Member

Description

  • Add opt-in Git version control for Beutl editing projects: save/close snapshots, history, diffs, restore, branches, and fast-forward-only remote synchronization.
  • Keep every repository mutation scoped to the project subtree, including adopted enclosing repositories, LFS objects, recovery refs, temporary indexes, hooks, and interrupted-operation recovery.
  • Add the Version Control tool tab, title-bar branch picker, settings, localized guidance, and Git-unavailable degradation.
  • Keep Git-specific canonical path and serialization-graph inspection internal to Beutl.Editor.VersionControl.
  • Keep host composition, mutation coordination, and recovery operations internal; the plugin-facing version-control surface is read/query only.
  • The branch is rebased directly onto main; review remediation is isolated in signed follow-up commits.

Frozen scope

Included here:

  • Git CLI backend and project-scoped repository safety
  • Git tool-tab and shell integration
  • save/close/safety/restore/recovery snapshots
  • branches, origin push, and fast-forward-only pull
  • the four Git-friendly storage prerequisites: stable appVersion metadata, LF JSON, portable scene patterns, and ID-based element filenames
  • the minimal existing-window safeguard that cancels closing when the required pre-close save is refused

Explicitly excluded from this PR:

  • public output admission and AgentToolkit render leases
  • public context-command completion
  • public canonical filesystem APIs and non-Git consumers
  • package export/resource relocation hardening
  • proxy and AgentHost lifecycle redesigns
  • asynchronous application shutdown redesign
  • renderer census and macOS menu identity fixes
  • generalized project-item migration propagation

Already-created extracted PRs target main directly and do not depend on this PR:

Integration order (direct-to-main, not stacked)

Before this PR is merged, the output/AgentHost safety prerequisites must land independently on main, and this branch must then be rebased onto that updated main:

This ordering keeps every PR based directly on main; there is no stacked-PR dependency chain.

Affected areas

  • Beutl.Engine (rendering / scene / track)
  • Beutl.ProjectSystem (project / document persistence)
  • UI (Beutl.Editor, Beutl.Editor.Components, Beutl.Controls)
  • Beutl.Extensibility (plugin-facing version-control query seam only)
  • Beutl.NodeGraph (node editor)
  • Beutl.FFmpegIpc / Beutl.FFmpegWorker (media IPC boundary)
  • Beutl.Api (server API client)
  • Build / CI / docs only

Breaking changes

Beutl.Core now preserves loaded project appVersion / minAppVersion until persisted content is explicitly migrated. Its shared JsonHelper / CoreSerializer options use LF line endings for projects, configuration, editor state, and every other consumer, so Windows users may observe one-time newline diffs.

No public output, context-command, canonical-path, package, AgentHost, proxy, or application-shutdown API contract is changed by this PR. A window close is canceled when the mandatory pre-close project save fails; the broader asynchronous shutdown redesign remains excluded.

The repository uses a blank squash-merge body by default. The merger must explicitly supply this trailer in the final squash commit body:

The exact footer is repeated as the final paragraph of this PR body and must be used unchanged for the squash commit.

Test plan

  • dotnet build Beutl.slnx -c Debug --no-restore — passed on the final tree, 0 errors
  • focused GitCliVersionControlService commit/history regressions — 72 passed
  • focused Git LFS prefetch regressions — 29 passed; unavailable-filter subset re-run on the final tree
  • VersionControlSnapshotScopeTests — 19 passed
  • focused VersionControlRestoreTests review regressions — 5 passed
  • Beutl.HeadlessUITests.VersionControlSaveTests — 16 passed
  • RepositoryWatcherTests — 44 passed
  • Beutl.PublicApiContractTests — 209 passed
  • scoped dotnet format --verify-no-changes on the final review delta — passed
  • git diff --check — passed
  • GPL/MIT diff boundary scan — passed

Fixed issues / References

  • Spec: docs/specs/005-project-git-versioning/

BREAKING-CHANGE: Beutl.Core now preserves loaded project appVersion and minAppVersion until explicit migration, and its shared JsonHelper and CoreSerializer output uses LF line endings for projects, configuration, editor state, and every other consumer. Windows consumers may observe one-time newline diffs.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants