Usage

State diagram

[alpm-conf state diagram]
The alpm-conf subcommands are:
  • help

  • diff a standalone utility

  • create, update, merge, state, reset and clean for managing the alpm-conf repository

Running the update subcommand followed by the merge subcommand updates the /etc directory with the changes introduced by new package archives and updates the master branch with changes in the /etc directory. The state subcommand prints the current state. It is either start, no-cherry-pick, cherry-pick or cherry-pick-conflict.

Help on a subcommand is printed by:

$ alpm-conf help <subcommand>

The alpm-conf man page section lists the options available for each subcommand.

alpm-conf does not need to be run within its git repository, however conflicts must be resolved from within the repository.

Terminology

etc-file

A file within the /etc directory.

user-file

An etc-file that has been created by the root user (such as a netctl profile) and that is tracked in the master branch.

cherry-pick

The changes in the new [1] etc-files extracted from new versions of package archives that are different from the original files in the previous version and that have been modified by the root user in the current instanciation of the file in the /etc directory are commited in the etc_tmp branch as a single commit. The update subcommand merges these changes into the master-tmp branch by running the git cherry-pick command on the master-tmp branch using the sha of this commit from the etc-tmp branch.

The files in the list of files of the cherry-pick commit are copied to the /etc directory by the merge subcommand.

Git repository

The master-tmp, etc-tmp and packages-tmp temporary branches are created by the update subcommand at respectively the master, etc and packages branches. All the changes made by the update subcommand are made in the temporary branches. These branches are merged into their ancestor as a fast-forward merge by the merge subcommand. The temporary branches are deleted after the merge.

master branch
  • etc-files installed by pacman archives and modified by the root user

  • user-files

etc branch
  • etc-files of the package archives currently installed

packages branch
  • files whose names are the names of the packages currently installed owning etc-files that are not symlinks; each file contains the package version and the sha256 of their etc-files

The master-prev, etc-prev and packages-prev tags are created at their respective branch just before the fast-forward merge.

Commands

create

Create the git repository and populate the master branch with files installed by pacman in the /etc directory that have been modified by the root user. The subcommand may be issued by the root user or by a plain user, the next alpm-conf subcommands should be issued by the owner of the repository except for the merge subcommand.

The git repository is located at the directory specified by the command line option --gitrepo-dir when this option is set, otherwise at $XDG_DATA_HOME/alpm-conf if the XDG_DATA_HOME environment variable is set, otherwise at $HOME/.local/share/alpm-conf.

Note

An etc-file added to the master branch by this subcommand may have been modified in the /etc directory a long time ago and never updated since then. The file may be very different from the one in the latest package version. In that case, when a new version of this file is installed by pacman, the following update subcommand may end in the cherry-pick-conflict state because the file in the master branch originates from a too old version.

update

Update the master-tmp branch after:

  • a pacman upgrade

  • modifications in the /etc directory of pacman installed etc-files

  • modifications in the /etc directory of user-files (i.e. files tracked by the master branch)

After the command has completed, the alpm-conf state is either no-cherry-pick, cherry-pick or cherry-pick-conflict.

The update subcommand calls git cherry-pick when there are changes in the etc-files extracted from new versions of package archives and the corresponding files in the /etc directory have been changed. There is a cherry-pick conflict when git cannot merge all the changes into the master-tmp branch and alpm-conf enters the cherry-pick-conflict state. One must resolve the conflicts to enter the cherry-pick state and to be able to run the merge subcommand. A git cherry-pick is just like a git merge, so one may use an editor to resolve the conflicts such as vim or emacs when a git mergetool has been configured.

Running git cherry-pick --abort also sets the alpm-conf state to cherry-pick. However this discards all the changes made by the new package versions and the cherry-pick becomes empty. Use instead the alpm-conf reset subcommand to abort the cherry-pick even in the middle of a partial attempt to resolve the conflicts. After the reset the alpm-conf state becomes start.

merge

The merge subcommand:

  • copies the changes made to the master-tmp branch by the cherry-pick to the /etc directory when the current state is cherry-pick

  • runs a git fast-forward merge of the temporary branches

  • deletes the temporary branches

When the current state is cherry-pick, the subcommand must be run with root privileges [2]. When the alpm-conf repository is owned by a plain user it may be useful to run the sudo or su subcommand to preserve the user’s environment (to access the location of the repository for example). This is done with the following subcommand line arguments:

  • sudo

    -E or –preserve-env

  • su

    -m or -p or –preserve-environment

state

The state subcommand prints the current alpm-conf state. See State diagram.

clean

The clean subcommand removes recursively files not under version control. For example backup files created by the editor while merging a conflict.

The alpm-conf subcommands update and merge require a clean working area because git will fail to switch between branches when a tracked file has been modified.

reset

The reset subcommand resets the alpm-conf state to start:

  • remove recursively files not under version control

  • reset the index and working tree by running the git reset --hard command

  • delete the temporary branches

diff

The diff subcommand prints the differences between the etc files of installed pacman package archives and the corresponding files modified in the /etc directory:

  • run the create subcommand to create the alpm-conf repository in a temporary directory

  • run the git diff --diff-filter=M etc master -- within the repository

  • remove the temporary directory upon completion of the command

Using the –difftool option allows using an editor for browsing the changes instead of printing the diffs.

Checking changes with git

The following git commands are run within the git repository (obviously).

List the user-file names (see Terminology):

$ git diff --name-only --diff-filter=A etc master --

Note

It is easier to use an editor when browsing differences between files in the following git commands. In order to use an editor with git one can use a git diff tool instead of the git diff command. For example diff can be replaced with ediff in the following commands when git is configured to use emacs or replaced with difftool when git is configured to use gvim as shown in the next Git tools section.

Print the changes before a merge subcommand:

$ git diff --diff-filter=M master...master-tmp

Print the changes after a merge subcommand, that is after the temporary branches have been merged and deleted [3]:

$ git diff --diff-filter=M master-prev...master

Print the differences between the etc-files of the package archives currently installed by pacman and the corresponding files modified in the /etc directory [4]:

$ git diff --diff-filter=M etc master --

Print the differences between one etc-file of the package archive currently installed by pacman and the corresponding file modified in the /etc directory:

$ git diff etc master -- etc/pacman.conf

Git tools

Git tools may be configured in $HOME/.gitconfig to use an editor for browsing differences in git revisions or for merging conflicts. The following links point to the corresponding documentation:

emacs git tools

With the following configuration and the emacs ediff major mode loaded, one may run git ediff in place of the git diff command and git mergetool in place of the git merge command in order to use emacs as a git tool:

[diff]
    tool = ediff-difftool

[difftool "ediff-difftool"]
    prompt = false
    cmd = emacs --no-desktop --eval \"(ediff-directories\
            \\\"$LOCAL\\\" \\\"$REMOTE\\\" nil)\" \
            2>/dev/null

[merge]
    tool = ediff-mergetool

[mergetool "ediff-mergetool"]
    keepBackup = false
    trustExitCode = true
    cmd = emacs --no-desktop --eval \"(ediff-merge-files-with-ancestor\
            \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" nil \\\"$MERGED\\\")\" \
            2>/dev/null

[alias]
    ediff = difftool -d

vim git tools

With the following configuration, one may run git difftool in place of the git diff command and git mergetool in place of the git merge command in order to use gvim as a git tool:

[merge]
    tool = gvimdiff

See also Git documentation on vimdiff.

Footnotes