Yesterday the arch community announced the successful migration to git. Congrats at this point.
Reading the news article and the steps to use the new repositories I stumbled over the lines "merge the pacman pacnew /etc/pacman.conf.pacnew file".
I compared the two files (my existing and the new one) with nvim -d (or vimdiff) and thought is it possible to merge the files like I am used to within a git repository?
My experience is from Fedora/Centos where rpm might produce
*.rpmsaveor*.rpmnewfiles, but I am assuming*.pacnewfiles behave in the exact same way.Yes it is. It requires a little bit of setup but it is absolutely doable.
Step 1, Install etckeeper
Etckeeper is a program that
THIS IS PROGRAM THAT EVERYONE SHOULD INSTALL, independently of plans of using git merge.
Etckeeper has had full support for Arch since 2021.
Step 2, create an additional worktree for
/etcWorktree in general
When you clone or initializes a repository with git you end up having the repo object storage where git stores commits in the
.gitdirectory, the index/staging/cache which also is stored in.gitand a working directory which contains the files corresponding to the current commit. And there is a one to one relation between them.However git supports connecting multiple working directories to the same repo object storage through the worktree command. The additional worktrees shares the original
.gitdirectory but gets their own indexes, and the files are checked out in different directories. Only one single worktree can check out a given branch (although you can of course check out any specific commit, or use a mirroring branch).Typical use cases for creating additional worktrees are for instance
Worktree for storing the contents of
/etcIf you use
/etcas your worktree when doing interactive rebase, then notice that git checks out older commits, and thus/etcsuddenly contains old versions of various config files. This not unlikely to represent a problem for some services. And when there is a conflicts where git inserts the "<<<<<"/">>>>>" markers, you will have config files that definitely have invalid syntax/content which is unlikely to not represent a problem.So for these reasons, you should consider
/etcas the production system that you normally do not touch and rather create an additional worktree as the staging system where you are free to break and make modifications to.Step 3, taking advantage of git for merging
In order to make use of git's merge power you need to keep your own changes separate from the upstream changes on separate branches (this sounds more complicated than it actually is). By having a branch which contains the upstream changes, you can then merge this branch and git is able to use its merge algorithm properly.
You only need to do this for files that end up producing
.pacnewor.rpmnewfiles and you can do this retroactively, so it is fine to just start with onemainbranch and oneworktree-mainbranch, and add upstream branches as needed over time.You need one branch per file with upstream changes you want to merge (e.g. this only applies to files that you have made local changes to which then prevents the package manager to update).
Example
One of my machines started out being installed with Fedora 26 in 2017. Why do I know that? Because etckeeper is the second program to install on my list of what to do on a new machine (only installing a full vim version has higher priority), and the first commit which
/etc/hostsis present in has commit message "Fresh install of Fedora 26". Did I mention how awesome etckeeper is?Over time I have added a few entries to
/etc/hosts(and thanks to etckeeper I know exactly when!). The initialhostsfrom Fedora 26 only contained two lines, but then in September 2022 (how do I know when?...) an update to thesetuppackage came with a newhostsfile which contained 5 additional comment lines. Since I had modifiedhoststhis new version ended up as/etc/hosts.rpmnew.So this is how I handled that update:
I ran
git log -p hoststo figure out what the newest commit before I started modifying it was. It was actually commit 1d49be6b Fresh install of Fedora 26. So that is the starting point for the upstream update branch.My branch naming policy is to prefix all such upstream branches with
rpmnewsince*.rpmnewfiles will be the source for the content of those. You can decide to use the full path in the branch or just the file name. For some cases like/etc/mock/default.cfgusingrpmnew/mock/default.cfgis obviously a much better choice thanrpmnew/default.cfgwhile usingrpmnew/sshd_configfor/etc/ssh/sshd_configmight be ok, just make a choice (where a hybrid approach is a possibility).So with that in mind, I created a
rpmnew/hostsbranch and updated it with the newhosts.rpmnewcontent.Notice that this resets the worktree's content back to 2017, but that's fine because is not used for anything else. If I had worked directly in
/etcthat would have been a huge problem.So the upstream changes branch is updated and I can then merge it into the
mainbranch (viaworktree-mainfirst).The last merge command might result in conflicts, and if so you need to resolve those. I highly recommend using KDiff3 for conflict resolution.
After the merge is done then
worktree-mainis one merge commit ahead ofmain. This one we want to update/etcto use.and that's it.
/etcwas moved forward from whatever today's content was to today's content plus an update tohostsand git made use of its merge functionality along the way.