Switch from the bare repository method to stow to manage my dotfiles

I finally made the switch from the bare-repository method to stow to
manage my dotfiles. This brings some nice benefits, e.g. I can savely
say what file is in my dotfiles and what is missing out. Furthermore the
usage is _way_ simpler the before. Though one downside is the more
complicated removal of files, but I've documented a way which feels nice
to me as well. Finally I removed my old setup-script since I switched to
an ansible-setup anyway. So this config will eventually be applied
ansible and I don't have to care about installed software in this repo
anymore!

Reference: https://www.gnu.org/software/stow/
Reference: https://news.ycombinator.com/item?id=11071754
Reference: https://gitea.nehrke.info/nemoinho/dev-machine/
This commit is contained in:
2025-09-05 16:43:54 +02:00
parent 78660ba340
commit f1ae24d120
4 changed files with 43 additions and 170 deletions

View File

@@ -51,7 +51,6 @@ export NVM_DIR="$HOME/.config/nvm"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# standard alias
alias config='/usr/bin/git --git-dir=$HOME/Development/nemoinho/gitea.nehrke.info/nemoinho/dotfiles --work-tree=$HOME'
alias cz='(pushd $(git rev-parse --show-toplevel); $(which cz); popd)'
alias e='eza --icons --long --time-style=long-iso --group'
alias ls='eza --time-style=long-iso --group'

View File

@@ -1,137 +0,0 @@
#!/bin/bash
set -e
_osname=$(uname -s)
if [ "$_osname" = "Darwin" ]
then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install \
git \
wget \
asciidoctor \
bash-completion \
vim
else
if [ $(which apt-get) ]
then
sudo apt-get install nala gpg curl
echo "deb [signed-by=/etc/apt/keyrings/enpass.gpg] https://apt.enpass.io/ stable main" | sudo tee /etc/apt/sources.list.d/enpass.list
curl -sSL https://apt.enpass.io/keys/enpass-linux.key | sudo gpg --dearmor -o /etc/apt/keyrings/enpass.gpg
sudo nala update
sudo nala install \
apt-transport-https \
ca-certificates \
gnupg \
git \
wget \
asciidoctor \
bash-completion \
vim \
rxvt-unicode \
i3 \
i3lock \
i3status \
scrot \
imagemagick \
libxcb-composite0 \
rofi \
oathtool \
neovim \
graphviz \
jq \
enpass
# install icon-font which I use for i3status
MATERIAL_DESIGN_FONT_ZIP=MaterialDesign-Webfont-4.9.95.zip
curl -sSL --output-dir $HOME/Downloads -o "$MATERIAL_DESIGN_FONT_ZIP" https://github.com/Templarian/MaterialDesign-Webfont/archive/v4.9.95.zip
mkdir -p $HOME/.local/share/fonts || true
unzip -jod $HOME/.local/share/fonts/ "$HOME/Downloads/$MATERIAL_DESIGN_FONT_ZIP" MaterialDesign-Webfont-4.9.95/fonts/materialdesignicons-webfont.ttf
fc-cache -fv
rm "$HOME/Downloads/$MATERIAL_DESIGN_FONT_ZIP"
# handle work-setup
while true
do
echo ""
read -p "Is this installation for work? [Yn] " yn </dev/tty
case $yn in
[Yy]*|"")
CHROME_DEB=google-chrome-stable_current_amd64.deb
curl -sSL --output-dir $HOME/Downloads -O https://dl.google.com/linux/direct/$CHROME_DEB
sudo nala install \
openconnect \
network-manager-openconnect \
network-manager-openconnect-gnome \
$HOME/Downloads/$CHROME_DEB
rm $HOME/Downloads/$CHROME_DEB
break;;
[Nn]*) break;;
*) echo "Please answer yes or no.";;
esac
done
# handle cli's for clouds
while true
do
echo ""
read -p "Is gcloud required? [Yn] " yn </dev/tty
case $yn in
[Yy]*|"")
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo tee /usr/share/keyrings/cloud.google.gpg > /dev/null
sudo nala update && sudo nala install google-cloud-cli
break;;
[Nn]*) break;;
*) echo "Please answer yes or no.";;
esac
done
else
echo Unsupported system
exit 1
fi
fi
unset _osname
# clone dotfiles for fast startup
GIT_DIR=$HOME/Development/nemoinho/gitea.nehrke.info/nemoinho/dotfiles
if [ ! -d "$GIT_DIR" ]
then
GIT_REMOTE=git@gitea.nehrke.info:nemoinho/dotfiles.git
mkdir -p "$(dirname "$GIT_DIR")"
git clone --separate-git-dir=$GIT_DIR $GIT_REMOTE $HOME/tmp-dotfiles
rm -r ~/tmp-dotfiles
else
/usr/bin/git --git-dir "$GIT_DIR" --work-tree "$HOME" pull || true
fi
/usr/bin/git --git-dir "$GIT_DIR" --work-tree "$HOME" config --local status.showUntrackedFiles no || true
/usr/bin/git --git-dir "$GIT_DIR" --work-tree "$HOME" checkout || true
# reload bash_profile to configure the current shell with the just installed dotfiles
. ~/.bash_profile
export XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
# install java with sdkman
export SDKMAN_DIR=${SDKMAN_DIR:-$XDG_CONFIG_HOME/sdkman}
curl -s https://beta.sdkman.io | /bin/bash
source "$SDKMAN_DIR/bin/sdkman-init.sh"
sdk version
sdk install java 11.0.14-tem
sdk install gradle 7.4
# install nvm to manage nodejs
curl -s https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | /bin/bash
nvm install node
export NVM_DIR="$XDG_CONFIG_HOME/nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# setup defaults
if [ $(which update-alternatives) ]
then
sudo update-alternatives --set x-terminal-emulator /usr/bin/urxvt
sudo update-alternatives --set vim /usr/bin/nvim
fi
echo "ready for work :-)"

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
README.*
!README.adoc

