Skip site navigation (1)Skip section navigation (2)



index | | raw e-mail

---

## 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

<div dir=3D"ltr"><div>
## Introduction<br>
<br>
I would like to share a shell script I developed with the assistance of Cla=
ude<br>
(Anthropic&#39;s AI) to automate the most tedious part of FreeBSD upgrades:=
 resolving merge conflicts in configuration files.<br>
<br>
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.<br>
<br>
---<br>
<br>
## The problem it solves<br>
<br>
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.<br>
<br>
The standard approach (mergemaster, etcupdate) works well but still require=
s<br>
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.<br>
<br>
---<br>
<br>
## How it works<br>
<br>
The core idea is a **3-way merge**:<br>
<br>
```<br>
base OLD (e.g. 14.3-RELEASE clean)  =E2=86=92  your customized file  =3D  Y=
OUR changes<br>
base OLD (e.g. 14.3-RELEASE clean)  =E2=86=92  base NEW (14.4-RELEASE) =3D =
 FreeBSD changes<br>
```<br>
<br>
By comparing both sets of changes independently against the original clean =
base,the script can automatically apply both your customizations and FreeBS=
D&#39;s updates without conflicts =E2=80=94 exactly the same mechanism git =
uses for merging branches.<br>
<br>
The script operates in two distinct modes:<br>
<br>
### EDITOR mode<br>
The script registers itself as the `$EDITOR` for `freebsd-update`:<br>
<br>
```sh<br>
EDITOR=3D/root/freebsd-automerge.sh freebsd-update -r 14.4-RELEASE upgrade<=
br>
```<br>
<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:<br>
<br>
1. Extracts the clean OLD base version from `base.txz`<br>
2. Extracts the clean NEW base version from `base.txz`<br>
3. Uses `merge(1)` (from the base system) for the 3-way merge in-place<br>
4. If residual conflicts remain, fall back to nano for manual resolution<br=
>
5. Returns control to freebsd-update<br>
<br>
### MAIN mode<br>
The primary workflow:<br>
<br>
1. Interactive menu querying the FreeBSD mirror in real time to show availa=
ble RELEASE, STABLE, RC, and BETA targets<br>
2. Downloads `base.txz` for both OLD and NEW releases<br>
3. Runs `freebsd-update upgrade` with itself as EDITOR<br>
4. After upgrade, scans `/etc` and `/usr/share` for any remaining `&lt;&lt;=
&lt;&lt;&lt;&lt;&lt;`<br>
   markers and resolves them with the same 3-way merge<br>
5. Creates a centralized backup of all conflicted files with SHA256 manifes=
t<br>
   and generates a `restore.sh` script for rollback<br>
6. Runs `freebsd-update install` and handles the reboot cycle automatically=
,<br>
   including the two-pass install required for major version upgrades<br>
<br>
---<br>
<br>
## Key features<br>
<br>
- **Zero configuration** =E2=80=94 detects OLD and NEW versions automatical=
ly from<br>
  `uname -r` and `/var/db/freebsd-update/tag`<br>
- **Live mirror query** =E2=80=94 the target selection menu fetches availab=
le versions directly from the FreeBSD mirror at runtime<br>
- **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)<br>
- **Auto-confirm mode** =E2=80=94 `--auto-confirm` flag uses `expect(1)` to=
 answer<br>
  freebsd-update&#39;s interactive prompts automatically<br>
- **Major upgrade support** =E2=80=94 handles the two-install, two-reboot c=
ycle for<br>
  major version jumps (e.g. 14.x =E2=86=92 15.x) using a temporary `rc.d` s=
ervice<br>
  that survives the first reboot<br>
- **Safe by design** =E2=80=94 full backup before touching anything, restor=
e script<br>
  generated automatically, SHA256 integrity verification<br>
