o-install, two-reboot c= ycle for major version jumps (e.g. 14.x =E2=86=92 15.x) using a temporary `rc.d` ser= vice that survives the first reboot - **Safe by design** =E2=80=94 full backup before touching anything, restor= e script generated automatically, SHA256 integrity verification --- ## Current limitations and known bugs I want to be transparent about what still needs work: 1. **STABLE branch detection** =E2=80=94 the menu regex for `-STABLE` targe= ts does not always match the mirror directory listing correctly 2. **State recovery after interruption** =E2=80=94 if the script is killed mid-upgrade, resuming it does not correctly re-enter the freebsd-update merge phase; it tries to call `freebsd-update install` prematurely 3. **grep -c arithmetic** =E2=80=94 a subtle shell arithmetic bug produces `[: 0 0: bad number` in some cases when counting conflict markers 4. **STABLE/CURRENT upgrade type** =E2=80=94 `is_major_upgrade()` only comp= ares major version numbers; it does not distinguish STABLE or CURRENT targets which may need different handling 5. **Terminal compatibility** =E2=80=94 Unicode box-drawing characters in m= enus do not render correctly in all FreeBSD terminal configurations; should fall back to plain ASCII --- ## What I would love feedback on This is where I genuinely need input from people who know FreeBSD internals better than I do: **1. Is using `$EDITOR` the right hook into freebsd-update?** Is there a cleaner, more supported way to intercept freebsd-update's merge phase? I am essentially abusing the EDITOR variable =E2=80=94 it works, but= it feels fragile. Is there an official API or hook mechanism I am missing? **2. The 3-way merge approach =E2=80=94 is merge(1) the right tool?** I am using `merge(1)` from the `rcs` package. Are there better alternatives in the FreeBSD base system? `diff3(1)` is available but requires more orchestration. `patch(1)` could work but loses context. Thoughts? **3. Handling STABLE and CURRENT upgrades** Upgrading to a -STABLE or -CURRENT branch is fundamentally different from a RELEASE upgrade =E2=80=94 freebsd-update behaves differently, and the bas= e.txz download path is different. Has anyone automated this reliably? **4. The two-reboot major upgrade cycle** I implemented this using a temporary `rc.d` service (`automerge_resume`) that runs `freebsd-update install` after the first reboot and then removes itself. It works, but it feels like a hack. Is there a cleaner pattern? **5. pkg alignment after major upgrades** After a major upgrade (e.g. 14.x =E2=86=92 15.x), all installed packages ne= ed to be rebuilt or reinstalled. I currently just tell the user to run `pkg upgrade -f` manually. Should this be integrated into the script? What is the safest sequence? --- ## How to get it The script is a single self-contained shell file with no external dependencies beyond `merge(1)` (from `pkg install rcs`) and optionally `expect(1)` for auto-confirm mode. Usage: ```sh # Show interactive target menu (queries mirror live) sh freebsd-automerge.sh # Filter menu to branch 14 sh freebsd-automerge.sh 14 # Direct upgrade, no menu sh freebsd-automerge.sh 14.4-RELEASE # Fully automated (requires: pkg install expect) sh freebsd-automerge.sh --auto-confirm 14 ``` --- ## Credits The script was conceived and directed by **ZioMario** (forums.freebsd.org user: ZioMario), developed with the assistance of **Claude** (Anthropic AI)= . The idea, architecture decisions, testing, and debugging were all driven by ZioMario =E2=80=94 Claude was used as an implementation tool. All feedback, pull requests, and brutal criticism are welcome. --=20 Mario. --0000000000000c3342065111147d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
## Introduction

