flowchart LR
T[tree] --> Q{can this path land?}
Q -->|yes| P[commit + push]
Q -->|conflict / too big / submodule| H[hold back]
P --> R[keep going]
H --> R
R --> F{anything still blocked?}
F -->|held some| D[remote has the rest]
F -->|nothing landed| K[park bak/pending-merge]
-
one conflicted, oversized, or submodule path parks the whole checkpoint
-
the rest of the tree sits unbacked on that machine
-
drip: push the clean subset; hold the rest; never stall the backup
-
laptop + desktop both edit
-
N local commits replay against remote -> same conflict N times
-
other machine's work never left that machine
-
agents touch many repos per session
-
add+commit+pushper repo burns time -
one blocker used to abort the whole run
-
two hosts append different
.ndjson/.jsonllines -
git sees one slot, two lines -> conflict
-
nothing was edited; both lines should keep
Separate bins. Same package. Plain gitty != gittysnap.
# scoped package; same bin names
npm i -g @vd7/gittyOptional resolvers (missing file -> empty allowlist -> drip/park, no auto-resolve):
per_host:
paths:
- registry/system-resource/manifest.json
globs:
- snapshots/$(hostname)/**
semantic_union:
globs:
- "**/*.ndjson"
- "**/*.jsonl"
key_field: ts| path | do this | get this |
|---|---|---|
| A | gitty |
drip + holdback checkpoint on remote |
| B | gittysnap |
snapshot-first solo sync |
| C | gittyunion install |
NDJSON union merge driver |
# land whatever can land; hold blockers; park only if nothing can
gitty "checkpoint" "$HOME/Documents/a/gitty"GITTY_PARTIAL=1 default. Park-only: GITTY_PARTIAL=0. Bulldoze: GITTY_FORCE=1.
# both hosts on remote first; rc=2 on conflict; worktree clean
gittysnap# union + dedupe + stable-sort for .ndjson / .jsonl
gittyunion install| signal | meaning |
|---|---|
| partial integrate | resolved subset committed; held paths stay local |
| holdback | oversized / submodule / push-reject left unstaged |
| park | nothing could land; bak/pending-merge-* + remote-snapshot-* |
Local branch stays put on park. Nothing lost.
| problem | fix | stability | why |
|---|---|---|---|
| one unresolvable file parks whole merge | drip (GITTY_PARTIAL=1): commit resolved subset |
stable | backup as much as possible |
| oversized path blocks push | leave GITTY_PARTIAL=1 |
stable | hold back; push the rest |
| N-commit rebase replays same conflict N times | merge --ff-only then --no-ff once |
stable | one merge, one conflict set |
| per-host artifact conflicts every sync | .gitty/additive-resolvers.yaml per_host |
stable | ours on that host; --no-ff keeps both parents |
.ndjson append conflict |
semantic_union or gittyunion install |
stable | union + dedupe + stable-sort |
| fresh clone drops union driver | re-run gittyunion install |
stable | attrs alone insufficient |
| nothing can land | park bak/pending-merge-* |
stable | first-class ref; nothing lost; non-fatal |
foreign-owned .git (old sudo git) |
sudo chown -R "$(whoami)" .git |
stable | fail-fast; GITTY_SKIP_PERM_CHECK=1 opt out |
| Doc | Topic |
|---|---|
docs/README |
index |
docs/commands |
all bins |
docs/gittysnap |
snapshot-first sync |
docs/gittyunion |
NDJSON union driver |
docs/partial-commit |
holdback + drip |
docs/environment |
env |
docs/hooks |
repo hooks |
npm tarball = bin/ + README only. docs/ is GitHub.
