Help us shape the future of Go! Take the 2026 Go Developer Survey

dof

command module
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

= dof

image:https://img.shields.io/badge/License-Apache%202.0-blue.svg[link="http://www.apache.org/licenses/LICENSE-2.0"]
image:https://github.com/steffakasid/dof/actions/workflows/codeql-analysis.yml/badge.svg[link:https://github.com/steffakasid/dof/actions/workflows/codeql-analysis.yml]
image:https://github.com/steffakasid/dof/actions/workflows/release.yml/badge.svg[link:https://github.com/steffakasid/dof/actions/workflows/release.yml]
image:https://github.com/steffakasid/dof/actions/workflows/go-test.yml/badge.svg[link:https://github.com/steffakasid/dof/actions/workflows/go-test.yml]

dof is a CLI tool for managing dotfiles with a bare git repository. It maps a bare repository into a work tree and provides commands to initialize, checkout, add, synchronize, and manage dotfiles.

The tool is written in Go and uses `cobra` for CLI handling, `viper` for configuration, and `logrus` for logging.

== General usage

The typical workflow is:

* configure the repository path, branch, or profile.
* initialize or checkout the dotfile repository.
* add files with `dof add`.
* sync changes with `dof sync`.
* use `dof alias` for direct git commands when needed.

=== Initialize a new repository

When creating a new local dotfile repository:

* `dof init` - creates the bare repo and checks out the configured branch.
* `dof add <file>` - stages and commits a file into the dotfile repo.
* `dof alias remote add origin <git-url>` - add a remote repository.
* `dof sync` - push and pull changes on the configured branch.

If you use a remote repository, you may also need to set the upstream branch manually, for example:

[source,shell]
----
git config --global init.defaultBranch main
----

=== Checkout an existing repository

To connect to an existing remote dotfile repo:

* `dof checkout <git-remote-repo>` - clones the repo as a bare repository, renames existing local files as backups, and checks out the tracked dotfiles.

=== Synchronize changes

* `dof add <file>` - add and commit a file.
* `dof status` - show the git status for the current bare repository.
* `dof sync` - commit local changes, push to origin, and pull remote changes with rebase.
* `dof sync --push-only` - only commit and push local changes.
* `dof sync --pull-only` - only pull remote changes.

== Configuration

dof supports configuration in several ways:

* `--config <file>` or `-c` - use a custom config file.
* `--profile <name>` - select a named profile from the config.
* `--repository <path>` or `-r` - path to the bare git repository.
* `--branch <name>` or `-b` - git branch to track.
* environment variables prefixed with `DOF_`.

The default config file is `$HOME/.dof.yaml`.

Profiles are defined under `profiles.<name>` and can override `repository`, `branch`, `skip_files`, and `git_env`.

The `--profile` flag selects one named profile from this single config file. That means you can keep multiple repository definitions in one shared config and switch between them at runtime.

Example config:

[source,yaml]
----
repository: /home/user/.dof
branch: main
skip_files:
  - README.md
  - LICENSE
git_env:
  GIT_CONFIG_GLOBAL: ~/.gitconfig
profiles:
  work:
    repository: /home/user/.dof-work
    branch: work
    skip_files:
      - scm-info.yaml
      - README.adoc
    git_env:
      GIT_CONFIG_GLOBAL: ~/.gitconfig_work
  personal:
    repository: /home/user/.dof-personal
    branch: main
----

Use profiles like this:

* `dof --profile work init`
* `dof --profile personal sync`

=== Git environment variables

The `git_env` option is a map of environment variables that dof applies to
every git invocation (`init`, `checkout`, `add`, `sync`, `status`, `alias`).
Use it to control git's behaviour without changing your global git setup — for
example, to point git at a dedicated global config file:

[source,yaml]
----
git_env:
  GIT_CONFIG_GLOBAL: ~/.gitconfig
  GIT_SSH_COMMAND: ssh -i ~/.ssh/dof_key
----

Notes:

* `git_env` is configured only in the config file (globally and per profile);
  there is no CLI flag or `DOF_` environment variable for it.
* Profile values win over global values per key; keys set only globally are
  merged in.