I would like to share a shell script I developed with the assistance of Cla= ude
(Anthropic's AI) to automate the most tedious part of FreeBSD upgrades:= resolving merge conflicts in configuration files.

The script is called **freebsd-automerge.sh** and it handles the complete u= pgrade workflow from start to finish, including conflict resolution, backup= , and the install/reboot cycle.

---

## The problem it solves

Anyone who has upgraded FreeBSD using `freebsd-update upgrade` knows the pa= in: When configuration files have been locally modified, freebsd-update sto= ps and asks you to manually resolve conflicts one by one in an editor. On a= system with many customized files, this can mean dozens of interruptions r= equiring careful manual editing.

The standard approach (mergemaster, etcupdate) works well but still require= s
significant manual intervention. I wanted something fully automated that co= uld handle an upgrade =E2=80=94 including a major version jump =E2=80=94 wi= th minimal human input.

---

## How it works

The core idea is a **3-way merge**:

```
base OLD (e.g. 14.3-RELEASE clean) =E2=86=92 your customized file =3D Y= OUR changes
base OLD (e.g. 14.3-RELEASE clean) =E2=86=92 base NEW (14.4-RELEASE) =3D = FreeBSD changes
```

By comparing both sets of changes independently against the original clean = base,the script can automatically apply both your customizations and FreeBS= D's updates without conflicts =E2=80=94 exactly the same mechanism git = uses for merging branches.

The script operates in two distinct modes:

### EDITOR mode
The script registers itself as the `$EDITOR` for `freebsd-update`:

```sh
EDITOR=3D/root/freebsd-automerge.sh freebsd-update -r 14.4-RELEASE upgrade<= br> ```

When freebsd-update encounters a file it cannot merge automatically, instea= d of opening nano it calls our script with the conflicted file path. The sc= ript then:

1. Extracts the clean OLD base version from `base.txz`
2. Extracts the clean NEW base version from `base.txz`
3. Uses `merge(1)` (from the base system) for the 3-way merge in-place
4. If residual conflicts remain, fall back to nano for manual resolution 5. Returns control to freebsd-update

### MAIN mode
The primary workflow:

1. Interactive menu querying the FreeBSD mirror in real time to show availa= ble RELEASE, STABLE, RC, and BETA targets
2. Downloads `base.txz` for both OLD and NEW releases
3. Runs `freebsd-update upgrade` with itself as EDITOR
4. After upgrade, scans `/etc` and `/usr/share` for any remaining `<<= <<<<<`
markers and resolves them with the same 3-way merge
5. Creates a centralized backup of all conflicted files with SHA256 manifes= t
and generates a `restore.sh` script for rollback
6. Runs `freebsd-update install` and handles the reboot cycle automatically= ,
including the two-pass install required for major version upgrades

---

## Key features

- **Zero configuration** =E2=80=94 detects OLD and NEW versions automatical= ly from
`uname -r` and `/var/db/freebsd-update/tag`
- **Live mirror query** =E2=80=94 the target selection menu fetches availab= le versions directly from the FreeBSD mirror at runtime
- **Kernel/userland selection** =E2=80=94 asks whether to upgrade both or u= serland only,useful for systems running custom kernels (e.g. ARM SBCs with = custom DRM drivers)
- **Auto-confirm mode** =E2=80=94 `--auto-confirm` flag uses `expect(1)` to= answer
freebsd-update's interactive prompts automatically
- **Major upgrade support** =E2=80=94 handles the two-install, two-reboot c= ycle for
major version jumps (e.g. 14.x =E2=86=92 15.x) using a temporary `rc.d` s= ervice
that survives the first reboot
- **Safe by design** =E2=80=94 full backup before touching anything, restor= e script
generated automatically, SHA256 integrity verification

---

## Current limitations and known bugs

I want to be transparent about what still needs work:

1. **STABLE branch detection** =E2=80=94 the menu regex for `-STABLE` targe= ts does not always match the mirror directory listing correctly

2. **State recovery after interruption** =E2=80=94 if the script is killed = mid-upgrade,
resuming it does not correctly re-enter the freebsd-update merge phase;<= br> it tries to call `freebsd-update install` prematurely

3. **grep -c arithmetic** =E2=80=94 a subtle shell arithmetic bug produces<= br> `[: 0 0: bad number` in some cases when counting conflict markers

4. **STABLE/CURRENT upgrade type** =E2=80=94 `is_major_upgrade()` only comp= ares
major version numbers; it does not distinguish STABLE or CURRENT targets=
which may need different handling

5. **Terminal compatibility** =E2=80=94 Unicode box-drawing characters in m= enus do not render correctly in all FreeBSD terminal configurations; should= fall back
to plain ASCII

---

## What I would love feedback on

This is where I genuinely need input from people who know FreeBSD internals=
better than I do:

**1. Is using `$EDITOR` the right hook into freebsd-update?**
Is there a cleaner, more supported way to intercept freebsd-update's me= rge
phase? I am essentially abusing the EDITOR variable =E2=80=94 it works, but= it feels
fragile. Is there an official API or hook mechanism I am missing?

**2. The 3-way merge approach =E2=80=94 is merge(1) the right tool?**
I am using `merge(1)` from the `rcs` package. Are there better alternatives=
in the FreeBSD base system? `diff3(1)` is available but requires more
orchestration. `patch(1)` could work but loses context. Thoughts?

**3. Handling STABLE and CURRENT upgrades**
Upgrading to a -STABLE or -CURRENT branch is fundamentally different from a RELEASE upgrade =E2=80=94 freebsd-update behaves differently, and the bas= e.txz
download path is different. Has anyone automated this reliably?

**4. The two-reboot major upgrade cycle**
I implemented this using a temporary `rc.d` service (`automerge_resume`) that runs `freebsd-update install` after the first reboot and then removes<= br> itself. It works, but it feels like a hack. Is there a cleaner pattern?

**5. pkg alignment after major upgrades**
After a major upgrade (e.g. 14.x =E2=86=92 15.x), all installed packages ne= ed to be
rebuilt or reinstalled. I currently just tell the user to run `pkg upgrade = -f`
manually. Should this be integrated into the script? What is the safest
sequence?

---

## How to get it

The script is a single self-contained shell file with no external dependenc= ies
beyond `merge(1)` (from `pkg install rcs`) and optionally `expect(1)` for auto-confirm mode.

Usage:

```sh
# Show interactive target menu (queries mirror live)
sh freebsd-automerge.sh

# Filter menu to branch 14
sh freebsd-automerge.sh 14

# Direct upgrade, no menu
sh freebsd-automerge.sh 14.4-RELEASE

# Fully automated (requires: pkg install expect)
sh freebsd-automerge.sh --auto-confirm 14
```

---

## Credits

The script was conceived and directed by **ZioMario** (forums.freebsd.org user: ZioMario), developed with th= e assistance of **Claude** (Anthropic AI).
The idea, architecture decisions, testing, and debugging were all driven by=
ZioMario =E2=80=94 Claude was used as an implementation tool.

All feedback, pull requests, and brutal criticism are welcome.

--
Mario.
--0000000000000c3342065111147d-- --0000000000000c3344065111147f Content-Type: application/zip; name="freebsd-automerge.sh.zip" Content-Disposition: attachment; filename="freebsd-automerge.sh.zip" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_moslgskv0 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 --0000000000000c3344065111147f--