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 just key = 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]=>module option β€” 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 πŸ’–

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 one link key in this section, go off πŸ’–
  • keep-targets = BOOL β€” allowed values are true and 1 (case-insensitive, we don't gatekeep). literally anything else gets interpreted as false. if keep-targets is 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-links to true and use a pattern like /* here. no cap. and if keep-targets is true, the applied links get added to the keep-dirs list too 🫢
  • add-if-target-regex = REGEX β€” same as add-if-target but 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 one dir key 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 one ignore key is allowed in this section ✨
  • ignore-regex = REGEX β€” does the same as ignore, 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 /etc files installed by the installation process. and yep, more than one copy key is allowed here πŸ’œ
  • copy-regex = REGEX β€” does the same as copy, 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 one dir key 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 one auto-add-dirs key is allowed in this section ✨
  • auto-add-dirs-regex = REGEX β€” does the same as auto-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 one dir key 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 one auto-add-dirs key is allowed in this section.
  • auto-add-dirs-regex = REGEX β€” does the same as auto-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 one target key 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 to false.

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 one file key is allowed in this section 🫢

  • 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 = PATTERN
  • exec = COMMAND β€” executes the command if a file matches the match expression. %t is replaces by the target file and %s is replaced by the source file.
  • exec-unstow = COMMAND β€” executes the command if a file matches the match expression and a package is unstowed. if exec-unstow is not set and a package gets unstowed, nothing will be executed. %t is replaces by the target file and %s is 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