Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,15 @@ perl -c cfg-update
./test/run-tests.sh --full
```

## Optional: MentisDB memory

If MentisDB MCP tools are available in this session:
- Use chain_key `cfg-update` (do not create another chain for this repo).
- Session start: list_chains → bootstrap → skill_md → list_agents → recent_context → Summary checkpoint.
- Reuse an existing agent_id; do not invent new agent IDs without maintainer approval.
- Persist Decision / Constraint / LessonLearned / TaskComplete / Checkpoint as work progresses.
- Search before append; one strong memory beats many weak ones.

If MentisDB tools are not available: **ignore this section completely**.
Do not invent a substitute, do not fail, and do not ask the user to install MentisDB
unless they explicitly want project memory.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
# Copyright 2002-2005 Gentoo Technologies, Inc.; Distributed under the GPL v2
# $Header: $

*cfg-update-1.11.0 (2026-07-28)

Safety checks added during all merges to prevent editing of any file versions
other than the leftmost one. This was always intended behavior but lacked
safeguards previously. Hashes are also checked to detect changes made
outside of cfg-update. These will still be preserved but will not be
relied upon in future automatic merges. The next clean package update
will return automatic merge behavior for that package.

*cfg-update-1.10.4 (2026-06-20)

Drop gtkdiff and imediff2 merge-tool support; align merge-tool lists in
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Feedback is welcome.

A safe, staged alternative to Gentoo's `etc-update` for handling configuration file updates after package merges.

**Version:** 1.10.4
**Version:** 1.11.0
**License:** GPL-2 ([COPYING](COPYING))

## Description
Expand Down
244 changes: 235 additions & 9 deletions cfg-update

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,14 @@ No conflict markers → apply merged result. Conflict → defer to stage 3.

Launches the configured merge tool with ancestor, live, and new files. Requires a tool with 3-way support (meld, kdiff3, xxdiff, tkdiff, imediff).

For Stage 3, the ancestor (`$path_backup_new`) and Portage marker (`$path_new`) are each copied via `make_merge_view_temp` to disposable files under `/tmp` (or `$TMPDIR`) before the tool runs, so accidental saves on non-live panes cannot corrupt permanent backups or markers. The live file and `*.merge` output paths remain real. See issue #65.

### Stage 4 — Manual 2-way merge (`update_stage4`)

Merges live file and `._cfg*` update when no backup exists. Works with all supported tools.

For Stage 4, the Portage marker (`$path_new`) is copied via `make_merge_view_temp` to a disposable file under `/tmp` (or `$TMPDIR`) before the interactive tool runs (same helper as Stage 3; ancestor view is a no-op when no backup ancestor exists). Accidental saves on the new-file pane cannot corrupt the real `._cfg*` marker. The live file and `*.merge` output paths remain real. See issue #68.

### Stage 5 — Manual special cases (`update_stage5`)

Interactive prompts for binaries, symlinks, and custom files.
Expand All @@ -203,6 +207,15 @@ Backups live under `/var/lib/cfg-update/backups/`, mirroring the original path:

These enable stage 2's 3-way merges on subsequent updates.

Before writing `._new-cfg_*`, cfg-update compares the staged marker snapshot
(`$path_temp_new`) to the Portage VDB `CONTENTS` MD5 for the **live path**
(not the checksum index, and not the `._cfg*` filename). The digest is taken
from the most recently installed package that owns that path (`BUILD_TIME`,
else CONTENTS mtime). On match, the ancestor is promoted as usual. On
mismatch, a warning is printed and the bad content is **not** stored as the
Stage 2 ancestor (issue #66). If CONTENTS is missing, unparseable, or the
manager is not Portage, promotion fails open (prior behavior) with a warning.

| Command | Purpose |
|---------|---------|
| `-b` / `--backups` | List available backups |
Expand Down
6 changes: 3 additions & 3 deletions docs/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ Run from a git checkout (no root required):
./test/run-tests.sh
```

Gentoo ebuild ([`gentoo/cfg-update-1.10.4.ebuild`](../gentoo/cfg-update-1.10.4.ebuild)):
Gentoo ebuild ([`gentoo/cfg-update-1.11.0.ebuild`](../gentoo/cfg-update-1.11.0.ebuild)):

```bash
FEATURES=test USE=test emerge --oneshot /path/to/gentoo/cfg-update-1.10.4.ebuild
FEATURES=test USE=test emerge --oneshot /path/to/gentoo/cfg-update-1.11.0.ebuild
```

