I track my dotfiles using this method:
- A bare repository resides in
$HOME/repos/dotfiles
. - All my dotfiles reside in their normal location, e.g.
$HOME/.vim/vimrc
, not$HOME/repos/dotfiles/vimrc
. - I run
git --git-dir=$HOME/repos/dotfiles --work-tree=$HOME ...
to manage things.
(Actually, I have a function g()
that expands to the above command when I'm in $HOME
, and to just git
otherwise.)
Everything works great, except...
The problem: Zsh git filename completion doesn't work.
Example:
% pwd
/home/brian
% g status ~
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .vim/vimrc
modified: .xmonad/xmonad.hs
no changes added to commit (use "git add" and/or "git commit -a")
% g add <Tab>
Completing not a git repository
(The "Completing ..." stuff is due to zstyle ':completion:*' format $'%{\e[0;31m%}Completing %B%d%b%{\e[0m%}'
.)
Notably, it would not suffice to somehow tell zsh's git completion to "move to/follow" the given value of --work-tree
, as if git
were being called from that directory, because explicitly doing that doesn't work either:
% cd repos/dotfiles
% g status
fatal: This operation must be run in a work tree
% g add <Tab>
Completing not a git repository
The question: Is there an easy way to get extend zsh's git completion to this kind of a case?
~/repos/dotfiles
, organized into various top-level directories, and then I usestow
to create symlinks of the dotfiles to their appropriate location (determined by the subdirectory structure of each top-level directory). It's not as simple as my original method, but (i) the dotfiles directory is a normal git repo, so zsh completion works perfectly, and (ii) I can also store configurations for things beyond just home directory dotfiles, e.g. stuff in/etc
.