Coder Social home page Coder Social logo

ocd's Introduction

Optimally Configured Dotfiles

Do you have dotfiles skewed across lots of different machines?

This script allows you to easily track and synchronize them using Git as a backend. It makes setting up a new system very fast and simple, and minimizes "config drift", i.e. slightly different versions of your configs scattered across the various machines you use.

OCD works by configuring symlinks for all your dotfiles pointing at the Git-tracked versions in ~/.ocd, like so:

$ ls -l ~/.bashrc
lrwxrwxrwx 1 luser luser 12 Aug 25 02:25 /home/luser/.bashrc -> .ocd/.bashrc

OCD functions are wrappers for moving files in and out of "tracked" status, restoring files, backup changes to the upstream Git repository, and so forth.

To use this, you just need a centrally accessible Git repo (e.g. a repo called "dotfiles" on Github) and this one shellscript.

Download the OCD script

Replace ~/bin with wherever you like to keep your tools. Make sure it's in your PATH.

mkdir -p ~/bin
curl https://raw.githubusercontent.com/nycksw/ocd/main/ocd.sh -o ~/bin/ocd
chmod +x ~/bin/ocd
PATH="$PATH:~/bin"

Set the repository

You'll need a Git repository for storing your dotfiles. Put its URL in your OCD config:

echo '[email protected]:luser/my-dotfiles.git' >> ~/.ocd.conf

Install an SSH key for the repository

Below shows how to create a new SSH keypair for the host.

ssh-keygen -t ed25519 -f ~/.ssh/your_deploy_key

Add your new public key to your origin repository. Here are the GitHub instructions for managing deploy keys.

OCD will work if you have an ssh-agent running with the appropriate key/config. To use a specific SSH deploy key for all the Git commands, set OCD_IDENT:

echo 'OCD_IDENT=~/.ssh/your_deploy_key' >> ~/.ocd.conf

Install your dotfiles via OCD

OCD will overwrite your local files with whatever is in the repository, so make sure the Git repo has the most recent versions.

To install your dotfiles into your home directory:

ocd install

When you run ocd install it does the following:

  • checks if an SSH identity is available
  • runs git clone, syncing your central dotfile repository into your OCD directory; the default destination is ~/.ocd.
  • creates symlinks in your home directory pointing at versions in ~/.ocd (the local Git repo).
  • (Debian-only) reports which of your favorite packages are missing from the system;
    • this requires keeping a list of your favorite packages in a file called ~/.favpkgs.
  • offers to install bash completion for itself; this is optional and requires sudo.

Usage

ocd install:        install files from <OCD_REPO>
ocd add FILE:       track a new file in the repository
ocd rm FILE:        stop tracking a file in the repository
ocd restore:        pull from git main and copy files to homedir
ocd backup:         push all local changes upstream
ocd status [FILE]:  check if a file is tracked, or if there are uncommited changes
ocd export FILE:    create a tar.gz archive with everything in ~/.ocd
ocd missing-pkgs:   compare system against ~/.favpkgs and report missing

Writing portable config files

This process may require you think a little differently about your dotfiles to make sure they're portable across all the systems you use. For example, my .bashrc is suitable for every system I use, and I put domain-centric or host-centric customizations (for example, hosts I use at work) in a separate file.

Consider these lines, a version of which I include at the end of my .bashrc:

source $HOME/.bashrc_$(hostname -f)
source $HOME/.bashrc_$(dnsdomainname)

This way, settings are only applied in the appropriate context.

Managing changes to tracked files

When I log in to a system that I haven't worked on in a while, the first thing I do is run ocd restore. Any time I make a config change, I run ocd backup.

Note: the actual dotfiles are linked to their counterparts in the local ~/.ocd git branch, so there's no need to copy changes anywhere before committing. Just edit in place and run ocd backup.

There are also helper functions: ocd status tells me if I'm behind the main, and ocd missing-pkgs tells me if my installed packages differ from my basic preferences recorded in ~/.favpkgs; for example, your openbox autostart may call programs that are not installed by default on a new system, and so ocd missing-pkgs is just a very simple way to record these dependencies and make it easy to install them, e.g.: sudo apt-get install $(ocd missing-pkgs)

Adding new files is just:

  • ocd add <filename>
  • ocd backup

Finally, you may also use ocd export filename.tar.gz to create an archive with all your files. This is useful if you'd like to copy your files to another host where you don't want to use OCD.

Example output

If I change something on any of my systems, I can easily push the change back to my Git repository. For example:

$ ocd backup
โœ“ git status in /home/e/.ocd:

On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   .bashrc
[...]
Commit everything and push to '[email protected]:nycksw/dotfiles.git'? [NO/yes]: yes
[main 5ac968a] Remove bash builder line.
 1 file changed, 1 deletion(-)
[...]
To github.com:nycksw/dotfiles.git
   684882f..5ac968a  main -> main

Caveats

Merges

Occasionally I'll change something on more than one system without running ocd backup, and git will complain that it can't run git pull without first committing local changes. This is easy to fix by changing into the ~/.ocd directory and doing a typical merge, a simple git push, git checkout -f $filename to overwrite changes, or some other resolution.

Portability of this script

I've run OCD on several different distributions, but it might not work on yours. Fork this repo and go nuts. ocd.sh is relatively simple.

I'd love to receive pull requests that make this script more portable, just so long as the changes don't result in a script that's too long or complicated to maintain.

Alternatives

There are other dotfile managers! You should almost certainly use one of them instead of this one. Here's a list:

I wrote OCD before any of these existed, and I've never tried them because they seem too heavyweight for my taste, but I'm sure they offer advantages over this little pet script of mine.

ocd's People

Contributors

nycksw avatar

Stargazers

Neal Fultz avatar Reza avatar  avatar eg avatar Gil Klein avatar Greg Bray avatar alan avatar VOS avatar Florian Wallner avatar Cameron Smith avatar Nick Silkey avatar H "Waldo" G avatar Peter Sarossy avatar Alex Dong avatar Aaron Westendorf avatar John Mark Schofield avatar somename123 avatar

Watchers

 avatar  avatar

ocd's Issues

Add a TL;DR to the README.md

It's too wordy and newbie-oriented. Write a section that just explains succinctly what it is and how to use/clone it.

Warn if favdebs not installed

~/.favdebs is a convention for specifying what packages should (or should not) be installed on the system. Usually these are packages required for the various dotfiles to work properly (example: 'feh' to set the wallpaper in Openbox.)

It would be nice if there was a warning displayed if there were any missing packages. This can probably happen at ocd-restore time

`git config` breaks file-tracking

I did:

git config --global init.defaultBranch main

Which adds defaultBranch = main to ~/.gitconfig, but I noticed the changes weren't reflected in ~/.ocd/.gitconfig. So, I checked the inodes for both files, and it looks like git config is replacing ~/.gitconfig entirely, creating a new file with a new inode, so it's no longer linked to the files in ~/.ocd.

I don't really know wtf to do about that. I could add some kind of thing that checks all the files to see if inodes have changed, but that feels clunky. When does it run? What happens if it finds changes? Should it notify the user?

File-centric ocd-{add,rm}, status functions

Be able to do something like this:

me@host$ ocd-add .newdotfile
OCD: Added .newdotfile

me@host$ ocd-status .newdotfile
OCD: .newdotfile is tracked

me@host$ ocd-rm .newdotfile
OCD: Removed .newdotfile

me@host$ ocd-status .newdotfile
OCD: .newdotfile is not tracked

Streamline installation

It's still not entirely push-button to install this setup, which was the entire point of this originally. Need to walk through installing on a fresh machine and catalog any messy parts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.