diff --git a/skills/weave-git-merge/SKILL.md b/skills/weave-git-merge/SKILL.md new file mode 100644 index 0000000..e4fb54c --- /dev/null +++ b/skills/weave-git-merge/SKILL.md @@ -0,0 +1,128 @@ +--- +name: weave-git-merge +description: Use and troubleshoot Weave as an entity-aware Git merge driver during merges, rebases, cherry-picks, and conflict resolution. Use when configuring Weave, previewing a merge, checking whether Git will invoke it, interpreting Weave conflict markers or exit behaviour, recovering from driver failures, or explaining what Weave actually resolves versus when it falls back to line-level merging. +--- + +# Use Weave with Git + +Treat Weave as a per-file Git merge driver, not as a replacement for `git merge` +or `git rebase`. Git selects it through attributes and invokes +`weave-driver %O %A %B %L %P` for each selected path. + +Read [behaviour.md](references/behaviour.md) before diagnosing a surprising +result or deciding whether an unresolved file is safe to edit. + +## Configure it + +Choose one scope deliberately: + +```bash +# Tracked for this repository; suitable when the whole team should use Weave. +weave setup + +# Untracked for this clone only; writes .git/info/attributes. +weave setup --local + +# All repositories for this user; writes global Git config and attributes. +weave setup --global +``` + +Pass `--driver /absolute/path/to/weave-driver` when auto-detection is +unreliable. Prefer a stable installed path over a versioned build directory. + +Do not assume setup succeeded merely because `.gitattributes` contains a rule. +Verify both selection and command: + +```bash +git check-attr merge -- path/to/file.ts +git config --show-origin --get merge.weave.driver +command -v weave-driver +weave-driver --version +``` + +Expect `git check-attr` to report `merge: weave`. Inspect all applicable +attribute sources with `git check-attr -a -- path` when another rule may +override it. + +## Preview before changing Git state + +```bash +weave preview other-branch +weave preview other-branch --file path/to/file.ts +``` + +Use preview as an estimate. It reads the merge base, `HEAD`, and the named +branch directly; it does not reproduce every higher-level Git operation or +pre-existing conflicted stage exactly. + +## Merge or rebase normally + +Run the ordinary Git operation. During a rebase, remember that Git's labels +and the human meaning of “ours” and “theirs” are easy to misread. Reason from +the desired rebased result and inspect the stage blobs when provenance matters. + +After Git stops: + +```bash +git status --short +git diff --name-only --diff-filter=U +git ls-files -u -- path/to/file.ts +weave summary path/to/file.ts +``` + +Inspect the three index inputs without touching the working file: + +```bash +git show :1:path/to/file.ts # merge base +git show :2:path/to/file.ts # stage 2 +git show :3:path/to/file.ts # stage 3 +``` + +During rebase, do not attach branch names to stages 2 and 3 from memory; +identify them from their content and the rebase operation. + +`weave summary` understands Weave's enhanced markers. It may report no Weave +conflicts when a path used the line-level fallback and therefore contains +ordinary diff3 markers. + +Review the whole merged file, including clean regions. Weave preserves the +ours-side entity ordering, inserts theirs-only entities, merges interstitial +text separately, and performs cleanup and structural validation. A clean exit +means no recorded conflict remains; it is not proof that the result has the +intended semantics. + +Resolve remaining markers, run the repository's normal formatting, tests, +lint, and type checks, then `git add` the path and continue the Git operation. + +## Interpret driver outcomes + +- Exit `0`: Weave wrote the result to `%A` and considers it clean. +- Exit `1`: Weave wrote a partially merged result with conflicts to `%A`; Git + keeps the path unmerged for manual or agent resolution. +- Exit `2`: invocation, input, output, or binary-file failure. Do not treat + this as a semantic conflict; inspect stderr and repair the driver/configuration. + +The Git driver uses enhanced seven-character markers with entity names and +hints. The `-l` option selects standard diff3-compatible markers and is meant +for tools such as Jujutsu; Git's positional `%L` does not disable enhanced +markers. + +Set `WEAVE_VERBOSE=1` to print per-file statistics. Set `WEAVE_TIMEOUT` to a +whole number of seconds only when the default five-second entity-merge timeout +is unsuitable. A timeout falls back to `git merge-file`; it does not abort the +overall driver invocation. + +## Recover safely + +Before rerunning or replacing a result, preserve it or inspect the index +stages. Commands that recreate conflict markers can overwrite Weave's +partially merged `%A` file. + +If Weave was selected but never ran, check attribute precedence, the exact +config scope, executable discovery, and quoting of a driver path containing +spaces. If the driver returned `2`, use its stderr to distinguish missing +inputs, binary detection, and write failure. + +Remove repository configuration with `weave unsetup`. It removes the local +`merge.weave` section and Weave rules from `.gitattributes` and +`.git/info/attributes`; it does not remove global setup. diff --git a/skills/weave-git-merge/agents/openai.yaml b/skills/weave-git-merge/agents/openai.yaml new file mode 100644 index 0000000..f0fbce5 --- /dev/null +++ b/skills/weave-git-merge/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Weave Git Merge" + short_description: "Use and troubleshoot Weave merge drivers" + default_prompt: "Use $weave-git-merge to configure, inspect, or troubleshoot a Git merge or rebase with Weave." diff --git a/skills/weave-git-merge/references/behaviour.md b/skills/weave-git-merge/references/behaviour.md new file mode 100644 index 0000000..2132288 --- /dev/null +++ b/skills/weave-git-merge/references/behaviour.md @@ -0,0 +1,115 @@ +# Weave merge behaviour + +## Contents + +- [Git driver contract](#git-driver-contract) +- [Resolution pipeline](#resolution-pipeline) +- [What resolves cleanly](#what-resolves-cleanly) +- [What remains conflicted](#what-remains-conflicted) +- [Fallbacks and limits](#fallbacks-and-limits) +- [Supported setup patterns](#supported-setup-patterns) + +## Git driver contract + +Setup records this command: + +```text +weave-driver %O %A %B %L %P +``` + +Git supplies ancestor, current-side temporary path, other-side temporary path, +marker length, and logical repository path. The driver reads all three inputs, +uses `%P` to select a parser, and overwrites `%A`. This is true for both clean +and conflicted results. It then returns `0` for clean, `1` for unresolved, or +`2` for operational failure and binary input. + +The driver records lifetime statistics on a best-effort basis. Statistics and +optional CRDT recording never decide merge success. + +## Resolution pipeline + +The engine applies these layers: + +1. Preserve an input that already contains conflict markers and report a + file-level conflict; nested three-way merging of pre-conflicted text is + deliberately avoided. +2. Take identical sides, or take the side changed from an unchanged base. +3. Fall back when content is binary, over 1 MB, unsupported, unparsable, + newly created differently on both sides with an empty base, or dominated by + duplicate entity names. +4. Parse top-level semantic entities and match base-to-branch entities, + including structural rename detection. +5. Resolve each entity independently, merge text between entities, and + reconstruct using ours as the ordering skeleton. +6. Clean duplicate/blank-line artefacts and validate a clean, jointly modified + result. Validation warnings can force a line-level retry when semantic + reconstruction looks unsafe. + +The core bridge is `entity_merge_with_registry`; the driver wraps it in a +five-second timeout and uses `git merge-file` on timeout. + +## What resolves cleanly + +Common clean cases include: + +- only one branch changes, adds, or deletes an entity; +- both branches produce identical entity content; +- branches change different functions or top-level entities; +- branches change different members inside supported container entities; +- one branch changes only whitespace while the other changes content; +- compatible edits within one entity succeed through a three-way text merge; +- compatible decorator/annotation additions merge commutatively; +- many import additions and supported grouped or multiline imports merge + commutatively; +- some structural renames are tracked so an entity is not emitted twice. + +These are implementation strategies, not semantic proofs. Always compile or +test the result. + +## What remains conflicted + +Expect an entity-scoped or file-scoped conflict for: + +- incompatible edits to the same entity after all inner strategies fail; +- modify/delete cases; +- different content added under the same new entity identity; +- both branches renaming the same base entity differently; +- rename-plus-modify cases that require human review; +- conflicting text between semantic entities; +- pre-existing markers in any input; +- any fallback merge that `git merge-file` or Diffy cannot resolve. + +Container conflicts may be narrowed to an individual method or member. Common +prefix and suffix lines are emitted outside the marker. Enhanced Git-driver +markers annotate the entity and deletion side; standard `-l` mode includes a +diff3 base section. + +## Fallbacks and limits + +Unknown file types do not receive arbitrary 20-line “semantic” chunks; they go +straight to line-level merging. Code-like fallback text first tries separator +expansion plus Diffy, compares its conflict-marker count with `git merge-file`, +and keeps the result that is no worse by that measure. + +Data formats and lock files skip separator expansion and use +`git merge-file --diff3` directly because expansion can worsen alignment. If +Git cannot be executed, the final fallback is Diffy. + +The driver rejects NUL-containing input before reaching the core fallback. +This produces exit `2`, allowing Git or the operator to handle the binary path +instead of accepting a text merge. + +## Supported setup patterns + +Current setup writes `merge=weave` for: + +```text +ts tsx js mjs cjs jsx py go rs java c h cpp cc cxx hpp hh hxx rb cs php +swift ex exs sh f90 f95 f03 f08 xml plist svg csproj fsproj vbproj json +yaml yml toml md scala sc sbt kojo mill dart +``` + +This setup list is narrower than every parser or format mentioned in project +documentation. Trust `git check-attr merge -- path` for the current repository, +and add an explicit attribute rule only after confirming the installed Weave +version handles that format acceptably.