<br>
---<br>
<br>
## Current limitations and known bugs<br>
<br>
I want to be transparent about what still needs work:<br>
<br>
1. **STABLE branch detection** =E2=80=94 the menu regex for `-STABLE` targe=
ts does not always match the mirror directory listing correctly<br>
<br>
2. **State recovery after interruption** =E2=80=94 if the script is killed =
mid-upgrade,<br>
   resuming it does not correctly re-enter the freebsd-update merge phase;<=
br>
   it tries to call `freebsd-update install` prematurely<br>
<br>
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<br>
<br>
4. **STABLE/CURRENT upgrade type** =E2=80=94 `is_major_upgrade()` only comp=
ares<br>
   major version numbers; it does not distinguish STABLE or CURRENT targets=
<br>
   which may need different handling<br>
<br>
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<br>
   to plain ASCII<br>
<br>
---<br>
<br>
## What I would love feedback on<br>
<br>
This is where I genuinely need input from people who know FreeBSD internals=
<br>
better than I do:<br>
<br>
**1. Is using `$EDITOR` the right hook into freebsd-update?**<br>
Is there a cleaner, more supported way to intercept freebsd-update&#39;s me=
rge<br>
phase? I am essentially abusing the EDITOR variable =E2=80=94 it works, but=
 it feels<br>
fragile. Is there an official API or hook mechanism I am missing?<br>
<br>
**2. The 3-way merge approach =E2=80=94 is merge(1) the right tool?**<br>
I am using `merge(1)` from the `rcs` package. Are there better alternatives=
<br>
in the FreeBSD base system? `diff3(1)` is available but requires more<br>
orchestration. `patch(1)` could work but loses context. Thoughts?<br>
<br>
**3. Handling STABLE and CURRENT upgrades**<br>
Upgrading to a -STABLE or -CURRENT branch is fundamentally different from<b=
r>
a RELEASE upgrade =E2=80=94 freebsd-update behaves differently, and the bas=
e.txz<br>
download path is different. Has anyone automated this reliably?<br>
<br>
**4. The two-reboot major upgrade cycle**<br>
I implemented this using a temporary `rc.d` service (`automerge_resume`)<br=
>
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?<br>
<br>
**5. pkg alignment after major upgrades**<br>
After a major upgrade (e.g. 14.x =E2=86=92 15.x), all installed packages ne=
ed to be<br>
rebuilt or reinstalled. I currently just tell the user to run `pkg upgrade =
-f`<br>
manually. Should this be integrated into the script? What is the safest<br>
sequence?<br>
<br>
---<br>
<br>
## How to get it<br>
<br>
The script is a single self-contained shell file with no external dependenc=
ies<br>
beyond `merge(1)` (from `pkg install rcs`) and optionally `expect(1)` for<b=
r>
auto-confirm mode.<br>
<br>
Usage:<br>
<br>
```sh<br>
# Show interactive target menu (queries mirror live)<br>
sh freebsd-automerge.sh<br>
<br>
# Filter menu to branch 14<br>
sh freebsd-automerge.sh 14<br>
<br>
# Direct upgrade, no menu<br>
sh freebsd-automerge.sh 14.4-RELEASE<br>
<br>
# Fully automated (requires: pkg install expect)<br>
sh freebsd-automerge.sh --auto-confirm 14<br>
```<br>
<br>
---<br>
<br>
## Credits<br>
<br>
The script was conceived and directed by **ZioMario** (<a href=3D"http://fo=
rums.freebsd.org">forums.freebsd.org</a> user: ZioMario), developed with th=
e assistance of **Claude** (Anthropic AI).<br>
The idea, architecture decisions, testing, and debugging were all driven by=
<br>
ZioMario =E2=80=94 Claude was used as an implementation tool.<br>
<br>
All feedback, pull requests, and brutal criticism are welcome.</div><br><sp=
an class=3D"gmail_signature_prefix">-- </span><br><div dir=3D"ltr" class=3D=
"gmail_signature" data-smartmail=3D"gmail_signature">Mario.<br></div></div>

--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: <f_moslgskv0>
X-Attachment-Id: f_moslgskv0

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
--0000000000000c3344065111147f--


home | help