curl -fsSL https://raw.githubusercontent.com/connorads/dotfiles/master/install.sh | bashIt installs dotfiles and sets upstream tracking so git status and LazyGit show ahead-behind correctly.
The script activates one config (nix-darwin on macOS, home-manager on Linux), normally resolved from the machine's hostname. On a freshly reset or provisioned box the hostname rarely matches yet, so pick it explicitly:
- macOS:
DARWIN_HOST=Connors-Mac-mini(orConnors-MacBook-Air) - Linux:
HM_HOST=dev(orpenguin/rpi5)
Without the variable, the script prompts. The prompt needs a terminal, so run bash <(curl -fsSL …/install.sh) or download then run, rather than a bare curl … | bash pipe.
The script refuses a host that does not match the machine, and fails with the valid list when the host is unknown or undecidable.
The first activation passes the config explicitly (--flake …#<attr>), then sets the hostname (macOS via networking.hostName, Linux via hostnamectl). After that, bare drs/hms/up resolve the config from the hostname.
Valid host names are hardcoded in install.sh (VALID_DARWIN / VALID_HM). Keep them in sync with flake.nix when adding or renaming a config.
Use this to follow the steps by hand or to fork the repo.
-
Clone using a separate git dir
DOTFILES_REPO=https://github.com/connorads/dotfiles.git DOTFILES_DIR=$HOME/git/dotfiles BOOTSTRAP_WORKTREE=$(mktemp -d "$HOME/.dotfiles-bootstrap.XXXXXX") git clone --separate-git-dir="$DOTFILES_DIR" "$DOTFILES_REPO" "$BOOTSTRAP_WORKTREE" rm -rf "$BOOTSTRAP_WORKTREE"
git cloneneeds a checkout target path, and$HOMEis non-empty. The temporaryBOOTSTRAP_WORKTREEdir is a disposable target. -
Point the repo at
$HOMEand ensure tracking refsgit --git-dir="$DOTFILES_DIR" config core.bare false git --git-dir="$DOTFILES_DIR" config core.worktree "$HOME" git --git-dir="$DOTFILES_DIR" config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" git --git-dir="$DOTFILES_DIR" fetch origin --prune
-
Check out dotfiles into
$HOME. This backs up conflicting files to<file>.bak, then overwrites them.git --git-dir="$DOTFILES_DIR" checkout 2>&1 | sed -n 's/^[[:space:]]\+//p' | while IFS= read -r file; do if [ -f "$file" ]; then mv "$file" "$file.bak" fi done git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" checkout -f
-
Set upstream for the current branch
CURRENT_BRANCH=$(git --git-dir="$DOTFILES_DIR" symbolic-ref --quiet --short HEAD) git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" branch --set-upstream-to="origin/$CURRENT_BRANCH" "$CURRENT_BRANCH"
-
Set up nix, brew and install software
macOS (nix-darwin):
# Install Homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" eval "$(/opt/homebrew/bin/brew shellenv)" # Install Nix (vanilla, not Determinate Nix) curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --determinate false . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh # Build and activate nix-darwin configuration nix run nix-darwin/master#darwin-rebuild -- switch --flake ~/.config/nix
Linux (home-manager):
# Install Nix (vanilla, not Determinate Nix) curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --determinate false . ~/.nix-profile/etc/profile.d/nix.sh # Build and activate home-manager configuration nix run home-manager/master -- switch --flake ~/.config/nix
-
Enable commit hooks and reload the shell
dotfiles config core.hooksPath .hk-hooks mise install exec zsh
DOTFILES_DIR=$HOME/git/dotfiles
if [ "$(git --git-dir=$DOTFILES_DIR rev-parse --is-bare-repository 2>/dev/null || true)" = "true" ]; then
git --git-dir=$DOTFILES_DIR config --unset core.bare || true
fi
git --git-dir=$DOTFILES_DIR config core.worktree $HOME
CURRENT_BRANCH=$(git --git-dir=$DOTFILES_DIR/ symbolic-ref --quiet --short HEAD)
git --git-dir=$DOTFILES_DIR/ config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git --git-dir=$DOTFILES_DIR/ fetch origin --prune
git --git-dir=$DOTFILES_DIR/ --work-tree=$HOME branch --set-upstream-to=origin/$CURRENT_BRANCH $CURRENT_BRANCHThe same git-dir and work-tree technique, for a new dotfiles repo of your own.
-
Create the git dir and point the work-tree at
$HOMEDOTFILES_DIR=$HOME/git/dotfiles mkdir -p "$DOTFILES_DIR" git init "$DOTFILES_DIR" git --git-dir="$DOTFILES_DIR" config core.worktree "$HOME" git --git-dir="$DOTFILES_DIR" config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
-
Ignore everything, then un-ignore specific files
touch "$HOME/.gitignore" grep -qxF '/*' "$HOME/.gitignore" || printf '%s\n' '/*' >> "$HOME/.gitignore" grep -qxF '!.gitignore' "$HOME/.gitignore" || printf '%s\n' '!.gitignore' >> "$HOME/.gitignore"
-
Track files by un-ignoring paths in
~/.gitignore, then adding themgit --git-dir="$DOTFILES_DIR" --work-tree="$HOME" add .gitignore git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" commit -m "chore(dotfiles): initialise from scratch"
-
Optionally connect a remote and push
DOTFILES_REPO=git@github.com:your-user/dotfiles.git dotfiles remote add origin "$DOTFILES_REPO" dotfiles push -u origin HEADGit supports separate fetch and push URLs for one remote. This pulls over HTTPS and pushes over SSH, so read-only updates do not depend on SSH agent forwarding:
dotfiles remote set-url origin https://github.com/your-user/dotfiles.git dotfiles remote set-url --push origin git@github.com:your-user/dotfiles.git