Question

I stored my dotfiles in github, with lots pains, because of no automation. I have to update it myself.

Is there a way that can auto install/update/sync dotfiles? I mean in a fresh server, I download dotfiles and exec a install script to copy dotfiles to local. After some time, I can exec a updateToRemote script to push local changes to remote repo, and on another server, I can exec a updateToLocal script to pull remote changes to local.

Something like that.

Was it helpful?

Solution 2

The main source of information about dotfiles is dotfiles.github.io.

It references blog posts like Using Git and Github to Manage Your Dotfiles, based on a symlink method.

For starters, we’ll be putting all of our dotfiles into a folder called dotfiles, like so: /home/smalleycreative/dotfiles/vimrc.
Then, we’ll simply symlink to them from our home directory.


Jaime mentions the Atlassian tutorial "The best way to store your dotfiles: A bare Git repository"

The technique consists in storing a Git bare repository in a "side" folder (like $HOME/.cfg or $HOME/.myconfig) using a specially crafted alias so that commands are run against that repository and not the usual .git/ local folder, which would interfere with any other Git repositories around.
(and then the dotfiles folder is managed as a git repo)

OTHER TIPS

The above answers are excellent and are exactly how I would do it on "real operating systems".

I ran into an issue with this on a well-known commercial OS using cygwin/msys whereby using symlinks can sometimes be problematic with "native" ports of some of my favorite software.

To work around this I experimented with just making the folder $HOME be a git repository directly. After some failures I found the key is all in the .gitignore file.

So the setup I've been using for a while was created by making $HOME a repository, making a .gitignore file, and adding the required "dotfiles" files individually. I also added a repository on a backup up drive (z: in this case) as an upstream just to gain the automatic backups. If you're folder is already backed up, adding an upstream is an unnecessary complication. So, assuming "/z/Backups/Dotfiles.git" is a pre-existing "bare" repository, in msys shell, the steps to set things up are:

$ cd $HOME
$ git init
Initialised empty Git repository in $HOME
$ git add .bashrc .emacs .gitconfig # for example
$ git commit -m "Initial import of dotfiles"
[master (root-commit) xxxxxxxx] Initial import for dotfiles
 3 files changed, xxx instertions(+)
 create mode 100644 .bashrc
 create mode 100644 .emacs
 create mode 100644 .gitconfig

# The following two lines just add an "upstream" purely for backup purposes.
$ git remote add origin /z/Backups/Dotfiles.git
$ git push -u origin master
<< snip >>

Next I put the following into $HOME/.gitignore:

# First exclude everything.
*
# then re-include all "dotfiles"
!/.*
# then a bunch of specific excludes as they are more-or-less "cache" data rather than configuration.
/.bash_history
/.dbus-keyrings/
/.emacs.d/
/.gimp-2.8/
/.git/
/.gitk
/.idlerc/
/.lesshst
/.saves/
/.thumbnails/

Finally the following commands (apologies I didn't capture the output from these) add the .gitignore itself to the repository:

$ cd $HOME
$ git add .gitignore
$ git commit -m "Added some rules so git status on the dotfiles is useful."
$ git push

Now any "normal" files you add to your home dir get ignored by the dotfiles repo, but any new dotfiles show up in git status e.g.:

$ cd $HOME
$ touch NewFile.txt
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

$ touch .funkychicken
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .funkychicken

nothing added to commit but untracked files present (use "git add" to track)

So far this has been working well, even with some subdirs being their own (unrelated) git repository. Sometimes there are "quirks" with non-git subdirs, but so far nothing problematic.

I'm using git repository (github) and bash script to creating symlinks. But now I found this tool which seems to be more powerful. Check it out: https://github.com/shanx/python-dotfiles.

Well, it's three years later and nobody has come up with anything great so i took a stab at this problem. It's platform agnostic and shell agnostic with no dependancies other then the bourne compatible shell you have available(bash, zsh, ksh, etc). It works on mac, linux, & windows:

dotsys

It will automatically synchronize changes to your dotfiles with github and multiple machines, along with many other features.

I found an interesting way to use plain git to manage your dotfiles, no symlinks needed. This way, you should be able to do push and pull the usual way:

Setup

git init --bare $HOME/.myconf
alias config='/usr/bin/git --git-dir=$HOME/.myconf/ --work-tree=$HOME'
config config status.showUntrackedFiles no

where my ~/.myconf directory is a git bare repository.

Usage

The usual git commands can then be used with the git alias, e.g. config or whatever you choose.

config status
config add .vimrc
config commit -m "Add vimrc"
config push

Benefits

  • No extra tooling
  • no symlinks

More Infos

The main idea is having a separated directory (usually called .dotfiles) with all the real dotfiles which you want to keep track in git and having symbolic links in the home directory.

There is already a lot of work done for this approach so I will recommend you to check DFM (dotfiles manager):

  • Here is my dotfiles selection using dfm (you can consider it an example): vicente's dotfiles
  • Github official repository DFM site

With a bare git repository I recommend using a git alias instead of a bash alias. It integrates more nicely, because git autocompletion for git commands still works:

git init --bare ~/dotfiles.git
git config --global alias.dotfiles '!git --git-dir=$HOME/dotfiles.git/ --work-tree=$HOME'

It's used like this:

git dotfiles add .gitconfig
git dotfiles commit -m 'Add gitconfig'

Some further information in this blogpost.

pain point:

  1. We may need to use git-submodules for: zsh-plug, vim-plug, coc, tpm(tmux plugins)
  2. If a symbolic link contains $HOME, and you have different account, suck.

ref:

  1. simple
    https://www.atlassian.com/git/tutorials/dotfiles
  2. detailed
    https://dotfiles.github.io

I have tried:

  • chezmoi:
    too complex!
    My soft link become recursive, and the cause seems to be chezmoi

  • submodule (like softlink. vim-plug use submodule to manage plugins)

  • subtree (like copy. "The Internet is full of articles on why you shouldn’t use Git submodules. Use subtree! )

todo

https://dotfiles.github.io/tips/

Submodules make managing dotfile dependencies so much easier. If you get fed up with submodules, many people prefer git-subtree, which lets you merge subtrees (other repositories) into one Git repository, and later split and push changes back out.

https://www.atlassian.com/git/tutorials/git-subtree

I was also looking for some way to set up a new machine in a minimal number of steps, after spending some time I found that almost all the developers use git to store and share these files and symlinks to sync them.

Well, symlinks works, but it isn’t the best way to sync your local files to the git repository. There is a much better solution to this, written by people at Atlassian – https://www.atlassian.com/git/tutorials/dotfiles.

So, to git bare repository is the best and most elegant way to sync your files with your remote copy create a bash script to automate installation and set up.

Managing dotfiles

The trick to managing these dotfiles is by creating a bare git repository. If you are starting from scratch and have not tracked your dotfiles before, make a bare repository in the $HOME directory.

git init --bare $HOME/.dotfiles

Just to make it easier to use we’ll alias this to dotfiles which we will use instead of regular git to interact with our dotfiles repository.

alias dotfiles="/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME"

Now we are good to track our dotfiles using the dotfiles command, some of the examples are:

# to check the version history 
dotfiles log

# to check the status of the tracked and untracked files 
dotfiles status

# to add a file for tracking
dotfiles commit .vimrc -m ".vimrc added"

# push new files or changes to the github
dotfiles push origin main

I also use this way to sync and store my dotfiles, see my dotfiles repository and can read at Storing dotfiles with Git - This is the way where I wrote about managing dotfiles for multiple devices.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top