Archlinux tool to track /etc files and .pacnew files using mercurial.
The .pacnew files are tracked in a mercurial branch named pacnew. After a pacman upgrade, the mercurial internal merge tool is used to automatically merge the differences in .pacnew files to the /etc files in the default branch. Merge conflicts are handled with Vim. Merging is done with the merge command:
The sync command is used to retrofit /etc with the result of the merge:
sudo etc-merge sync
The user changes in /etc files is the difference between both branches and may be viewed using mercurial with the Vim DirDiff plugin (an AUR package):
hg vimdiff -r pacnew:default
After a merge, the latest changes in the .pacnew files can be seen using mercurial with the Vim DirDiff plugin:
hg vimdiff -c pacnew
The DirDiff plugin may also be used to view the difference between the repository and /etc with the Vim command:
:DirDiff <path_to_repository> /etc
All the commands (except help) have a –dry-run option to perform a trial run with no changes made. These commands also have a –repo option to specify the location of the repository root directory that is otherwise the current working directory.
Create the repository with a pacnew branch if the repository does not exist. Add the /etc files that have a .pacnew file and are unknown to the repository to the default branch and their .pacnew files to the pacnew branch. Also copy the changed .pacnew files to the pacnew branch and merge the changes to the default branch:
When a .pacnew file does not exist in the repository, the file is added to the default branch (except for passwd and group and not readable files such as sudoers) and its .pacnew file is added to the pacnew branch. Then etc-merge does a null merge as there is no means to know which changes have been brought by this .pacnew file. So the difference between the file and its corresponding .pacnew file may include .pacnew changes as well as user changes. It is important  to correct this so as to have only user changes in this difference: after the merge and sync commands, fix the file in /etc and run the commit command to synchronize /etc to the repository. This needs to be done only the first time when the file is added to the repository.
A merge conflict  is handled with Vim showing three windows, from left to right:
Apply the changes between the previous and latest .pacnew files to the current file in the leftmost window and type :wqa in the leftmost window to save the changes and quit. Or type :cq to abort the merge, this will cause all the the changes made by the previous or following merges in this same session to be reverted, then you can restart the merge all over again.
Synchronize the files of the default branch to /etc:
sudo etc-merge sync
Copy to /etc the files in the default branch whose md5sum differs with the one in /etc and that have a corresponding file in the pacnew branch.
Synchronize /etc files to the default branch and commit the changes:
Copy to the default branch, the /etc files whose md5sum differs with the one in the default branch and that have a corresponding file in the pacnew branch. Then commit the changes.
|||The difference between a file in the default branch and the file in the pacnew branch is an invariant after a merge. So if this difference includes a line that is not a user change and that line is changed much later by a pacman upgrade, then a very much confusing merge conflict will occur because you will have forgotten by that time that you had (wrongly) handled this line as a user change when the file was added to the repository.|
|||Note that the mercurial internal merge tool also considers that there is a conflict when the line of a change between the pacnew files is next to a line that is a user change.|