Seven's blog

你不会找到路,除非你敢于迷路

0%

使用 git 备份和恢复 dotfiles

前言

Unix 用户的配置文件一般存储在以 . 开头的文件中,这些文件被统称为 “dotfiles”。

本文讲述了一种极其优雅的通过 git 备份和恢复 dotfiles 的方法。

备份

  1. 初始化 git 仓库

    1
    2
    3
    4
    5
    6
    # 初始化 git 仓库
    git init --bare $HOME/.dotfiles
    # 指定 git 仓库和工作树路径并创建指令别名,简化操作
    cp -a .bashrc{,.bak} && echo "alias dotfiles='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'" >> .bashrc && source .bashrc
    # git status 不显示未跟踪的文件
    dotfiles config status.showUntrackedFiles no
  2. 创建远程仓库,比如 git@github.com/seven/dotfiles

  3. 添加文件

    1
    2
    3
    4
    dotfiles add .zshrc
    dotfiles commit -m "add .zshrc"
    dotfiles remote add origin ${git_repo}
    dotfiles push

恢复

1
2
3
4
5
6
7
8
9
10
# 把 dotfiles 克隆到本地临时目录
git clone --separate-git-dir=$HOME/.dotfiles ${git_repo} $HOME/dotfiles-tmp
# 用临时目录中的文件覆盖本地文件
cp $HOME/dotfiles-tmp/.* $HOME
# 删除临时目录
rm -r $HOME/dotfiles-tmp/
# 指定 git 仓库和工作树路径并创建指令别名,简化操作
cp -a .bashrc{,.bak} && echo "alias dotfiles='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'" >> .bashrc && source .bashrc
# git status 不显示未跟踪的文件
dotfiles config status.showUntrackedFiles no

git 参数讲解

  • git init --bare ${path}

    Create a bare repository. If GIT_DIR environment is not set, it is set to the current working directory.

    ${path} 目录创建一个空的 git 仓库。

  • git --git-dir=${git_dir}

    Set the path to the repository (“.git” directory). This can also be controlled by setting the GIT_DIR environment variable. It can be an
    absolute path or relative path to current working directory.

    Specifying the location of the “.git” directory using this option (or GIT_DIR environment variable) turns off the repository discovery that
    tries to find a directory with “.git” subdirectory (which is how the repository and the top-level of the working tree are discovered), and
    tells Git that you are at the top level of the working tree. If you are not at the top-level directory of the working tree, you should tell
    Git where the top-level of the working tree is, with the –work-tree=${git_dir} option (or GIT_WORK_TREE environment variable)

    If you just want to run git as if it was started in ${git_dir} then use git -C ${git_dir}.

    指定 git 仓库的路径。

  • git --work-tree=${path}

    Set the path to the working tree. It can be an absolute path or a path relative to the current working directory. This can also be
    controlled by setting the GIT_WORK_TREE environment variable and the core.worktree configuration variable (see core.worktree in git-
    config(1) for a more detailed discussion).

    指定工作树的路径。

  • git clone --separate-git-dir=${git_dir}

    Instead of placing the cloned repository where it is supposed to be, place the cloned repository at the specified directory, then make a filesystem-agnostic Git symbolic link to there. The result is Git repository can be separated from working tree.

    把 git 仓库克隆到指定的目录 ${git_dir} 下,然后做一个与文件系统无关的 git 符号链接到该目录。从而使 git 仓库和工作树分离。

这里需要搞懂 git 的两个概念: “git 仓库” 和 “工作树”。
假设我们使用 git clone git@github.com/seven/dotfiles 把远程仓库克隆到了本地的 dotfiles 目录。dotfiles 目录就是“工作树”的路径,dotfiles/.git 目录就是 git 仓库的路径。

举一反三

  • 可以为不同的系统或者不同的电脑创建不同的分支
  • 可以通过灵活指定 git 仓库和工作树路径,达到备份其他文件的目的

参考文档

  • Hacker News
  • The best way to store your dotfiles: A bare Git repository
  • Dotfiles - ArchWiki
  • 用 Chezmoi 管理配置文件
微信公众号
扫码关注, 一起进步!