* The variables are added on top of your existing shell environment — you only
  list additions or overrides; `PATH`, `HOME`, and the rest are kept.
* Values are passed to git verbatim; dof does not expand `~` or `$VAR`
  (git itself expands `~` in paths such as `GIT_CONFIG_GLOBAL`).

=== Adding a profile

To add a new profile, open `$HOME/.dof.yaml` and add an entry under `profiles`:

[source,yaml]
----
profiles:
  myprofile:
    repository: /home/user/.dof-myprofile
    branch: main
    skip_files:
      - README.md
----

Each profile can set any combination of `repository`, `branch`, and `skip_files`. Values you omit fall back to the top-level defaults.

Then use the profile with `--profile myprofile`:

[source,shell]
----
dof --profile myprofile init
dof --profile myprofile checkout git@github.com:user/dotfiles.git
dof --profile myprofile sync
----

=== Skipping files

Some dotfile repositories contain files that are useful on the remote (e.g. `README.md`, `LICENSE`, `scm-info.yaml`) but should not appear in the home directory. The `skip_files` option excludes these files from the working tree.

Add the files you want to skip to your config:

[source,yaml]
----
skip_files:
  - README.md
  - README.adoc
  - LICENSE
  - scm-info.yaml
----

This works by setting up git sparse-checkout in non-cone mode. Once applied, the excluded files stay absent across all git operations (checkout, pull, merge) without any extra wrapper logic.

The skip rules are applied automatically when you run `dof init` or `dof checkout`. If you change the `skip_files` list later, run `dof init` again to update the sparse-checkout rules.

To add `skip_files` to an existing repository that was already initialized, just add the list to your `$HOME/.dof.yaml` and run:

[source,shell]
----
dof init
----

This re-applies the sparse-checkout rules and removes the skipped files from your working tree. The files remain tracked in git and are still pushed to the remote — they just do not appear locally.

== Command overview

* `dof init` - initialize a bare dotfile repository.
* `dof checkout <git-repo-url>` - clone and checkout an existing bare repository.
* `dof add <file>` - add a file to the repository and commit it.
* `dof status` - show repository status.
* `dof sync` - sync local and remote changes.
* `dof alias ...` - run any git command against the configured bare repository.
* `dof completion <bash|zsh|fish|powershell>` - generate shell completion.
* `dof version` - print version and build metadata.

== Project structure

* `main.go` - application entrypoint.
* `cmd/` - CLI command implementations.
** `root.go` - root command, configuration and flags.
** `init.go` - repository initialization logic.
** `checkout.go` - checkout workflow for existing repos.
** `add.go` - add files to the repository.
** `sync.go` - sync workflow with remote.
** `status.go` - git status command.
** `alias.go` - arbitrary git command support.
** `completion.go` - shell completion generation.
** `version.go` - version command.
* `go.mod`, `go.sum` - module and dependency definitions.

== Dependencies

dof requires `git` to be installed and available on `PATH`.

Go dependencies:

* `github.com/spf13/cobra` - CLI command framework.
* `github.com/spf13/viper` - configuration and environment handling.
* `github.com/sirupsen/logrus` - logging.
* `github.com/stretchr/testify` - unit testing helpers.

Indirect dependencies include the Cobra/Viper ecosystem packages such as `fsnotify`, `pflag`, `afero`, and `yaml.v3`.

== Development

Build the project:

[source,shell]
----
go build -o dof ./...
----

Run the CLI:

[source,shell]
----
./dof --help
go run main.go --help
----

Run tests:

[source,shell]
----
go test ./...
----

Format the code:

[source,shell]
----
go fmt ./...
----

== Notes

dof is designed to work with one configured repository per invocation. Use profiles, `--repository`, or `--config` to switch between repositories on the same machine.

== GitHub Actions

This repository uses GitHub Actions for continuous integration, including Go tests, CodeQL analysis, and release workflow automation. It also builds binaries for release distribution.

Documentation

Overview

Copyright © 2020 Steffen Rumpf <github@steffen-rumpf.de>

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Directories

Path Synopsis
Package cmd implements the CLI commands for dof.
Package cmd implements the CLI commands for dof.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL