Tip
Proctor your user settings ~/.*
| $HOME
with
dotfiles --
topic,
io,
codespaces,
devcontainers,
"awesome"
This is my dotfile repository. It follows the "$HOME
is a repo" pattern, with bells attached. See the devlog for more.
This dotfile repository is setup in a way that it follows "$HOME
is a repo", in multiple ways.
- "
$HOME
is this repo" -- you can directly clone this on top of$HOME
. - "
$HOME
is another repo" -- you add this as a submodule in your own dotfiles repo ~=$HOME
.
My use cases are a combination of
- For personal machines
- "
$HOME
is this repo" :: "clone this'shome
"
- "
- For work machines
- "
$HOME
is this repo" :: "fork this'shome
" to my work account CloutKhan/dotfiles-base - + "
$HOME
is another repo" :: "remake this'sbase
and target your fork of this'shome
"
- "
Tip
The other provided use cases allow you to do the exact same thing, but with an emphasis on keeping your own forks of everything, in every case. I like what I've done here, but fundamentally dotfiles are "personal" configuration, so if you do like this pattern, you should fork it, because there's no guarantee I won't completely change this at any point. This's main
is an example of the setup, with some essentially unchanged config files as examples only. This's home
is the actual settings I use. If you kinda like the idea of this, but that's it, the main
branch's init commit contains the actual core files. Idk do what you want lol.
To use any approach, you'll need to have git
installed, as well as ssh
, and have the ssh-agent
running, and your key added to the agent, and uploaded to GitHub. See my ssh gist for steps on how to handle setting up ssh
on Ubuntu or Windows (pay close attention to the step for setting "GIT_SSH"
if you're on Windows). If you already have ssh
setup and git
installed, then you're ready to continue to one of the below steps!
Important
A critical feature that underpins all approaches to using these dotfiles effectively, you should be aware of this directory. Different config files are allowed to independently expect or optionally hook various files that should or must be kept under ~/.include/*
. They provide a means for "core" or "centralised" or "shared" configuration to be kept in this repository, but also allows "extensible" configuration files, that are "core" files with the ability to seek out "extension" configuration files, that needn't or shouldn't be checked-in here. "Extensible" just means files that can attempt to parse other files in ~/.include/*
and will composite or allow overwriting of "core" (checked-in here) config, by the "extension" configuration files that you will have to maintain in ~/.include/*
.
Tip
See both ~/.include/.pre/README.md
and ~/.include/.post/README.md
for the two most commonly parsed folders, that provide suggestions on what config files to add in either place. For an illustrative example of this, have a look at how to add your ssh key setup to .bashrc
.
If you're planning to accept this repo into your $HOME
, you're doing so aware that these steps will destructively replace files of the same name that exist in your $HOME
already.
You would typically be interested in following this step as one of the first things you do setting up a new machine, so the destructivity would be limited to only replacing the user files that the system had generated for you. If you're following this step at some other point well after you've been using your machine for a while, chances are that customisations and personal settings might have crept in to your local dotfiles.
If that is the case, you should try your best to extract whatever diff
there is between your existing config and what's in here, and keep it under ~/.include/
. Alternatively, you could back up your existing config just in case, as an optional step listed in the below.
If you're going to just clone this, then you wouldn't be able to checkin your ~/.include/*
's, but if you fork this, you can checkin you ~/.include/*
's.
More than likely, ~
won't be empty, so git
will refuse to clone into it.
- If you have pre-existing checkout here, remove it;
rm -rf .git/
- Be in your home directory;
cd
works differently acrossbash
,pwsh
, andcmd
- Make
~
the repo, add the remote, and set the head. ONLYbash
orcmd
, NOTpwsh
.
Clone my home
Caution
Destructively overwrite the files of the same name as those checked in.
git init && git remote add origin [email protected]:Skenvy/dotfiles.git && git fetch && git checkout -b home remotes/origin/home -f
Fork this, calling it dotfiles
, and edit the following to point you <YOU>
.
Caution
Destructively overwrite the files of the same name as those checked in.
git init && git remote add origin [email protected]:<YOU>/dotfiles.git && git fetch
# Use only the core set on main
git checkout -b main remotes/origin/main -f
# Use and extend my home settings
git checkout -b home remotes/origin/home -f
If you would like to utilise the configurations here as a base, but also be able to add and track your own .include
files, then adding this as a submodule is what you want.
Using submodules, you can include and refer to this dotfiles repo inside of another dotfiles repo, where you can track this repository and use its contents without ending up with a cluttered repository, while also maintaining your own .include
files, as well as checking them in, whether for a public or private dotfiles repo.
If this sounds like something you want to try, you should add this repository as a submodule in your own dotfiles repository, and symlink its contents into $HOME
(a script to do the linking is provided). This lets you use and stay up-to-date with changes to this, but also allows you to commit any additional files you need, provided they wont just get symlinked over by following this process. To read about what originally motivated me to provide two seemingly antithetical ways of consuming this repo, see this.
If you do not yet have a dotfiles repository, and this is the way you intend to start one for the first time, or starting over, there's a few things to take note of.
Notably, some files "can't" be symlinked, in that the programs that read them won't be happy following symlinks, e.g. certain git
configuration for example can't by symlinked as git
won't follow symlinks.
You'll need to create a new repo that should match this's base
. If you'd rather fork this and work out of your clone of your fork in this's base
branch, that's fine too, but it should be easier to just put together the handful of files.
To begin your repository, you may start with a blank repository, and add two files;
.gitignore
of just*
.gitattributes
of just* text=auto
Which assumes that you will be only ever "force adding" with git add -f
, and that you won't be checking in anything other than text files. These both exist in this repo with the same content, but they will be ignored by the symlinking script.
Now you have an "existing repository" with .gitignore
and .gitattributes
, follow the next steps.
Here's how you would submodule this into another repository and symlink it into $HOME
, whether you are submoduling this repo, or if you forked it and you're submoduling your fork.
- If you use a
.gitignore
that is just*
, this can conflict with adding a submodule, so temporarilyrm .gitignore
- If you'd like to fork this first, you can, and, say, call it
dotfiles-base
- Now you can track this as a submodule
git submodule add [email protected]:Skenvy/dotfiles.git
- Or if you forked
git submodule add -- [email protected]:<YOU>/dotfiles-base.git dotfiles
- The submodule and
.gitmodules
are staged, sogit restore .gitignore
and commit. git submodule init && git submodule update
- +
git submodule update --remote
to periodically retrack your modules'sHEAD
Now with a .gitmodules
file that places this repository in the dotfiles
folder in the repo that has added this;
# If you submodulesd this directly --
[submodule "dotfiles"]
path = dotfiles
url = [email protected]:Skenvy/dotfiles.git
branch = main # or home
# Or if you forked this and submoduled your fork of this --
[submodule "dotfiles"]
path = dotfiles
url = [email protected]:<YOU>/dotfiles-base.git
branch = home
With the submodule initialised and updated we can now symlink its contents into $HOME
.
Caution
CLOBBER_HOME=DESTRUCTIVELY
will force symlinks (ln -sf
) to write over files.
cd ~ && ./dotfiles/bin/dotfiles-submodule-symlinks # Safest.
# Or, if you prefer to live on the edge..
CLOBBER_CHECKEDIN_ROOT=REPLACE CLOBBER_HOME=GRACEFULLY ./dotfiles/bin/dotfiles-submodule-symlinks
Warning
If you want to maintain a README.md
that will display on the github page of the repository that submodules this, because this process will clobber the including repository's root README.md
with a symlink to this repository's README.md
, you can get around this by placing your README.md
you want displayed at .github/README.md
, which is the first path for a README.md
file that github will look for (even before a root README.md
).
Important
Note that the process of linking files into $HOME
wont touch several files, listed in the script. You should ideally have a ~/.gitignore
of just *
and a ~/.gitattributes
of just * text=auto
.
Note
dotfiles by Nathan Levett is licensed under CC-BY-SA-4.0