| Requirement | Gentoo package | Used in |
Expand Down Expand Up @@ -161,7 +161,7 @@ grep -q 'cfg-update --index' /etc/portage/bashrc && echo "hook OK"
A reference ebuild is maintained in [`gentoo/`](../gentoo/). Install with:

```bash
FEATURES=test USE=test emerge --oneshot /path/to/gentoo/cfg-update-1.10.4.ebuild
FEATURES=test USE=test emerge --oneshot /path/to/gentoo/cfg-update-1.11.0.ebuild
```

Or from the Gentoo tree: `emerge app-portage/cfg-update`.
Expand Down
7 changes: 4 additions & 3 deletions docs/INVENTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**Updated:** 2026-06-20 (issue #29)
**Repo:** [rich0/cfg-update](https://github.com/rich0/cfg-update)
**Version:** 1.10.4
**Version:** 1.11.0
**Target usage:** Single-host Gentoo with Portage (`emerge`); Paludis best-effort

---
Expand All @@ -23,7 +23,7 @@ The repository has **no language-level lockfile** (no `package.json`, `cpanfile`
| [`cfg-update.conf`](../cfg-update.conf) | 166 | Config template (installed as `/etc/cfg-update.conf`) |
| [`cfg-update.8`](../cfg-update.8) | 149 | Man page |
| [`cfg-update_indexing`](../cfg-update_indexing) | 12 | Paludis hook script (copied to `/usr/share/paludis/hooks/...`) |
| [`gentoo/cfg-update-1.10.4.ebuild`](../gentoo/cfg-update-1.10.4.ebuild) | — | Reference Gentoo ebuild with `src_test()` |
| [`gentoo/cfg-update-1.11.0.ebuild`](../gentoo/cfg-update-1.11.0.ebuild) | — | Reference Gentoo ebuild with `src_test()` |
| [`ChangeLog`](../ChangeLog) | — | Gentoo ebuild changelog (historical) |
| [`COPYING`](../COPYING) | — | GPL v2 |
| [`test/run-tests.sh`](../test/run-tests.sh) | — | Integration test harness (Tiers 0–F) |
Expand Down Expand Up @@ -106,6 +106,7 @@ Every normal invocation (unless `--ebuild`) runs `check_hooks` and `check_tool`
| `update_stage1`–`update_stage5` | Per-stage logic |
| `update_retry`, `update_canceled`, `update_merge_*`, `update_replace_complete`, `update_keep_complete` | Interactive update handlers |
| `make_temp_backups` | Temp files during merge |
| `lookup_contents_md5_for_live`, `promote_backup_new` | Validate marker vs Portage CONTENTS before Stage 2 ancestor promote (issue #66) |

### Index and hooks

Expand Down Expand Up @@ -219,7 +220,7 @@ See [DEPENDENCIES.md](DEPENDENCIES.md) for install commands. Summary:

| Package | Purpose |
|---------|---------|
| `app-portage/cfg-update` | Install via [`gentoo/cfg-update-1.10.4.ebuild`](../gentoo/cfg-update-1.10.4.ebuild) |
| `app-portage/cfg-update` | Install via [`gentoo/cfg-update-1.11.0.ebuild`](../gentoo/cfg-update-1.11.0.ebuild) |
| `sys-apps/findutils` | `xargs` for index build |
| `dev-util/meld` (recommended) | Default merge tool |
| `dev-perl/Term-ANSIColor`, `dev-perl/TermReadKey` | Perl deps |
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ FEATURES=test USE=test emerge --oneshot app-portage/cfg-update
| D | `-u` + stdin | Stages 3–5 execute (one stage enabled at a time): stage-specific output, mock 3-way merge, replace/keep filesystem outcomes |
| E | `-i` / `-i -f` | Portage `--index`: up-to-date skip, stale rebuild from mock CONTENTS, marker-blocked skip, force rebuild |
| F | `-b`, `-r`, `--optimize-backups` | Backup list/restore after stage-2 update; stage-1 backups land in `BACKUP_PATH` (not inline); optimize-backups creates `._new-cfg_*` for unmodified files |
| G | CONTENTS promote validation | Issue #66: pristine marker promotes `._new-cfg_*`; tampered marker does not poison ancestor; missing CONTENTS fails open; last-install `BUILD_TIME` wins |

Tier B/C/D/E/F pass `--testsandbox` with `--ebuild` so `-u`, `--index`, `-r`, and `--optimize-backups` skip the root check inside the temp sandbox.
Tier B/C/D/E/F/G pass `--testsandbox` with `--ebuild` so `-u`, `--index`, `-r`, and `--optimize-backups` skip the root check inside the temp sandbox.

### Golden `expected/` files

Expand Down
Loading
Loading