Bug 252417 - mergemaster: deprecation and removal plan
Summary: mergemaster: deprecation and removal plan
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Enji Cooper
Depends on:
Reported: 2021-01-04 19:24 UTC by Enji Cooper
Modified: 2021-04-05 15:34 UTC (History)
9 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Enji Cooper freebsd_committer 2021-01-04 19:24:35 UTC
mergemaster(8) has been deprecated for several releases and its replacement--etcupdate(8)--has been present in production systems since at least 9.x/10.x.

Reasons for deprecating/removing mergemaster(8) are as follows:
1. It doesn't have a maintainer.
2. It's not being actively developed.
3. It was made fragile with the move from svn to git (it relies on RCS tags like $FreeBSD$, which are no longer incremented when touched, requiring manual human intervention).

It's past time to replace mergemaster(8) with etcupdate(8).

This bug will track the following items:
* Reconciling all missing features (if any) between etcupdate(8) and mergemaster(8) so the transition can be relatively painless.
* Replacing mergemaster(8) with etcupdate(8) in documentation (in base and docs). Affected areas [in base] in my svn checkout (which is admittedly dated) appear to be as follows:
$ grep -rIl mergemaster .

* Adding appropriate messaging in the utility to note the deprecation/removal plan.
Comment 1 VVD 2021-01-05 00:52:03 UTC
Please, write an "article/howto" with description of the migration from mergemaster to etcupdate.
Fore example I want to see an equivalent of the "mergemaster -iUF".
Comment 2 jakub_lach 2021-02-01 21:36:23 UTC
(In reply to VVD from comment #1)

Yes, I'm currently lookig for a etcupdate drop-in replacement for 'mergemaster -Ui'
Comment 3 John Baldwin freebsd_committer freebsd_triage 2021-02-02 16:43:51 UTC
etcupdate's default behavior is to always do the equivalent of -Ui.  etcupdate keeps the previous "unmodified" version of each /etc file around in /var/db/etcupdate/current (this is what enables it to do 'etcupdate diff' for example as it runs a diff of files in /etc against those unmodified copies).  On each update, etcupdate generates a new tree and then does a 3-way merge copying over any new files or updating changed files for which the file in /etc matches the old version (equivalent to -Ui).  In addition, if you have local changes in a file in /etc, it uses diff3 to generate a 3-way merge similar to 'svn up' or 'cvs up', etc. and if the changes do not conflict, it installs the updated file with the new changes merged in but local changes kept.  If the changes conflict, it saves a version with conflict markers for the user to manually resolve.  At the end of 'etcupdate', it lists any conflicts you manually need to resolve.  For those, you run 'etcupdate resolve' which gives you options to either keep your version, install the new version only, or invoke an editor to resolve the changes.

In my experience, manual conflicts are quite rare and most of the time after an upgrade you just run 'etcupdate' after 'make installworld' and it auto-updates any files you have without requiring any user interaction.

Brand new installs come with etcupdate bootstrapped, so if you install a new VM, etc. you can use 'etcupdate' after your first 'make installworld' and it will work fine.

If you have done several worlds with 'mergemaster' instead, then etcupdate's database in /var/db/etcupdate is stale.  You can overwrite the database by doing 'etcupdate extract' _before_ you do an 'svn up' or 'git pull'.  To check to see what local diffs etcupdate thinks you have, run 'etcupdate diff' (it outputs a patch).
Comment 4 jakub_lach 2021-02-03 14:41:13 UTC
(In reply to John Baldwin from comment #3)

Great summary, thanks. Only thing I feel is not stressed enough - before first use of etcupdate you need to run 'etcupdate extract' to bootstrap etcupdate _before_ updating /usr/src (you need to have src aligned to the already running system).
Comment 5 Antoine 2021-03-21 13:18:25 UTC
Upgrading jail/etc was simple with mergemaster -xxx -D /jail_root_filesystem/ from inside the host containing /usr/src.
Now it seems that /usr/src has to be mounted then etcupdate executed from inside each jail. 
Any other easiest way ?
Comment 6 Christos Chatzaras 2021-03-21 13:30:03 UTC
(In reply to Antoine from comment #5)

I use these commands:

cd /usr/src
etcupdate -p -D /home/jail/redis
make installworld DESTDIR=/home/jail/redis
etcupdate -D /home/jail/redis
make -DBATCH_DELETE_OLD_FILES delete-old DESTDIR=/home/jail/redis
make -DBATCH_DELETE_OLD_FILES delete-old-libs DESTDIR=/home/jail/redis