CLI Documentation

Install

Dotfile should work on most unix systems. Golang is required to build Dotfile.

Install with Go

go install github.com/knoebber/dotfile/cmd/dotfile@latest

Install with make

git clone https://github.com/knoebber/dotfile
cd dotfile
make dotfile
# copy bin/dotfile to somewhere in $PATH.

Shell Completion

Add the following to your ~/.bashrc or equivalent:

eval "$(dotfile --completion-script-bash)"

Or

eval "$(dotfile --completion-script-zsh)"

Overview

The Dotfile CLI is a version control system for single files. When a file is checked in an alias is created. The alias is mapped to the path. This allows for quick access regardless of the working directory. For example, the following command prints the content in ~/.bashrc:

dotfile show bashrc

Use dotfile --help to learn more.

Data Storage

Dotfile stores tracking data in ~/.local/share/dotfile. If its parent directory does not exist it will fallback to ~/.dotfile. The storage directory can be changed with the --storage-dir flag. For every tracked file there is a .json file and a directory for its commits.

Example: ~/.local/share/dotfile/bashrc.json

{
  "path": "~/.bashrc",
  "revision": "599a1af0398b7c518bc46aaa4a9e8ae72c2d28cb",
  "commits": [
    {
      "hash": "d47481afa38dcab0d8c8d163aa75e0cf5af6e355",
      "message": "Initial commit",
      "timestamp": 1590956605
    },
    {
      "hash": "599a1af0398b7c518bc46aaa4a9e8ae72c2d28cb",
      "message": "Add alias for dotfile",
      "timestamp": 1593576508
    }
  ]
}

The revision field is the hash of the current version. Each hash in the commit list represents a complete snapshot of the file at timestamp. Hashes are the sha1 sum of the file content.

File revisions are compressed with zlib and named as the hash. In this example there would be the following files containing compressed snapshots of ~/.bashrc:

  • ~/.local/share/dotfile/bashrc/d47481afa38dcab0d8c8d163aa75e0cf5af6e355

  • ~/.local/share/dotfile/bashrc/599a1af0398b7c518bc46aaa4a9e8ae72c2d28cb

Dotfile doesn't have merge conflicts or issue with rewriting history. It's possible to restore revisions manually by decompressing the revision files with zlib.

User Config

Remote commands require a user configuration. By default Dotfile creates a directory in a location returned by the Golang function os.UserConfigDir(). This can be overridden with the global --config-file flag.

The config file can be edited manually or with the dotfile config command. The config file has the following keys:

  • remote - The remote server to use.

  • username - A Dotfilehub username. Pull, push, and commands with the --remote flag use this for account lookups.

  • token - A secret required for writing to a remote server. Find this under "Settings" / "Setup CLI" in the web interface.

Example: ~/.config/dotfile/dotfile.json

{
  "remote": "https://dotfilehub.com",
  "token": "eb19981fa4a7d29a42be2ed46790bf4ff307ba20d454ee06",
  "username": "knoebber"
}

Init

Initialize a file.

dotfile init <path> <alias>

Alias is optional. It's generated from the path when empty.

Initialize as "bashrc":

dotfile init ~/.bashrc

Initialize as "i3":

dotfile init ~/.config/i3/config i3

When the file is inside the home directory $HOME is replaced with "~" in the saved path. This allows the file to be installed to the same relative location regardless of user.

The absolute path is saved when the file is outside of the home directory.

Show

Show a file's content.

dotfile show <alias>
  • -d, --data Show the file's json data.

  • -r, --remote Show a file on a remote server.

  • -u, --username Override the configured username.

List

List tracked files. Asterisks are added to files that have uncommitted changes.

dotfile ls
  • -p, --path Include the file path in the output.

  • -r, --remote List the remote users files.

  • -u, --username Override the configured username.

Edit

Open a file in $EDITOR

dotfile edit <alias>

Diff

Print the changes of a file against a past commit. Commit hash is optional - defaults to the current commit.

dotfile diff <alias> <commit-hash>

Log

Print a log of commits for a file.

dotfile log <alias>

Commit

Save the current revision of the file.

dotfile commit <alias> <message>

Message is optional.

Checkout

Revert a file to a past revision.

dotfile checkout <alias> <hash>
  • -f, --force Overwrite unsaved changes

Hash defaults to the current revision when empty.

To checkout a specific revision use dotfile log to find the hash.

Config

Read and set user configuration.

dotfile config <keyname> <value>

Keyname and value are optional. Prints the current config when empty.

Valid values for keyname are username, remote, or token.

Push

Push a file and its revisions to a remote server.

dotfile push <alias>

The remote file will either be created or updated to the current revision of the local file. All new local revisions will be saved to the remote server.

Pull

Retrieves a file and its new revisions from a remote server. Creates a new file at path when it does not yet exist.

dotfile pull <alias>
  • -u, --username Override the configured username.

  • -a, --all Pull all files.

Alternatively pull a file without using the Dotfile CLI:

# Get a list of user's files:
curl https://dotfilehub.com/api/knoebber
# Output: [bashrc, inputrc, vim, emacs]

# Install the file:
curl https://dotfilehub.com/knoebber/inputrc > ~/.inputrc

Move

Change a file's path.

dotfile mv <alias> <path>
  • -p, --parent-dirs Create parent directories that don't exist.

Rename

Change a file's alias.

dotfile rename <alias> <new-alias>

Forget

Untracks a file - removes all Dotfile data for the file. Leaves the file in its current state on the filesystem.

dotfile forget <alias>
  • -c, --commits Remove all data except for the current revision. (Deletes history)

Remove

Untrack and remove the file from the filesystem. Equivalent to dot forget bashrc && rm ~/.bashrc.

dotfile rm <alias>