XSTOW.INI(5)
π XSTOW.INI β the XStow config file, bestie π
okay so this is from the XStow Reference Guide, and the manual is literally called xstow.ini(5). Buckle up, we're reading a config file spec and honestly? it's giving cozy.
β¨ NAME β¨
xstow.ini β literally the config file for XStow. that's it. that's the whole name. iconic.
π§ CONTENT π§
so the xstow.ini file is where you stash some static informations about your system. like, the stuff that doesn't change and that XStow just needs to know.
now here's the tea: you can set most of the necessary values by passing the required command line option instead, and sometimes that's totally fine! but in some cases this won't make sense if you're using xstow quite often β because why would you retype the same flag every single time when you could just write it down once and let the config file carry you. main character energy honestly.
πΈ SYNTAX πΈ
the syntax of the configuration file is simple. fr fr. and the best part? it's the same as it is used by KDE and GNOME, so if you've ever poked at those, you already know the vibe. iykyk.
the data is splitted into keys values and sections. and the # sign marks a comment. here's an example so you can see it with your own eyes:
[traverse-links]
keep-targets = true
link = /usr/tmp # comment
okay let's break down what you're looking at, because it's not scary at all:
[traverse-links]β is a section with the name"traverse-links". sections are like little folders for your settings πkeep-targets = trueβ is a key - value pair, where'keep-targets'is the key and'true'is the value. that's the whole thing, it's justkey = value, no drama π
π₯ PROCESSING π₯
so how does XStow actually deal with all these files? it processes the config files one after another. periodt.
and the way the merging works is lowkey important, so pay attention bestie:
- Static configuration options β like the
[debug]=>moduleoption β can be overwritten by the next config file. so the last one wins, basically. rip to the ones that came before π - List keys β like
[traverse-links]=>linkβ will be appended to the list. they don't get replaced, they just keep piling up. the more the merrier β¨
if you wan't more informations about the current stow setup, call XStow like this:
xstow -s -dl 1 dummy-package | less
and ooh, and if you want to peek at which config files were processed, you'll have to set some environment values for that (see xstow(1) for details, it's got the full lore). eg.:
XSTOW_DEBUG_LEVEL=1 xstow -s -dl 1 dummy-package | less
pro tip from your fav: piping to less is a whole mood, it keeps your terminal from getting spammed and lets you scroll all fancy π«Ά
okay that's this part done, don't go anywhere β there's more coming π
β¨ traverse-links β¨
okay bestie so this section is your lil VIP list π
β you write down the links that xstow should treat as links that are NOT part of any xstow-managed package. like, for FHS compliance it's super common to set a link from /usr/share/man to /usr/man, which makes old applications dump their manpages into /usr/share/man instead of /usr/man. classic.
but xstow is paranoid fr fr π β it assumes the link points at something else entirely, and it refuses to write data into whatever directory that link points to. so dramatic.
the simple fix? just tell xstow which links should be handled like normal directories, and list them right here. easy peasy π
link = LINKβ this value has to be an absolute path to the link that should be handled as a normal directory. the link itself can be an absolute or a relative link, no stress. you can absolutely have more than onelinkkey in this section, go off πkeep-targets = BOOLβ allowed values aretrueand1(case-insensitive, we don't gatekeep). literally anything else gets interpreted as false. ifkeep-targetsis set to true, the target of the links in this section gets automatically added to the keep-dirs section β¨ this stops those targets from getting removed and the links from becoming dead links. we love not breaking things.add-if-target = PATTERNβ auto-adds every link whose target matches the pattern to the link list. XStow uses this as its last chance for solving dependencies β only if all the other tests failed will the application even try applying this test. which means it's totally fine to set[links]=>absolute-linksto true and use a pattern like/*here. no cap. and ifkeep-targetsis true, the applied links get added to the keep-dirs list too π«Άadd-if-target-regex = REGEXβ same asadd-if-targetbut it supports regular expressions. XStow will always try matching the regular expressions before the normal shell patterns, cause a regex can be way more exact than a shell pattern. slay.
π§Ί keep-dirs π§Ί
this section is for the directories that should not be removed. because here's the tea: when xstow removes a package and a directory becomes empty, that directory gets removed too π
dir = DIRβ the value of this key must be an absolute path to the directory that should be kept. you can have more than onedirkey in here, live your truth. and pookie listen: the value should not end with a'/'!!
π matches π
XStow takes this pattern and tries matching it against all the file names it found in packages. only the file names, bestie β so you do not have to care about the slashes at all. iconic behaviour honestly.
ignore = PATTERNβ ignore files matching this pattern. more than oneignorekey is allowed in this section β¨ignore-regex = REGEXβ does the same asignore, but supports regular expressions. XStow will always try matching the regular expressions before the normal shell patterns, cause a regex can be much more exact than a shell pattern.copy = PATTERNβ copy files or directories matching this pattern instead of linking them. this makes sense for some global files that get used by more than one package and get updated during the installation process. files installed this way won't be removed when you unstow a package, since XStow can not handle package dependencies and does not know if any other package requires the file. if a directory matches this expression, the content of the directory gets copied recursively. super useful for some/etcfiles installed by the installation process. and yep, more than onecopykey is allowed here πcopy-regex = REGEXβ does the same ascopy, but supports regular expressions. XStow will always try matching the regular expressions before the normal shell patterns, cause a regex can be much more exact than a shell pattern.nignore = NIGNORE_RULEβ ignore everything except files and directories matching this expression. eg:"systree/bintree". for using nignore support, fnmatch and configration file support has to be enabled. a rule (eg.:"systree/headertree") has a set of subrules (eg.:"systree"and"headertree"). these subrules are defined in a separate section which is named as the subrule. eg, the subrule for"systree":
[systree]
dir = /usr
dir = /usr/local
follow = false
and there's an example config file "nignore.ini" in the doc directory of this package, so go peek π
πΈ NIGNORE-SUB-RULE πΈ
this is the description of a nignore subrule. the section is called like the nignore subrule, eg: "systree". cute, right?
dir = DIRβ directories where a file of the package should be installed. you can use shell pattern's too (eg.:"/man/man*"), but only use this feature if this subrule is the last one in an nignore rule. don't get spicy with it.follow = BOOLβ follow subdirs.
ποΈ stow-dirs ποΈ
dir = DIRβ the value of this key must be an absolute path to the directory that can be handled as if it were part of your own stow directory. this means xstow is allowed to make changes in packages that are related to this directory. more than onedirkey is allowed in this section. and again bestie: the value should not end with a'/'!!auto-add-dirs = PATTERNβ automatically add a directory if it matches this pattern. heads up: in Stow directories that were detected with this pattern, configuration files will never be searched for. and yes, more than oneauto-add-dirskey is allowed in this section β¨auto-add-dirs-regex = REGEXβ does the same asauto-add-dirs, but supports regular expressions. XStow will always try matching the regular expressions before the normal shell patterns, cause a regex can be much more exact than a shell pattern.
π‘οΈ protect-dirs π‘οΈ
the whole goal of this section is limiting the access within a legal target directory. eg.: if your stow directory is '/stow' and you're installing packages this way:
make install DESTDIR=/stow/package_name
but the 'prefix' is set to '/usr/local'. in this case the target directory will be '/', but the real target directory of the package will be '/usr/local'. the following keys within this section let you restrict the installation access within the valid target directory π₯
dir = DIRβ the value of this key must be an absolute path to the directory that has not to be changed. XStow is not allowed to install a package there or within the subdirectories, and will report an error if it would. more than onedirkey is allowed in this section. the value should not end with a'/'!!auto-add-dirs = PATTERNβ automatically add a directory if it matches this pattern. more than oneauto-add-dirskey is allowed in this section.auto-add-dirs-regex = REGEXβ does the same asauto-add-dirs, but supports regular expressions. XStow will always try matching the regular expressions before the normal shell patterns, cause a regex can be much more exact than a shell pattern.target = DIRβ the value of this key must be an absolute path to the directory that is allowed to be changed. if this value is set, XStow will report an error if it would touch any other, or upper directory within the tree. more than onetargetkey is allowed in this section. the value should not end with a'/'!!target-add-traversable-links = BOOLβ automatically add the targets of traversable links to the targets list. this can be useful if you do not add manually all possible targets of traversable links to the target list. by default this value is set tofalse.
so if your stow directory is '/stow' and all packages should be installed in '/usr/local/', a config file like this will make sense:
[traverse-links]
link = /usr/local/etc
[protect-dirs]
target = /usr/local
target-add-traversable-links = true
XStow will report an error if it would install a package outside of '/usr/local' π
π debug π
these values will be ignored if one of these values is set by a command line option. command line stays the main character, sorry.
module = MODULEβ set the default debug module.level = INTEGERβ set the debug level.
βοΈ config-files βοΈ
in-home = BOOLβ search in the home directory for a config file named"xstow.ini"or".xstow.ini". only in the home directory will it be searched for hidden files, that's just how it is.in-stow-dir = BOOLβ search in the current stow directory for a config file.in-other-stow-dirs = BOOLβ search in other public stow directories for config files.file = FILEβ read this config file too. more than onefilekey is allowed in this section π«Ά
π links π
absolute-paths = BOOLβ create links with absolute path names. simple as that.
π exec π
okay story time. if a package comes with some GNU info files, install-info creates an index directory named 'dir' in STOWDIR/PACKAGE/share/info. if this is the first package with an info index file, this won't be a problem π
but if a second package creates another 'dir' file in the packages info directory, this file will not contain the informations from the first package too, and xstow will report a problem unless you use the ignore or copy option.
and here's the thing β using the copy option is not a solution, since the content of each of the files is incomplete. you can use the ignore option and run mkinfodir in the /usr/local/info directory after installing the package with xstow. (such a script is available on various distributions, no worries.)
the other solution is running a program that merges the old and the new 'dir' file. this section provides a hook that allows executing such tools if a file or directory matches a condition. β¨
XStow ships a program called merge-info(1) that can be used this way.
bestie be aware: there can be more than one exec Section within an ini file!!
match = PATTERNexec = COMMANDβ executes the command if a file matches the match expression.%tis replaces by the target file and%sis replaced by the source file.exec-unstow = COMMANDβ executes the command if a file matches the match expression and a package is unstowed. ifexec-unstowis not set and a package gets unstowed, nothing will be executed.%tis replaces by the target file and%sis replaced by the source file.
π EXAMPLE xstow.ini
ok so like. reading the syntax is one thing, but bestie you NEED to see these in the wild, fr fr. here are two whole real configs, screaming and thriving. β¨
π EXAMPLE 1
this one is the classic β it's what you'd write when xstow is out here managing the /usr/local tree like a boss. it's giving sysadmin main character energy π
[traverse-links]
keep-targets = true
link = /usr/local/tmp
link = /usr/local/var
link = /usr/local/man
link = /usr/local/doc
link = /usr/local/info
[keep-dirs]
dir = /usr/local/bin
dir = /usr/local/sbin
dir = /usr/local/lib
dir = /usr/local/include
[matches]
ignore = *~
ignore = core
ignore = core.*
ignore = CVS
[exec]
match = dir # GNU info index file
exec = merge-info %t %s -o %t
exec-unstow = merge-info -u %t %s -o %t
[stow-dirs]
dir = /usr/local/stow
dir = /usr/local/stow2
like. look at her. four link entries in [traverse-links] walking into /usr/local/tmp, /usr/local/var, /usr/local/man, /usr/local/doc and /usr/local/info, keep-targets = true holding it down, a whole [keep-dirs] squad keeping /usr/local/bin, /usr/local/sbin, /usr/local/lib and /usr/local/include from getting clobbered, [matches] ghosting *~, core, core.* and CVS, then [exec] doing the merge-info thing on dir matches (that # GNU info index file is just a little comment, she's serving notes βοΈ, %t is the target, %s is the source), and TWO stow dirs: /usr/local/stow and /usr/local/stow2. iconic. no notes. periodt. π
π¦ EXAMPLE 2
now THIS one is for when xstow is still managing the /usr/local tree, but the stow directory lives all the way over at /stow. wanderlust behavior lowkey πΈ
[matches]
ignore = *~
ignore = CVS
ignore = core*
[stow-dirs]
dir = /stow
[protect-dirs]
target = /usr/local
see the glow-up? [matches] is being pickier β only *~, CVS and core* get ignored this time (core* with the star, she's feral like that π€). [stow-dirs] has exactly ONE dir, and it's /stow. and then [protect-dirs] shows up with target = /usr/local to keep that whole tree safe. queen shit. π‘οΈ
π SEE ALSO
xstow(1)merge-info(1)xstow.ini fileβ yeah girl, the file you're literally reading the manual for rn π
and that's the whole page bestie!! you made it to the end, you absolute legend π«Ά go forth and write the most immaculate xstow.ini the world has ever seen. slay. π
β¨
this gorgeous manual is from XStow 1.1.1, dated 2026-02-10, and it lives at XSTOW.INI(5). take care of her. π
π¦ where this page comes from
- ubuntu resolute: xstow 1.1.1-1build1
- ubuntu stonking: xstow 1.1.1-1build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms