## File: README.md

# Mackup™

[](https://github.com/lra/mackup/actions/workflows/test.yaml)
[](https://badge.fury.io/py/mackup)
[](https://pypi.org/project/mackup/)
[](https://github.com/astral-sh/ruff)
[](http://mypy-lang.org/)
[](https://github.com/lra/mackup/blob/master/LICENSE)

Backup and keep your application settings in sync.

## Table of contents

- [Mackup™](#mackup)
  - [Table of contents](#table-of-contents)
  - [Quickstart](#quickstart)
  - [Usage](#usage)
  - [What does it do](#what-does-it-do)
    - [Copy mode](#copy-mode)
    - [Link mode](#link-mode)
      - [`mackup link install`](#mackup-link-install)
      - [`mackup link`](#mackup-link)
      - [`mackup link uninstall`](#mackup-link-uninstall)
  - [Supported Storages](#supported-storages)
  - [Unsupported Storages](#unsupported-storages)
  - [Supported Applications](#supported-applications)
  - [Can you support application X](#can-you-support-application-x)
  - [Personalization \& configuration](#personalization--configuration)
  - [Why did you do this](#why-did-you-do-this)
  - [What platforms are supported](#what-platforms-are-supported)
  - [What's up with the weird name](#whats-up-with-the-weird-name)
  - [Architecture](#architecture)
  - [Where can I find more information](#where-can-i-find-more-information)

## Quickstart

On macOS or Linux, if you want an easy install, you can install
[Homebrew](http://brew.sh/) and do:

```bash
# Install Mackup
brew install mackup

# Launch it and back up your files
mackup backup
```

If not running macOS or Linux, or you don't like Homebrew, you can use [pip](https://pip.pypa.io/en/stable/).

```bash
# Install Mackup with PIP
pip install --upgrade mackup

# Launch it and back up your files
mackup backup
```

You're all set and can back up from now on.

Next, on any new workstation, do:

```bash
# Install Mackup
brew install mackup

# Launch it and restore your files
mackup restore
```

Done!

You can find more detailed instructions in [INSTALL.md](INSTALL.md).

## Usage

`backup`, `restore`, `link install`, `link uninstall` and `link` operate on all
of your configured applications by default. To limit a command to a single
application, add its name (the identifier shown by `mackup list`), e.g.
`mackup backup vim`. Naming an application overrides the
`[applications_to_sync]` / `[applications_to_ignore]` settings in your
`.mackup.cfg`, so you can act on any supported app without editing your config.

`mackup backup [application]`

Back up your application files. Copy your local config files into the Mackup folder.
Name an application to back up only that one, e.g. `mackup backup vim`.

`mackup restore [application]`

Restore your application settings on a newly installed workstation.
Copy config files from the Mackup folder to your home folder.
Name an application to restore only that one, e.g. `mackup restore emacs`.

`mackup link install [application]`

Move your local config files into the Mackup folder,
and link them to their original place.
Name an application to install only that one.

$${\color{red}warning}$$ _the `link` strategy [doesn't work correctly on macOS](#link-mode)_

`mackup link [application]`

On another workstation, links local config files from the Mackup folder.
Name an application to link only that one.

`mackup link uninstall [application]`

Copy back any synced config file to its original place.
Removes the links and copies config files from the Mackup folder back into your
home.
Name an application (e.g. `mackup link uninstall git`) to unlink only that one;
scoping to an application skips the global uninstall confirmation.

`mackup list`

Display the list of applications supported by Mackup.

`mackup -h`

Get some help, obviously...

## What does it do

By only tracking pure configuration files, it keeps the crap out of your
freshly new installed workstation (no cache, temporary and locally specific
files are transferred).

Mackup makes setting up the environment easy and simple.

There are 2 modes of operations: copy mode and link mode.

### Copy mode

Copy mode is used to back up and restore your files.
The files are backed up into the configured Mackup folder,
which can be in Dropbox, iCloud, or wherever you configure it.

It is covered by the 2 commands:

- `mackup backup`
- `mackup restore`

### Link mode

> [!WARNING]
> If you are using Mackup on a current version of macOS, link mode will BREAK
  YOUR PREFERENCES. macOS Sonoma (macOS 14) and later don't support symlinked
  preferences, see [issue #2035](https://github.com/lra/mackup/issues/2035) for
  additional information. [PR #2085](<https://github.com/lra/mackup/pull/2085>)
  added copy mode, which should be used instead.

Link mode is used to move your config files into the Mackup folder,
and link them back to their original place.

This mode is useful if you are using multiple workstations,
and want to keep your application settings in sync at all times.

- Backs up your application settings in a safe directory (e.g. Dropbox)
- Syncs your application settings among all your workstations
- Restores your configuration on any fresh install in one command line

Let's take `git` as an example. Your settings for `git` are saved in your home
folder, in the `.gitconfig` file.

It is covered by the 3 commands:

- `mackup link install`
- `mackup link`
- `mackup link uninstall`

#### `mackup link install`

If you have Dropbox, these things happen when you launch `mackup link install`:

1. `cp ~/.gitconfig ~/Dropbox/Mackup/.gitconfig`
2. `rm ~/.gitconfig`
3. `ln -s ~/Dropbox/Mackup/.gitconfig ~/.gitconfig`

Now your `git` config is always backed up and up to date on all your workstations.

#### `mackup link`

When you launch `mackup link`, here's what it's really doing:

1. `ln -s ~/Dropbox/Mackup/.gitconfig ~/.gitconfig`

That's it, you got your `git` config setup on your new workstation.

`mackup` does the same for any supported application.

#### `mackup link uninstall`

You can revert all your files to their original state.

```bash
# Just run this
mackup link uninstall
```

This will remove the symlinks and copy back the files from the Mackup folder in
Dropbox to their original places in your home. The Mackup folder and the files
in it stay put, so that any other computer also running Mackup is unaffected.

To revert a single application instead, name it, e.g.
`mackup link uninstall git`. Scoping the command to an application unlinks only
that app — the rest of your setup and the Mackup config itself are left in
place, and the global uninstall confirmation is skipped.

## Supported Storages

- [Dropbox](https://www.dropbox.com/)
- [Google Drive](https://drive.google.com/)
- [iCloud](http://www.apple.com/icloud/)
- Anything able to sync a folder (e.g. [Git](http://git-scm.com/))

See the [README](doc/README.md) file in the doc directory for more info.

## Unsupported Storages

- [Box](https://www.box.com): No longer supported as it ignores dotfiles, see
  <https://github.com/lra/mackup/issues/807>.

## Supported Applications

- [1Password 4](https://agilebits.com/onepassword)
- [2Do](http://www.2doapp.com/)
- [Ack](http://beyondgrep.com/)
- [act](https://github.com/nektos/act)
- [ActivityWatch](http://activitywatch.net/)
- [Adium](https://adium.im/)
- [Adobe Camera Raw](http://www.adobe.com/products/photoshop/extend.html)
- [Adobe Illustrator CC](https://www.adobe.com/products/illustrator.html)
- [Adobe Photoshop CC](http://www.adobe.com/products/photoshop.html)
- [Adobe Photoshop Lightroom CC](https://www.adobe.com/products/photoshop-lightroom.html)
- [Adobe Photoshop Lightroom Classic](https://www.adobe.com/de/products/photoshop-lightroom-classic.html)
- [aerc](https://aerc-mail.org/)
- [AeroSpace](https://github.com/nikitabobko/AeroSpace)
- [Affinity Designer](https://affinity.serif.com/designer)
- [Affinity Photo](https://affinity.serif.com/photo)
- [Affinity Publisher](https://affinity.serif.com/publisher)
- [Airflow](https://airflowapp.com/)
- [Airmail](http://airmailapp.com/)
- [Akamai-CLI](https://developer.akamai.com/cli)
- [Alacritty](https://github.com/jwilm/alacritty)
- [AlDente](https://apphousekitchen.com/)
- [AltTab](https://alt-tab-macos.netlify.app/)
- [Amethyst](https://ianyh.com/amethyst/)
- [Ancient Domains of Mystery](http://www.adom.de/home/index.html)
- [Android Studio](https://developer.android.com/sdk/)
- [Ansible](http://www.ansible.com/)
- [AppCleaner](http://freemacsoft.net/appcleaner/)
- [AppCode](http://www.jetbrains.com/objc/)
- [Apple Music](https://www.apple.com/apple-music/)
- [Apptivate](http://www.apptivateapp.com/)
- [Arara](https://github.com/cereda/arara)
- [aria2c](http://aria2.sourceforge.net/)
- [Arm](https://www.atagar.com/arm/)
- [Artistic Style](http://astyle.sourceforge.net)
- [asciinema](https://asciinema.org/)
- [asdf version manager](https://github.com/asdf-vm/asdf)
- [Aspell](http://aspell.net/)
- [Atlantis](http://www.riverdark.net/atlantis/)
- [Atom](https://atom.io/)
- [Audacious](http://audacious-media-player.org/)
- [AusKey](https://abr.gov.au/AUSkey/)
- [Autokey](https://code.google.com/p/autokey/)
- [Awareness](http://iamfutureproof.com/tools/awareness/)
- [AWS Command Line Interface](https://aws.amazon.com/cli/)
- [Bartender](http://www.macbartender.com/)
- [Base](https://menial.co.uk/base/)
- [Bash it](https://github.com/Bash-it/bash-it)
- [Bash](http://www.gnu.org/software/bash/)
- [Bat](https://github.com/sharkdp/bat)
- [Bc](https://www.gnu.org/software/bc/)
- [Beatport Pro](https://www.beatport.com/desktop)
- [Beets](http://beets.io/)
- [BetterSnapTool](http://www.boastr.net/)
- [BetterTouchTool](http://www.boastr.net/)
- [Beyond Compare](https://scootersoftware.com/)
- [BibDesk](http://bibdesk.sourceforge.net/)
- [Billings Pro Server Admin](https://www.marketcircle.com/billingspro/download/billingspro-server/)
- [BitBar](https://getbitbar.com/)
- [Bitchx](http://www.bitchx.org/)
- [Blackfire](https://blackfire.io/)
- [ble.sh](https://github.com/akinomyoga/ble.sh)
- [Blender](https://blender.org/)
- [Boto](https://github.com/boto/boto)
- [Boxer](http://boxerapp.com)
- [Brackets](http://brackets.io/)
- [Brave](https://brave.com/)
- [Btop](https://github.com/aristocratos/btop)
- [Bump](https://github.com/fabiospampinato/bump)
- [Bundler](http://bundler.io)
- [Byobu](http://byobu.co/)
- [Caffeine](http://lightheadsw.com/caffeine/)
- [Calibre](https://calibre-ebook.com/)
- [Capture One](http://www.phaseone.com/Imaging-Software/Capture-One.aspx)
- [Cartographica](https://www.macgis.com/)
- [Cerebro](https://cerebroapp.com/)
- [Charles](http://www.charlesproxy.com)
- [Cheat](https://github.com/chrisallenlane/cheat)
- [Chef](https://www.chef.io/chef/)
- [Chicken](http://sourceforge.net/projects/chicken/)
- [Choosy](https://www.choosyosx.com/)
- [chunkwm](https://github.com/koekeishiya/chunkwm)
- [Cider](https://github.com/msanders/cider)
- [ClashX](https://github.com/yichengchen/clashX)
- [Clasp](https://github.com/google/clasp)
- [Claude Code](https://www.claude.com/product/claude-code)
- [CleanShot](https://cleanshot.com/)
- [Clementine](https://www.clementine-player.org/)
- [CLion](https://www.jetbrains.com/clion/)
- [ClipMenu](http://www.clipmenu.com/)
- [Clipy](https://clipy-app.com/)
- [CloudApp](http://getcloudapp.com/)
- [Coda 2](http://panic.com/coda/)
- [Codex](https://openai.com/codex/)
- [Colloquy](http://colloquy.info/)
- [ColorSchemer Studio 2](http://www.colorschemer.com/osx_info.php)
- [ColorSlurp](http://colorslurp.com/)
- [ColorSync](https://en.wikipedia.org/wiki/ColorSync)
- [Composer](https://getcomposer.org/)
- [Concentrate](http://www.getconcentrating.com/)
- [Conky](https://github.com/brndnmtthws/conky)
- [Consular](https://github.com/achiu/consular)
- [Context7](https://context7.com/)
- [Contexts](https://contexts.co)
- [ControlPlane](http://www.controlplaneapp.com/)
- [CopyQ](https://github.com/hluk/CopyQ)
- [CoRD](http://cord.sourceforge.net/)
- [CotEditor](http://coteditor.com/)
- [Ctags](http://ctags.sourceforge.net/)
- [Cursor](https://cursor.sh/)
- [cVim](https://github.com/1995eaton/chromium-vim)
- [Cyberduck](https://cyberduck.io/)
- [DaisyDisk](https://daisydiskapp.com)
- [Dash](https://kapeli.com/dash)
- [DataGrip](https://www.jetbrains.com/datagrip/)
- [Day-O](http://www.shauninman.com/archive/2011/10/20/day_o_mac_menu_bar_clock)
- [DBeaver](https://dbeaver.io/)
- [DbVisualizer](https://www.dbvis.com/)
- [Deal Alert](http://dealalertapp.com/)
- [Deepin-dde-dock](https://github.com/linuxdeepin/dde-dock)
- [Deepin-dde-file-manager](https://www.deepin.org/en/original/dde-file-manager/)
- [Deepin-Terminal](https://github.com/linuxdeepin/deepin-terminal)
- [Default Folder X](http://www.stclairsoft.com/DefaultFolderX/)
- [Devil's Pie 2](http://www.gusnan.se/devilspie2/)
- [Devil's Pie](<https://en.wikipedia.org/wiki/Devil's_Pie_(software)>)
- [dig](<http://en.wikipedia.org/wiki/Dig_(command)>)
- [Divvy](http://mizage.com/divvy/)
- [Docker](https://www.docker.com/)
- [Dolphin](https://dolphin-emu.org/)
- [Doom Emacs](https://github.com/hlissner/doom-emacs)
- [Double Commander](http://doublecmd.sourceforge.net/)
- [Doxie](http://www.getdoxie.com/)
- [Dozer](https://github.com/Mortennn/Dozer)
- [Draft](https://draft.sh/)
- [Droplr](https://droplr.com/)
- [Dropzone 3](https://aptonic.com/dropzone3/)
- [Drush](http://www.drush.org/)
- [Eagle (ogdesign)](https://eagle.cool/)
- [EditorConfig](http://editorconfig.org/)
- [Electrum](https://electrum.org/#home)
- [Elgato StreamDeck](https://www.elgato.com/en/welcome-to-stream-deck)
- [Emacs](http://www.gnu.org/software/emacs/)
- [Enjoyable](https://yukkurigames.com/enjoyable/)
- [Environmental Station Alpha](http://www.hempuli.com/esa/)
- [eqMac2](https://bitgapp.com/eqmac/)
- [ESLint](https://eslint.org/)
- [espanso](https://espanso.org)
- [Exercism](http://exercism.io/)
- [ExpanDrive](http://www.expandrive.com/)
- [Factorio](https://www.factorio.com)
- [Factory Droid](https://factory.ai/)
- [Fantastical](http://flexibits.com/fantastical)
- [fasd](https://github.com/clvv/fasd)
- [fastlane](https://fastlane.tools)
- [FastScripts](https://redsweater.com/fastscripts/)
- [Feeds](http://www.feedsapp.com/)
- [FileZilla](https://filezilla-project.org/)
- [Finicky](https://github.com/johnste/finicky)
- [Fish](http://fishshell.com/)
- [Fisher](https://github.com/jorgebucaran/fisher)
- [Flake8](https://flake8.pycqa.org/)
- [Flameshot](https://flameshot.org)
- [FlexGet](http://flexget.com/)
- [Flux](https://justgetflux.com/)
- [Focus](https://heyfocus.com)
- [Fontconfig](https://www.freedesktop.org/wiki/Software/fontconfig/)
- [FontExplorer X](http://www.fontexplorerx.com/)
- [Forge](http://www.slightlymagic.net/wiki/Forge)
- [Fork](https://git-fork.com/)
- [ForkLift](http://www.binarynights.com/forklift/)
- [Franz](https://meetfranz.com)
- [Gas Mask](https://github.com/2ndalpha/gasmask/)
- [gdb](https://www.gnu.org/software/gdb/)
- [Gear Player](https://www.gearmusicplayer.com/)
- [GeekTool](http://projects.tynsoe.org/en/geektool/)
- [GHCi](https://wiki.haskell.org/GHC/GHCi)
- [Ghidra](https://ghidra-sre.org)
- [Ghostty](https://ghostty.org/)
- [Ghostwriter](https://wereturtle.github.io/ghostwriter/)
- [Gimp](https://www.gimp.org/)
- [Git Hooks](https://github.com/git-hooks/git-hooks)
- [Git](http://git-scm.com/)
- [Gitbox](http://gitboxapp.com/)
- [GitFox](https://www.gitfox.app)
- [GitHub CLI](https://cli.github.com/)
- [GitKraken](https://www.gitkraken.com)
- [GitUp](http://gitup.co/)
- [Gmail Notifr](http://ashchan.com/projects/gmail-notifr)
- [gmailctl](https://github.com/mbrt/gmailctl)
- [GMVault](http://gmvault.org/)
- [Gnome SSH Tunnel Manager](http://sourceforge.net/projects/gstm/)
- [GNU Stow](https://www.gnu.org/software/stow/)
- [GnuPG](https://www.gnupg.org/)
- [Go2Shell](http://zipzapmac.com/Go2Shell)
- [Goku](https://github.com/yqrashawn/GokuRakuJoudo)
- [GoLand](https://www.jetbrains.com/go/)
- [Goldendict](http://goldendict.org/)
- [GoodSync](https://goodsync.com/)
- [GoShare](https://github.com/dictget/goshare)
- [Gradle](http://gradle.org)
- [GrandTotal 3](http://www.mediaatelier.com/GrandTotal4/)
- [grsync](http://www.opbyte.it/grsync/)
- [Hammerspoon](http://www.hammerspoon.org/)
- [HandBrake](https://handbrake.fr/)
- [Hands Off!](http://www.oneperiodic.com/products/handsoff/)
- [Hazel](http://www.noodlesoft.com/hazel.php)
- [Helix](https://helix-editor.com/)
- [Hero Lab](http://www.wolflair.com/index.php?context=hero_lab)
- [Heroku](https://www.heroku.com/)
- [HexChat](https://hexchat.github.io/)
- [Hexels](http://hexraystudios.com/hexels/)
- [Hocus Focus](http://hocusfoc.us/)
- [Homebrew](https://brew.sh)
- [Homebridge](https://github.com/nfarina/homebridge)
- [Houdini](http://uglyapps.co.uk/houdini/)
- [Hstr](https://github.com/dvorka/hstr)
- [HTML Tidy](https://www.html-tidy.org/)
- [Htop](http://htop.sourceforge.net/)
- [HTTPie](https://httpie.org/)
- [hub](https://hub.github.com)
- [Hyper.app](https://hyper.is/)
- [HyperDock](https://bahoom.com/hyperdock)
- [HyperSwitch](https://bahoom.com/hyperswitch)
- [i2cssh](https://github.com/wouterdebie/i2cssh)
- [i3](https://i3wm.org/)
- [IDA Pro](https://www.hex-rays.com/products/ida/)
- [IdeaVim](https://github.com/JetBrains/ideavim)
- [IINA](https://iina.io)
- [Inkscape](https://inkscape.org/)
- [Insomnia](https://insomnia.rest/)
- [IntelliJIDEA](http://www.jetbrains.com/idea/)
- [IPython](http://ipython.org/)
- [Irssi](http://www.irssi.org/)
- [iStat Menus](https://bjango.com/mac/istatmenus/)
- [iTerm2](https://www.iterm2.com/)
- [iTermocil](https://github.com/TomAnthony/itermocil)
- [Itsycal](https://github.com/sfsam/Itsycal)
- [iTunes Scripts](https://www.apple.com/)
- [JankyBorders](https://github.com/FelixKratz/JankyBorders)
- [Janus](https://github.com/carlhuda/janus)
- [Jitouch](http://www.jitouch.com/)
- [Joplin](https://joplinapp.org/)
- [jrnl](https://jrnl.sh)
- [JS Beautifier](https://github.com/beautify-web/js-beautify)
- [JSHint](http://jshint.com/)
- [Julia](http://julialang.org)
- [Jumpcut](http://jumpcut.sourceforge.net/)
- [Jupyter](http://jupyter.org/)
- [k9s](https://k9scli.io/)
- [Kaggle](https://kaggle.com/)
- [Kaleidoscope](http://www.kaleidoscopeapp.com/)
- [Karabiner Elements](https://github.com/tekezo/Karabiner-Elements)
- [Karabiner](https://pqrs.org/osx/karabiner/)
- [Kdenlive](https://kdenlive.org/)
- [KeePassX](http://www.keepassx.org/)
- [KeePassXC](https://keepassxc.org/)
- [KeepingYouAwake](https://github.com/newmarcel/KeepingYouAwake)
- [Keka](http://www.kekaosx.com/en/)
- [Keybase](https://keybase.io/)
- [Keyboard Maestro](http://www.keyboardmaestro.com)
- [Keymo](http://manytricks.com/keymo/)
- [KeyRemap4MacBook](https://pqrs.org/osx/karabiner/)
- [Khd](https://github.com/koekeishiya/khd/)
- [Kiro](https://kiro.dev/)
- [kitty](https://sw.kovidgoyal.net/kitty/)
- [Krew](https://github.com/kubernetes-sigs/krew)
- [Kubectl](https://kubernetes.io/docs/reference/kubectl/overview/)
- [Kwm](https://koekeishiya.github.io/kwm/)
- [LaTeXiT](http://www.chachatelier.fr/latexit/latexit-home.php?lang=en)
- [LaunchBar](https://www.obdev.at/products/launchbar/index.html)
- [lazydocker](https://github.com/jesseduffield/lazydocker)
- [lazygit](https://github.com/jesseduffield/lazygit)
- [Ledger](http://ledger-cli.org)
- [Leiningen](http://leiningen.org/)
- [lf](https://github.com/gokcehan/lf)
- [LibreOffice](https://www.libreoffice.org/)
- [Liftoff](https://github.com/thoughtbot/liftoff)
- [Light Table](http://lighttable.com/)
- [LightPaper](https://getlightpaper.com/)
- [LimeChat](http://limechat.net/mac/)
- [Liquid Prompt](https://github.com/nojhan/liquidprompt)
- [LittleSnitch](http://www.obdev.at/products/littlesnitch/)
- [Livestreamer](http://livestreamer.tanuki.se/)
- [Logitech Options](https://www.logitech.com/en-us/product/options)
- [Logseq](https://logseq.com/)
- [Lollypop](https://gnumdk.github.io/lollypop-web/)
- [Loopback](https://rogueamoeba.com/loopback/)
- [Luftrausers](http://luftrausers.com)
- [LunarVim](https://www.lunarvim.org/)
- [MacDive](http://www.mac-dive.com/)
- [MacDown](http://macdown.uranusjr.com/)
- [MacOSX](http://www.apple.com/osx/)
- [MacVim](https://github.com/macvim-dev/macvim)
- [Magic Launch](https://www.oneperiodic.com/products/magiclaunch/)
- [MagicPrefs](http://magicprefs.com/)
- [Magnet](https://magnet.crowdcafe.com/)
- [Maid](https://github.com/benjaminoakes/maid/)
- [Mail](https://support.apple.com/guide/mail/welcome/mac)
- [Mailmate](http://freron.com/)
- [Mailplane](http://mailplaneapp.com/)
- [mako](https://wayland.emersion.fr/mako/)
- [Marked 2](http://marked2app.com)
- [Marta](https://marta.yanex.org/)
- [MATLAB](http://www.mathworks.com/products/matlab/)
- [Maven](http://maven.apache.org)
- [Max](http://sbooth.org/Max/)
- [Mendeley Desktop](https://www.mendeley.com)
- [MenuMeters](http://www.ragingmenace.com/software/menumeters/)
- [Mercurial](https://www.mercurial-scm.org/)
- [MercuryMover](http://www.heliumfoot.com/mercurymover/)
- [Messages](http://www.apple.com/osx/apps/#messages)
- [Micro](https://github.com/zyedidia/micro)
- [Microsoft Azure CLI](https://github.com/Azure/azure-xplat-cli)
- [Microsoft Remote Desktop](https://itunes.apple.com/us/app/microsoft-remote-desktop-10/id1295203466)
- [mise-en-place](https://github.com/jdx/mise)
- [mitmproxy](https://mitmproxy.org/)
- [mkcert](https://github.com/FiloSottile/mkcert)
- [Mole](https://github.com/tw93/Mole)
- [MonoDevelop](http://www.monodevelop.com)
- [Moom](http://manytricks.com/moom/)
- [Mosaic](https://lightpillar.com/mosaic.html)
- [Mou](http://25.io/mou/)
- [mpd](http://www.musicpd.org)
- [MPlayerX](http://mplayerx.org)
- [MPS Youtube](https://github.com/mps-youtube/mps-youtube)
- [MPV](https://mpv.io/)
- [MTMR](https://github.com/Toxblh/MTMR)
- [Multitouch](https://multitouch.app/)
- [Mumu](https://getmumu.com)
- [MusicBrainz Picard](https://picard.musicbrainz.org/)
- [MuteSpotifyAds](https://github.com/simonmeusel/MuteSpotifyAds)
- [mycli](https://www.mycli.net/)
- [myrepos](https://github.com/joeyh/myrepos)
- [MySQL Workbench](https://www.mysql.com/products/workbench/)
- [MySQL](http://www.mysql.com/)
- [Name Mangler](http://manytricks.com/namemangler/)
- [Nano](http://www.nano-editor.org/)
- [Navicat](http://navicat.com/)
- [ncmpcpp](http://rybczak.net/ncmpcpp/)
- [Neofetch](https://github.com/dylanaraps/neofetch)
- [neovim](https://github.com/neovim/neovim)
- [Nethack](http://www.nethack.org)
- [Netlify](https://www.netlify.com/)
- [newsbeuter](http://newsbeuter.org/)
- [ngrok](https://ngrok.com/)
- [ni](https://github.com/antfu/ni/)
- [Nomacs](http://nomacs.org/)
- [NoSQLBooster for MongoDB](https://www.nosqlbooster.com/)
- [notion-enhancer](https://notion-enhancer.github.io/)
- [Nova](https://www.nova.app/)
- [npm](https://www.npmjs.com/)
- [npmrc](https://github.com/deoxxa/npmrc/)
- [NSLogger](https://github.com/fpillet/NSLogger)
- [nuget](https://www.nuget.org/)
- [Nushell](https://www.nushell.sh/)
- [nvALT](http://brettterpstra.com/projects/nvalt/)
- [nvm](https://github.com/nvm-sh/nvm)
- [nvpy](https://github.com/cpbotha/nvpy)
- [OBS](https://obsproject.com)
- [OfflineIMAP](https://www.offlineimap.org/)
- [Oh My Fish](https://github.com/bpinto/oh-my-fish)
- [Oh My Tmux](https://github.com/gpakosz/.tmux)
- [okta-awscli](https://github.com/okta-awscli/okta-awscli)
- [OmniFocus](https://www.omnigroup.com/omnifocus/)
- [OmniGraffle](https://www.omnigroup.com/omnigraffle/)
- [Openbox](http://openbox.org)
- [OpenCode](https://opencode.ai)
- [OpenEmu](http://openemu.org)
- [OpenSSH](http://www.openssh.com/)
- [Opera](http://www.opera.com)
- [Oracle Cloud Infrastructure CLI](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/cliconcepts.htm)
- [Paintbrush](http://paintbrush.sourceforge.net/)
- [Pandoc](http://pandoc.org)
- [Pass](http://www.passwordstore.org/)
- [Pastebot](http://tapbots.com/software/pastebot/)
- [Path Finder](http://www.cocoatech.com/pathfinder/)
- [PDFjam](https://warwick.ac.uk/fac/sci/statistics/staff/academic-research/firth/software/pdfjam/)
- [Pear](http://pear.php.net/)
- [Pentadactyl](http://5digits.org/pentadactyl/)
- [Perl](https://www.perl.org/)
- [Phoenix](https://github.com/kasper/phoenix)
- [PhoneView](https://www.ecamm.com/mac/phoneview/)
- [PhpStorm](http://www.jetbrains.com/phpstorm/)
- [PicGo](https://github.com/Molunerfinn/PicGo)
- [Pidgin](https://www.pidgin.im)
- [PIP](http://www.pip-installer.org/)
- [PixelSnap 2](https://getpixelsnap.com/)
- [PixelSnap](https://getpixelsnap.com/)
- [Planner](https://useplanner.com/)
- [Plover](http://www.openstenoproject.org/plover/)
- [Pnpm](https://pnpm.js.org/)
- [Pock](https://pock.pigigaldi.com)
- [Podman](https://podman.io/)
- [Poedit](http://poedit.net/)
- [Poetry](https://python-poetry.org)
- [PokerStars](https://www.pokerstars.com/)
- [Polybar](https://polybar.github.io/)
- [PopClip](http://pilotmoon.com/popclip/)
- [Popcorn-Time](https://popcorntime.io/)
- [PostgreSQL](http://www.postgresql.org/)
- [Postico](https://eggerapps.at/postico/)
- [Pow](http://pow.cx/)
- [Powerlevel10k](https://github.com/romkatv/powerlevel10k)
- [Powerline-shell](https://github.com/b-ryan/powerline-shell)
- [Powerline](https://github.com/powerline/powerline)
- [Prezto](https://github.com/sorin-ionescu/prezto)
- [Processing](https://processing.org/)
- [Proselint](https://github.com/amperser/proselint)
- [ProxyChains NG](http://sourceforge.net/projects/proxychains-ng/)
- [ProxyChains](http://proxychains.sourceforge.net)
- [Proxyman](https://proxyman.io)
- [PrusaSlicer](https://www.prusa3d.com/prusaslicer/)
- [PsySH](https://psysh.org/)
- [Punto Switcher](https://punto.yandex.ru/)
- [PyCharm](https://www.jetbrains.com/pycharm/)
- [PyPI](https://pypi.python.org/pypi)
- [PyRadio](http://www.coderholic.com/pyradio/)
- [Querious](http://www.araelium.com/querious/)
- [Quicksilver](http://qsapp.com/)
- [Quitter](https://marco.org/apps)
- [Qutebrowser](http://qutebrowser.org/)
- [Qv2ray](https://qv2ray.net/)
- [R](http://www.r-project.org/)
- [Rails](http://rubyonrails.org/)
- [Ranger](https://ranger.github.io/)
- [Rbenv](https://www.github.com/rbenv/rbenv)
- [Rclone](https://rclone.org/)
- [Rectangle](https://rectangleapp.com/)
- [Redshift Scheduler](https://github.com/spantaleev/redshift-scheduler)
- [Redshift](http://jonls.dk/redshift/)
- [Remote Desktop Manager](https://remotedesktopmanager.com/)
- [Rhythmbox](https://wiki.gnome.org/Apps/Rhythmbox)
- [Rime](http://rime.im/)
- [ripgrep](https://github.com/BurntSushi/ripgrep)
- [Robo 3T](http://robomongo.org/)
- [Rocket](https://matthewpalmer.net/rocket/)
- [Rofi](https://github.com/DaveDavenport/rofi)
- [Royal TSX](http://www.royaltsx.com/ts/osx/features)
- [RStudio](https://www.rstudio.com/)
- [rTorrent](http://libtorrent.rakshasa.no/)
- [rtx](https://github.com/jdx/rtx)
- [rubiTrack 5](https://www.rubitrack.com)
- [Rubocop](https://github.com/bbatsov/rubocop)
- [Ruby Version Manager](https://rvm.io/)
- [Ruby Version](https://gist.github.com/fnichol/1912050)
- [Ruby](https://www.ruby-lang.org/)
- [RubyMine](http://www.jetbrains.com/ruby/)
- [Rust](https://www.rust-lang.org/)
- [RustRover](https://www.jetbrains.com/rust/)
- [S3cmd](http://s3tools.org/s3cmd)
- [SABnzbd](http://sabnzbd.org/)
- [SBCL](http://www.sbcl.org/)
- [SBT](http://www.scala-sbt.org/)
- [Scenario](http://www.lagentesoft.com/scenario/)
- [Screen](http://www.gnu.org/software/screen/)
- [Screenhero](https://screenhero.com)
- [Scrivener](http://www.literatureandlatte.com/scrivener.php)
- [Scroll Reverser](https://pilotmoon.com/scrollreverser/)
- [Secure Pipes](http://www.opoet.com/)
- [SecureCRT](https://www.vandyke.com/products/securecrt/)
- [Seil](https://pqrs.org/osx/karabiner/seil.html.en)
- [SelfControl](http://selfcontrolapp.com/)
- [Sequel Pro](http://www.sequelpro.com/)
- [ShadowsocksX-NG](https://github.com/shadowsocks/ShadowsocksX-NG)
- [ShiftIt](https://github.com/fikovnik/ShiftIt)
- [Shifty](https://shifty.natethompson.io/)
- [Shimo](https://www.feingeist.io/shimo/)
- [ShowyEdge](https://pqrs.org/osx/ShowyEdge/index.html.en)
- [SHSH Blobs](https://en.wikipedia.org/wiki/SHSH_blob)
- [Shuttle](http://fitztrev.github.io/shuttle/)
- [SizeUp](http://www.irradiatedsoftware.com/sizeup/)
- [Sizzy](https://sizzy.co/)
- [SketchyBar](https://felixkratz.github.io/SketchyBar/)
- [skhd](https://github.com/koekeishiya/skhd/)
- [Skim](http://skim-app.sourceforge.net/)
- [Skitch](https://evernote.com/skitch/)
- [Slate](https://github.com/jigish/slate)
- [Slic3r](http://slic3r.org)
- [Slogger](http://brettterpstra.com/projects/slogger/)
- [SmartGit](http://www.syntevo.com/smartgit/)
- [Smooth Mouse](http://smoothmouse.com/)
- [Soulver](http://www.acqualia.com/soulver/)
- [SourceTree](https://www.sourcetreeapp.com/)
- [SpaceLauncher](https://spacelauncherapp.com)
- [Spacemacs](https://github.com/syl20bnr/spacemacs)
- [SpaceVim](https://github.com/SpaceVim/SpaceVim)
- [SpamSieve](https://c-command.com/spamsieve)
- [Spark](http://www.shadowlab.org/softwares/spark.php)
- [Spectacle](https://www.spectacleapp.com/)
- [Spectrwm](https://github.com/conformal/spectrwm/wiki)
- [Splice](https://splice.com/)
- [Spotify Notifications](http://spotify-notifications.citruspi.io/)
- [Spotify](https://www.spotify.com/)
- [Sqitch](https://sqitch.org/)
- [Starship](https://starship.rs/)
- [Startupizer2](http://appledoc.gentlebytes.com/startupizer/)
- [Stata](http://www.stata.com/)
- [Stats](https://github.com/exelban/stats)
- [Stay](https://cordlessdog.com/stay/)
- [Storyist](http://storyist.com/)
- [Subler](https://subler.org)
- [Sublime Merge](https://www.sublimemerge.com/)
- [Sublime Text](http://www.sublimetext.com/)
- [Subversion](http://subversion.apache.org/)
- [SuperDuper!](http://www.shirt-pocket.com/SuperDuper/SuperDuperDescription.html)
- [Surge](http://surge.run/manual/)
- [Sway](https://swaywm.org/)
- [Swinsian](http://swinsian.com/)
- [Swish](https://highlyopinionated.co/swish/)
- [SwitchHosts](https://github.com/oldj/SwitchHosts)
- [T](http://sferik.github.io/t/)
- [TablePlus](https://tableplus.io)
- [TaskPaper](https://www.taskpaper.com)
- [Taskwarrior](http://taskwarrior.org/)
- [Teamocil](https://github.com/remi/teamocil)
- [Telegram for macOS](https://macos.telegram.org)
- [Terminal](http://www.apple.com/osx/apps/)
- [Terminator](https://launchpad.net/terminator/)
- [termite](https://github.com/thestinger/termite)
- [Termux](https://termux.dev/)
- [Terraform](https://developer.hashicorp.com/terraform)
- [TextExpander](https://smilesoftware.com/textexpander)
- [TextMate](http://macromates.com/)
- [Textual](http://www.codeux.com/textual/)
- [Things](https://culturedcode.com/things/)
- [Tig](https://github.com/jonas/tig)
- [Tiles](https://www.sempliva.com/tiles/)
- [Tilix](https://github.com/gnunn1/tilix)
- [Timeout](https://www.dejal.com/timeout/)
- [tint2](https://code.google.com/p/tint2/)
- [TinyFugue](http://tinyfugue.sourceforge.net)
- [Tmux](http://tmux.sourceforge.net/)
- [Tmuxinator](https://github.com/tmuxinator/tmuxinator)
- [Tmuxp](https://github.com/tony/tmuxp)
- [Todo.txt CLI](http://todotxt.com/)
- [ToothFairy](https://c-command.com/toothfairy/)
- [TotalSpaces2](http://totalspaces.binaryage.com/)
- [Tower](http://www.git-tower.com/)
- [Transmission](http://www.transmissionbt.com/)
- [Transmit](http://panic.com/transmit/)
- [TripMode](https://www.tripmode.ch)
- [Trizen](https://github.com/trizen/trizen)
- [Tunnelblick](https://tunnelblick.net)
- [tvnamer](https://github.com/dbr/tvnamer)
- [Twitterrific](http://twitterrific.com/)
- [Typinator](http://www.ergonis.com/products/typinator/)
- [Typora](https://typora.io)
- [Übersicht](http://tracesof.net/uebersicht/)
- [ulauncher](https://ulauncher.io/)
- [uTorrent](http://www.utorrent.com/)
- [Ventrilo](http://www.ventrilo.com/)
- [Verdaccio](https://verdaccio.org/)
- [Versions](http://www.versionsapp.com)
- [Vim](http://www.vim.org/)
- [Vimperator](http://www.vimperator.org/vimperator)
- [Vimwiki](https://vimwiki.github.io/)
- [Viscosity](http://www.sparklabs.com/viscosity/)
- [Visual Studio Code - Insiders](https://code.visualstudio.com/insiders)
- [Visual Studio Code - OSS](https://github.com/Microsoft/vscode)
- [Visual Studio Code](https://code.visualstudio.com/)
- [Visual Studio for Mac](https://www.visualstudio.com/vs/visual-studio-mac/)
- [VLC](http://www.videolan.org/)
- [Volt](https://github.com/vim-volt/volt)
- [VSCodium](https://vscodium.com/)
- [Wakatime](https://wakatime.com/)
- [Warp](https://www.warp.dev)
- [waybar](https://github.com/Alexays/Waybar)
- [WebStorm](https://www.jetbrains.com/webstorm/)
- [WezTerm](https://wezfurlong.org/wezterm/)
- [Wget](https://www.gnu.org/software/wget/)
- [WhatsApp Web](https://web.whatsapp.com/)
- [Windsurf](https://www.codeium.com)
- [Wireshark 2](https://www.wireshark.org)
- [Witch](http://manytricks.com/witch/)
- [WordGrinder](https://cowlark.com/wordgrinder/)
- [WordPress WP-CLI](http://wp-cli.org/)
- [Workrave](http://www.workrave.org/)
- [X11](http://www.x.org/)
- [Xamarin Studio](https://xamarin.com/studio)
- [xbar](https://xbarapp.com/)
- [XBindKeys](http://www.nongnu.org/xbindkeys/)
- [Xchat](http://xchat.org/)
- [Xcode](https://developer.apple.com/xcode/)
- [Xee](https://theunarchiver.com/xee)
- [XEmacs](http://www.xemacs.org/)
- [XLD](http://tmkk.undo.jp/xld/)
- [Xonsh](https://xon.sh)
- [XtraFinder](http://www.trankynam.com/xtrafinder/)
- [yabai](https://github.com/koekeishiya/yabai)
- [yarn](https://yarnpkg.com)
- [yazi](https://github.com/sxyazi/yazi)
- [youtube-dl](https://ytdl-org.github.io/youtube-dl/)
- [Yummy FTP](http://www.yummysoftware.com/)
- [zabbix-cli](https://github.com/usit-gd/zabbix-cli)
- [zathura](https://pwmt.org/projects/zathura/)
- [zed](https://zed.dev/)
- [Zoom](http://zoom.com/)
- [zoxide](https://github.com/ajeetdsouza/zoxide)
- [Zsh](http://zsh.sourceforge.net/)

## Can you support application X

We can [with your help](doc#get-official-support-for-an-application) ;)

## Personalization & configuration

Have an application that shouldn't be generally supported but that you use?
Or some personal files you want to sync, e.g. various config files in a `~/.config/`
directory or your personal `~/.gitignore`?

- Create a `~/.mackup` directory to [sync an application or any file or directory](doc#add-support-for-an-application-or-any-file-or-directory)

## Why did you do this

Yesterday, I had a talk with [Zach Zaro](http://zacharyzaro.com/), complaining
about the pain it is to reconfigure our Macbook each time we get a new one or
install from scratch. That's a talk we have already had months ago.

I change my workstation every X months. Each time I either lose my apps'
configurations, or I just waste a bunch of hours getting setup like I was on my
old box. I also spend a lot of time reconfiguring the same stuff again on all my
workstations (home, work).

Boring...

Some people tried to solve the problem on the application layer, like
[Github's Boxen](https://boxen.github.com/),
but it solves a different problem, from my point of view. I don't spend a lot
of time installing or downloading stuff. I spend time configuring it.

For years, I've used a personal shell script that was copying known config
files into Subversion, Git or Dropbox, and linked them into my home. But I felt
a lot of us had the same problem: Making a more generic tool could help others
and I could get help from others to support more apps in the tool.

So here comes Mackup, the little tool that will sync all your application
configs to Dropbox (or Google Drive, or anything).

And it's [GPL](http://www.gnu.org/licenses/gpl.html), of course.

## What platforms are supported

- macOS
- GNU/Linux

## What's up with the weird name

Mackup is just a portmanteau of Mac and Backup. It is simple, short, and easy to
remember, and it corresponds with the whole idea of Mackup: the simpler – the better!
(And I suck at naming stuff, but who doesn't.)

## Architecture

Want to understand how Mackup works internally? Check out the
[Architecture Guide](doc/ARCHITECTURE.md) which includes:

- Visual architecture diagram
- Component breakdown
- Data flow diagrams
- Design decisions
- Extension points for contributors

Perfect for contributors who want to understand the codebase or users
curious about how their configs are managed.

## Where can I find more information

In the [doc](doc) directory.

---

## File: doc/configuration_merge_guide.md

# Guide for Merging Configurations Across Machines

This guide is for users who want to combine configuration settings for two or
more machines.

For example, you might have some bash settings on Machine A (like useful
command aliases) that are not on Machine B. You also have some settings on
Machine B that you would like to move over to Machine A.

The problem is that if you use Mackup to send Machine A's bash configuration
settings to Machine B, you will permanently lose any configurations on Machine
B that you wanted to keep. Mackup obviously has no idea which features you want
to keep and which ones you don't, so you'll have to do a bit of work to merge
the different configuration files yourself before using Mackup.

## Step 0: Read Through This Entire Guide First

It will probably save you some pain in the long run.

## Step 1: Determine Which Configuration Files to Merge

First, pick the app you wish to keep in sync. Then determine which
configuration files will be synced for that application by doing the following:

1. [Install Mackup](./../INSTALL.md)
2. Create a `.mackup.cfg` file in your home directory
3. Add the following two lines to `.mackup.cfg`. Replace **bash**
   in the example below with the name of your application.

```text
[applications_to_sync]
bash
```

You can get a list of supported apps by running `mackup list`.

1. Save the file
2. Run the following command:

`mackup --dry-run --verbose backup`

This command will let you see what mackup will do behind the scenes when it
backs up your application's configuration files so you can readily see what
configuration files Mackup will sync. Make note of these files.

## Step 2: Prepare Your Workstations for Syncing

Now that you've identified which files you have to merge, choose one of the two
approaches below for merging the configuration files. **Method 1** has you do all
the configuration file merges first and then pushes them out with Mackup.
With **Method 2**, you'll push out the configuration files from one machine to the
others and then merge in your configuration changes gradually over time.

Which method should you use? It doesn't really matter. Method 1 is more work up
front in exchange for less work later. Method 2 is less work up front but more
work later.

Method 1 is probably best if you have very dissimilar configurations and have
few machines. Method 2 is probably best if you have a machine that is very
close to working the way you want and just need a few configuration settings
from other machines.

### Method 1: Backup Merge-Push Approach

1. Create a backup of each machine's configuration files for the app you wish
   to sync.
2. Choose a machine that will serve as the initial "master". It doesn't really
   matter which one.
3. Edit your configuration files on the master machine so that they
   represent the ideal version of the file you wish to distribute out to your
   other machines.

#### Method 1 Example

Let's say we have two machines, A and B, and we want to sync our bash configuration
across the machines. We decide that Machine A will serve as our master.

First, backup the bash configuration files (there are a few of them)
for your application on all machines.

##### Method 1: Sample backup commands for Machine A

```bash
mkdir ~/bash_backup
cp ~/.bash_profile ~/bash_backup/bash_profile.bak
cp ~/.bash_login ~/bash_backup/bash_login.bak

...plus any other bash config files you want to keep
```

##### Method 1: Sample backup commands for Machine B

```bash
mkdir ~/bash_backup
cp ~/.bash_profile ~/bash_backup/bash_profile.bak
cp ~/.bash_login ~/bash_backup/bash_login.bak

...plus any other bash config files you want to keep
```

Machine A will be our master so we now edit the existing configuration files
on Machine A. We will use the vim text editor to do this for each of our
configuration files:

```bash
vim .bash_profile
vim .bash_login
```

When editing these configuration files on Machine A, copy and paste the settings
from Machine B that you want to keep. In essence, you are manually merging the
configuration files together. Once you are satisfied the configuration files
have all the settings you want and need, you are ready to push out your changes
from the master machine.

### Method 2: Backup Push-Merge Approach

1. Choose a machine that will serve as the initial "master". You'll probably
   want to choose the machine you use most and like its configuration
   settings the best.
2. For each machine that isn't the "master" (i.e. "slaves"), back up all the
   configuration files for each app that you want to sync. That's it for now.
   However, there will be more work for you later.

#### Method 2 Example

Let's say we have two machines, A and B, and we want to sync our bash configuration
across the machines. We decide that Machine A will serve as our master.

Since A is our master, we only need to backup the bash configuration files on
Machine B:

##### Method 2: Sample backup commands for Machine B

```bash
mkdir ~/bash_backup
cp ~/.bash_profile ~/bash_backup/bash_profile.bak
cp ~/.bash_login ~/bash_backup/bash_login.bak

...plus any other bash config files you want to keep
```

If you have other machines you are syncing with the master, back those up, too.

## Step 3: Push Out the Configuration Files with Mackup

Now you are ready to use Mackup to push out the changes. You should have Mackup
already installed and the `.mackup.cfg` file in place according to the
instructions provided above. If not, do that before proceeding.

Run the following command on the master machine:

`mackup backup`

On each of the other "slave" machines, run:

`mackup restore`

If you used Method 1 in Step 2 above, you are done. You may discover
that you didn't quite merge the files exactly the way you wanted but don't
worry, that's why you created the configuration file backups. You can grab
snippets from these backup configuration files and add them in to the live
configuration files and then easily push the changes out to all your
machines using mackup.

If you used Method 2, you'll need to merge in new features over time. As you
discover features you need to add, you'll need to take the appropriate snippets
of configuration code from the backup configuration files you created and
insert them into the appropriate configuration file. Remember it does not matter
which machine's configuration file you update as these configuration files are
now shared across all machines.

---

## File: doc/develop.md

# Develop

```sh
# Install the tool for dependency management and packaging in Python
pipx install uv

# You can now edit files and see the impact of your changes
uv run mackup --version
make test
```

## Running Tests with Coverage

To run tests with coverage reporting:

```sh
# Run tests with coverage
make coverage

# View coverage report in terminal
make coverage-report

# Open HTML coverage report
open htmlcov/index.html
```

## Code Quality Checks

The project includes several code quality tools:

```sh
# Run all checks (ruff, mypy, pytest)
make check

# Run individual checks
make ruff      # Code linting
make mypy      # Type checking
make test      # Unit tests
make coverage  # Tests with coverage
```

## Coverage Configuration

Coverage is configured in `pyproject.toml` with:

- Branch coverage enabled
- Test files excluded from coverage
- HTML and XML reports generated
- 67%+ coverage currently achieved

You can view detailed coverage reports by running `make coverage` and opening
`htmlcov/index.html` in your browser.

---

## File: doc/README.md

# Configuration

> 💡 **New to Mackup?** Check out the
> [Architecture Guide](ARCHITECTURE.md) to understand how Mackup works
> under the hood.

All the configuration is done in a file named `.mackup.cfg` stored at the
root of your home folder. This location can be overridden via environment
variables or the `--config-file` command-line option.

To configure Mackup, create a file named `.mackup.cfg` in your home
directory.

```bash
vi ~/.mackup.cfg
```

## Configuration file location

Config files are searched in the following order. If none is found, Mackup will
use the default config location of `~/.mackup.cfg`

- `~/.mackup.cfg`
- `$MACKUP_CONFIG`
- `$XDG_CONFIG_HOME/mackup/mackup.cfg` or `~/.config/mackup/mackup.cfg`

You can also specify a custom config file location using the `--config-file`
command-line option:

```bash
mackup --config-file ~/.mackup-custom.cfg backup
```

The path can be absolute or relative to your home directory. Note that the
config file must be located within your home directory for security reasons.

## Storage

You can specify the storage type Mackup will use to store your configuration
files.

For now, you have 4 options: `dropbox`, `google_drive`, `icloud` and `file_system`.

If none is specified, Mackup will try to use the default: `dropbox`.
With the `dropbox` storage engine, Mackup will automatically figure out your
Dropbox folder.

### Dropbox

```ini
[storage]
engine = dropbox
```

### Google Drive

If you choose the `google_drive` storage engine instead, Mackup will figure out
where your Google Drive is and store your configuration files in it.

```ini
[storage]
engine = google_drive
```

### iCloud

If you choose the `iCloud` storage engine, Mackup will store your
configuration files in the `~/Library/Mobile\ Documents/com\~apple\~CloudDocs/`
folder.

```ini
[storage]
engine = icloud
```

You can check if your files are synced using:

```sh
brctl monitor com.apple.CloudDocs
```

### File System

If you want to specify another directory, you can use the `file_system` engine
and Mackup won't try to detect any path for you: it will store your files where
you explicitly told it to, using the `path` setting.
The `path` can be absolute (from the `/` of your drive) or relative to your
home directory.
The `path` setting is mandatory when using the `file_system` engine.

```ini
[storage]
engine = file_system
path = some/folder/in/your/home
# or path = /some/folder/in/your/root
```

Note: you don't need to escape spaces or wrap the path in quotes.
For example, the following paths are valid:

```ini
path = some/path in your/home
path = /some path/in/your/root
```

### Custom Directory Name

You can customize the directory name in which Mackup stores your files. By
default, if not specified, Mackup creates a `Mackup` directory in the storage
engine you chose, e.g. `~/Dropbox/Mackup`.

```ini
[storage]
directory = Mackup
```

For example:

```ini
[storage]
engine = file_system
path = dotfiles
directory = backup
```

This will store your files in the `~/dotfiles/backup` directory in your home.

You can also select a subfolder:

```ini
[storage]
engine = icloud
directory = .config/mackup
```

### Switching Storage

If you ever change your mind and switch storage solutions after Mackup is
already setup (ex: from `dropbox` to `icloud`), complete the following steps.

1. Run `mackup uninstall` on all computers
2. Copy your Mackup files to the new storage location
3. Change the storage provider details in your `.mackup.cfg` file (see above)
4. Run `mackup backup` on the main computer and `mackup restore` on all others

## Applications

### Only sync one or two applications

In your home folder, create a file named `.mackup.cfg` and add the application
names to allow in the `[applications_to_sync]` section, one per line.

```ini
# Example, to only sync SSH and Adium:
[applications_to_sync]
ssh
adium
```

Use `mackup list` to get a list of valid application names. Don't use fancy
names (with spaces) here.

A [sample](.mackup.cfg) of this file is available in this folder. Just copy it
to your home folder:

```bash
cp mackup/doc/.mackup.cfg ~/
```

### Don't sync an application

In your home folder, create a file named `.mackup.cfg` and add the application
names to ignore in the `[applications_to_ignore]` section, one per line.

```ini
# Example, to not sync SSH and Adium:
[applications_to_ignore]
ssh
adium
```

Use `mackup list` to get a list of valid application names. Don't use fancy
names (with spaces) here.

A [sample](.mackup.cfg) of this file is available in this folder. Just copy it
to your home folder:

```bash
cp mackup/doc/.mackup.cfg ~/
```

### Get official support for an application

Open a [new issue](https://github.com/lra/mackup/issues) and ask for it, or
fork Mackup and open a
[Pull Request](https://help.github.com/articles/using-pull-requests).
The stock application configs are in the `mackup/applications` directory.

Remember to follow the guidelines in [CONTRIBUTING.md](https://github.com/lra/mackup/blob/master/.github/CONTRIBUTING.md)
to get your Pull Request merged faster.

### Add support for an application or (almost) any file or directory

You can customize the Mackup engine and add support for unsupported
applications or just custom files and directories you'd like to sync.

NOTE: Files and directories to be synced should be rooted at $HOME.

Let's say that you'd like to add support for Nethack (config file:
`.nethackrc`), for the `bin` and `.hidden` directories and for the
`.gitignore` file you keep in your home.

In your home, create a `.mackup` directory and add a config file for the
application you'd like to support:

```bash
mkdir ~/.mackup
touch ~/.mackup/nethack.cfg
touch ~/.mackup/my-files.cfg
```

#### Custom applications directory location

Custom application configs are searched in the following order:

1. `~/.mackup/` (legacy location, takes priority)
2. `$XDG_CONFIG_HOME/mackup/applications/` or `~/.config/mackup/applications/`

If the same application config exists in both locations, the legacy location
(`~/.mackup/`) takes priority.

For XDG-compliant setups, you can use:

```bash
mkdir -p ~/.config/mackup/applications
touch ~/.config/mackup/applications/nethack.cfg
```

Edit those files:

```bash
$ nano ~/.mackup/nethack.cfg
[application]
name = Nethack

[configuration_files]
.nethackrc
```

```bash
$ nano ~/.mackup/my-files.cfg
[application]
name = My personal synced files and dirs

[configuration_files]
bin
.hidden
.gitignore
```

Note that Mackup assumes the file paths listed here are relative to your home
directory.

You can run mackup to see if they are listed:

```bash
$ mackup list
Supported applications:
[...]
 - my-files
 - nethack
[...]
```

All good, you can now sync your newly configured files:

```bash
mackup backup
```

If you override an application config that is already supported by Mackup, your
new config for this application will replace the one provided by Mackup.

You can find some sample configs in this directory.

### Locally test an application before submitting a Pull Request

You can add and test an application by following these steps:

- fork this project
- create a branch _(usually containing the name of the application)_
- add the appropriate application config file in the `mackup/applications` folder
- from the top-most folder _(mackup)_ run `make develop` that replaces the
  currently installed mackup with the local modified one
- simply run `mackup backup` to test if everything is ok
- if everything works as expected:
  - run `make undevelop` to revert to the official version
  - commit and push the change to your fork and then create the Pulls Request

### Add support for an application using the XDG directory

For applications storing their configuration under the `~/.config` folder, you
should not hardcode it. The `.config` folder is the default location but it can
be named differently on other users' systems by setting the `XDG_CONFIG_HOME`
environment variable.

See <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html>

Mackup supports this mechanism and provides a dedicated `xdg_configuration_files`
section for those applications.

If any path starts with `.config`, remove the `.config` part and move the path
to a dedicated `xdg_configuration_files` section.

Instead of:

```ini
[application]
name = Git

[configuration_files]
.gitconfig
.config/git/config
.config/git/ignore
.config/git/attributes
```

Use this:

```ini
[application]
name = Git

[configuration_files]
.gitconfig

[xdg_configuration_files]
git/config
git/ignore
git/attributes
```

---

## File: doc/release.md

# Release

Releasing is now automated. Pushing a version tag triggers the
[`release` workflow](../.github/workflows/release.yaml), which builds the
package, publishes it to PyPI, and creates the GitHub release.

To cut a release, run one command. The version is `X.Y.Z`
(`major.minor.patch`), and the `BUMP` you choose increments one number and
resets the numbers to its right to `0`:

```sh
make release              # patch: 0.10.3 -> 0.10.4 (bug fixes)
make release BUMP=minor   # minor: 0.10.3 -> 0.11.0 (new features)
make release BUMP=major   # major: 0.10.3 -> 1.0.0  (breaking changes)
make release VERSION=1.2.3  # pin an exact version, no arithmetic
```

Preview a bump without changing anything with `uv version --bump <level>
--dry-run`.

This runs the checks, bumps the version, syncs the lockfile, then commits, tags
and pushes. The workflow takes over from the tag push:

- Builds the package with `uv build`
- Publishes it to PyPI with `uv publish`
- Creates the GitHub release with auto-generated notes and the built artifacts