# Include dotfiles from elsewhere

## Include a subdirectory from a URL

To include a subdirectory from another repository, e.g. [Oh My
Zsh](https://github.com/ohmyzsh/ohmyzsh), you cannot use git submodules because
chezmoi uses its own format for the source state and Oh My Zsh is not
distributed in this format. Instead, you can use the
`.chezmoiexternal.<format>` to tell chezmoi to import dotfiles from an external
source.

For example, to import Oh My Zsh, the [zsh-syntax-highlighting
plugin](https://github.com/zsh-users/zsh-syntax-highlighting), and
[powerlevel10k](https://github.com/romkatv/powerlevel10k), put the following in
`~/.local/share/chezmoi/.chezmoiexternal.toml`:

```toml title="~/.local/share/chezmoi/.chezmoiexternal.toml"
[".oh-my-zsh"]
    type = "archive"
    url = "https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz"
    exact = true
    stripComponents = 1
    refreshPeriod = "168h"
[".oh-my-zsh/custom/plugins/zsh-syntax-highlighting"]
    type = "archive"
    url = "https://github.com/zsh-users/zsh-syntax-highlighting/archive/master.tar.gz"
    exact = true
    stripComponents = 1
    refreshPeriod = "168h"
[".oh-my-zsh/custom/themes/powerlevel10k"]
    type = "archive"
    url = "https://github.com/romkatv/powerlevel10k/archive/v1.15.0.tar.gz"
    exact = true
    stripComponents = 1
```

To apply the changes, run:

```console
$ chezmoi apply
```

chezmoi will download the archives and unpack them as if they were part of the
source state. chezmoi caches downloaded archives locally to avoid
re-downloading them every time you run a chezmoi command, and will only
re-download them at most every `refreshPeriod` (default never).

In the above example `refreshPeriod` is set to `168h` (one week) for
`.oh-my-zsh` and `.oh-my-zsh/custom/plugins/zsh-syntax-highlighting` because
the URL point to tarballs of the `master` branch, which changes over time. No
refresh period is set for `.oh-my-zsh/custom/themes/powerlevel10k` because the
URL points to the a tarball of a tagged version, which does not change over
time. To bump the version of powerlevel10k, change the version in the URL.

To force a refresh the downloaded archives, use the `--refresh-externals` flag
to `chezmoi apply`:

```console
$ chezmoi --refresh-externals apply
```

`--refresh-externals` can be shortened to `-R`:

```console
$ chezmoi -R apply
```

When using Oh My Zsh, make sure you disable auto-updates by setting
`DISABLE_AUTO_UPDATE="true"` in `~/.zshrc`. Auto updates will cause the
`~/.oh-my-zsh` directory to drift out of sync with chezmoi's source state. To
update Oh My Zsh and its plugins, refresh the downloaded archives.

## Include a single file from a URL

Including single files uses the same mechanism as including a subdirectory
above, except with the external type `file` instead of `archive`. For example,
to include
[`plug.vim`](https://github.com/junegunn/vim-plug/blob/master/plug.vim) from
[`github.com/junegunn/vim-plug`](https://github.com/junegunn/vim-plug) in
`~/.vim/autoload/plug.vim` put the following in
`~/.local/share/chezmoi/.chezmoiexternal.toml`:

```toml title="~/.local/share/chezmoi/.chezmoiexternal.toml"
[".vim/autoload/plug.vim"]
    type = "file"
    url = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
    refreshPeriod = "168h"
```

## Include a subdirectory from a git repository

You can configure chezmoi to keep a git repository up to date in a subdirectory
by using the external type `git-repo`, for example:

```toml title="~/.local/share/chezmoi/.chezmoiexternal.toml"
[".vim/pack/alker0/chezmoi.vim"]
    type = "git-repo"
    url = "https://github.com/alker0/chezmoi.vim.git"
    refreshPeriod = "168h"
```

If the directory does not exist then chezmoi will run `git clone` to clone it.
If the directory does exist then chezmoi will run `git pull` to pull the latest
changes, but not more often than every `refreshPeriod`. In the above example
the `refreshPeriod` is `168h` which is one week. The default `refreshPeriod` is
zero, which disables refreshes. You can force a refresh (i.e. force a `git
pull`) by passing the `--refresh-externals`/`-R` flag to `chezmoi apply`.

You can customize the arguments to `git clone` and `git pull` by setting the
`<dir>.clone.args` and `<dir>.pull.args` variables in
`.chezmoiexternal.<format>`, for example:

```toml title="~/.local/share/chezmoi/.chezmoiexternal.toml"
[".vim/pack/alker0/chezmoi.vim"]
    type = "git-repo"
    url = "https://github.com/alker0/chezmoi.vim.git"
    refreshPeriod = "168h"
    [".vim/pack/alker0/chezmoi.vim".pull]
        args = ["--ff-only"]
```

!!! note

    chezmoi's support for `git-repo` externals is limited to running `git
    clone` and/or `git pull` in a directory. The contents of `git-repo`
    externals are not manifested in commands like `chezmoi archive` or `chezmoi
    dump`.

!!! note

    chezmoi's support for `git-repo` externals currently requires `git` to be
    in your `$PATH`.

## Extract a single file from an archive

You can extract a single file from an archive using the
`<entry>.filter.command` and `<entry>.filter.args` variables in
`.chezmoiexternal.<format>`, for example:

```toml title="~/.local/share/chezmoi/.chezmoiexternal.toml"
{{ ageVersion := "1.0.0" -}}
[".local/bin/age"]
    type = "file"
    url = "https://github.com/FiloSottile/age/releases/download/v{{ $ageVersion }}/age-v{{ $ageVersion }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz"
    executable = true
    refreshPeriod = "168h"
    [".local/bin/age".filter]
        command = "tar"
        args = ["--extract", "--file", "/dev/stdin", "--gzip", "--to-stdout", "age/age"]
```

This will extract the single archive member `age/age` from the given URL (which
is computed for the current OS and architecture) to the target
`./local/bin/age` and set its executable bit.

## Import archives

It is occasionally useful to import entire archives of configuration into your
source state. The `import` command does this. For example, to import the latest
version [`github.com/ohmyzsh/ohmyzsh`](https://github.com/ohmyzsh/ohmyzsh) to
`~/.oh-my-zsh` run:

```console
$ curl -s -L -o ${TMPDIR}/oh-my-zsh-master.tar.gz https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz
$ mkdir -p $(chezmoi source-path)/dot_oh-my-zsh
$ chezmoi import --strip-components 1 --destination ~/.oh-my-zsh ${TMPDIR}/oh-my-zsh-master.tar.gz
```

!!! note

    This only updates the source state. You will need to run:

    ```console
    $ chezmoi apply
    ```

    to update your destination directory.