View File

@@ -4,42 +4,51 @@ Felix Nehrke <felix@nehrke.info>
:source-highlighter: rouge
[abstract]
I'll use the https://news.ycombinator.com/item?id=11071754["bare repository and alias method"] to track my dotfiles.
I use https://www.gnu.org/software/stow/[`stow`] to sync my dotfiles between the OS and this repository.
== Requirements
Install `git` and `stow` if not already present on the system.
.Install via apt on Debian/Ubuntu
[source,bash]
sudo apt install git stow
.Install via brew on macos
[source,bash]
brew install git stow
== Usage
Use all your familiar git commands but with `config` instead of `git`.
Checkout this repository into `~/dotfiles` and apply run `stow` to sync the dotfiles.
[IMPORTANT]
The directory should be loacted directly in the HOME directory.
Otherwise stow needs an additional flat `-t $HOME` everytime, which is a bit annoying!
[source,bash]
config status
config add .vimrc
config commit -m "Add vimrc"
config add .config/redshift.conf
config commit -m "Add redshift config"
config push
git clone git@gitea.nehrke.info:nemoinho/dotfiles.git ~/dotfiles # <1>
cd $_
stow --adopt . # <2>
[ -n "$(git status --short)" ] && git restore . # <3>
== Setup
<1> Clone this repository
<2> Create symlinks for all files managed by this repository, so that the file in the $HOME points to the file in this repository
<3> In case of differences between existing files and the ones from this repository keep the version of the repository
.Quick setup
=== Removing files
If a file is going to be removed make sure to remove the linked file as well.
Otherwise we end up with a bunch of dangling files in `$HOME`!
To automatically delete these dangling links we can use a git-hook as the following.
That will remove the links pre-commit.
.Setup git-hook to automatically remove links to deleted files
[source,bash]
curl -s https://gitea.nehrke.info/nemoinho/dotfiles/raw/branch/main/.config/dotfiles/setup-machine.sh | bash
.Clone on new machine
[source,bash]
GIT_DIR=$HOME/Development/nemoinho/gitea.nehrke.info/nemoinho/dotfiles
GIT_REMOTE=git@gitea.nehrke.info:nemoinho/dotfiles.git
git clone --separate-git-dir=$GIT_DIR $GIT_REMOTE $HOME/tmp-dotfiles
rm -r ~/tmp-dotfiles
alias config='/usr/bin/git --git-dir=$GIT_DIR --work-tree=$HOME'
config checkout
config config --local status.showUntrackedFiles no
.Initial setup
[source,bash]
GIT_DIR=$HOME/Development/nemoinho/gitea.nehrke.info/nemoinho/dotfiles
GIT_REMOTE=git@gitea.nehrke.info:nemoinho/dotfiles.git
git init --bare -b main $GIT_DIR
alias config='/usr/bin/git --git-dir=$GIT_DIR --work-tree=$HOME'
config config status.showUntrackedFiles no
config remote add origin $GIT_REMOTE
config push -u origin main
cat <<EOF > .git/hooks/pre-commit
#!/usr/bin/env bash
set -e
git status --short | grep -E '^D' | sed s/...// | while read f
do
test -L "\$HOME/\$f" && rm "\$HOME/\$f"
done
EOF
chmod +x .git/hooks/pre-commit