下面的示例经过简化以显示问题的核心,而不是问题本身(我的文件树比这更复杂)。
假设我有两个文件要备份;一个在~/somedir/otherdir
,另一个在~/otherdir/somedir/
。我想从一个 git 存储库的两个目录中备份文件。我怎样才能做到这一点?软链接仅携带有关文件存储位置的信息,而不是实际文件,而硬链接对我来说有点陌生。这是应该使用硬链接的情况吗?
澄清:我想使用它git
有四个原因:我想存储文本文件的点文件/脚本/配置并跟踪随时间的变化,我知道 git,我有一个可以用来存储它们的私有 git 存储库,以及我希望能够在多台电脑上共享这些文件。
答案1
如果您不介意移动文件...
您可以通过将文件移动到 git 存储库中,并将它们符号链接到它们的旧位置来完成此操作;你最终会得到
~/gitrepo/somedir/otherdir/file1
搬自~/somedir/otherdir/file1
~/gitrepo/otherdir/somedir/file2
搬自~/otherdir/somedir/file2
~/somedir/otherdir/file1
从到 的符号链接~/gitrepo/somedir/otherdir/file1
~/otherdir/somedir/file2
从到 的符号链接~/gitrepo/otherdir/somedir/file2
然后,您可以安全地提交 git 存储库中的文件,并使用 git 操作它们,并且使用旧文件路径的任何内容都将看到 git 工作区中当前的内容。以相反的方式链接文件或使用硬链接将是危险的,因为任何重写文件的 git 操作(更改分支、恢复到以前的版本...)都会破坏链接。 (希望这可以解释为什么硬链接并不是真正可行的解决方案。)
在这种情况下,您必须小心那些完全重写文件、破坏链接的程序;许多文本编辑器以及诸如此类的工具都会这样做sed -i
。更安全的方法是将整个文件夹移动到 git 存储库中,并对目录进行符号链接。
如果您想将文件保留在适当的位置...
另一种可能性是在你的主目录中创建一个 git 存储库,告诉 git 忽略所有内容,然后强制添加你想要跟踪的文件:
cd
git init
echo '*' > .gitignore
git add -f .gitignore
git commit -m "Initialise repository and ignore everything"
git add -f somedir/otherdir/file1
git commit -m "Add file1"
git add -f otherdir/somedir/file2
git commit -m "Add file2"
完成此操作后,您将能够轻松跟踪对已明确添加的文件的更改,但 git 不会考虑新文件。通过这个设置就可以了应该在你的主目录的子目录中也可以安全地拥有其他 git 存储库,但我还没有详细检查......
答案2
我在 GitHub 上写了如何管理点文件:https://github.com/jesuswasrasta/dotfiles
我的解决方案不涉及移动原始文件(即使我不喜欢它),也不涉及符号链接等。底层系统保持不变,不可知。
点文件
这是我使用的点文件的个人存储库。
这个想法
我需要一种精益的方式来在我的机器上存储、备份和版本点文件(*nix 但不仅如此)。
我喜欢 Git,所以我四处寻找使用 DVCS 处理它们的其他人,我发现了一些不同的方法:这就是我最终找到的方法。灵感来自于一篇文章尼古拉·保卢奇,前阿特拉斯人开发者煽动者,正如他自己定义的:)
这是原始文章:存储点文件的最佳方式。
我非常喜欢这个主意。
我对其进行了一些修改,以更好地符合我对命令名称和文件夹的品味。怎么运行的
该技术包括将点文件存储在裸露的 Git存储库,但位于自定义
$HOME/.dotfiles
文件夹而不是通常的.git
文件夹中。然后,使用特殊的 Git 别名命令,我可以添加并提交我想要在存储库中跟踪的文件,并将它们推送到远程(私有比特桶就我而言,回购协议;我建议保密,直到你确定不会推送机密信息)。存储库结构
我为每台机器使用不同的 Git 分支;在
master
分支上只有我用作模板的通用文件。主分支包含:
- 通用忽略文件
- 我经常使用的常见 shell 别名
- 我喜欢在所有机器上拥有的其他常见文件和配置
从头开始
如果您之前没有在 Git 存储库中跟踪过您的配置,则可以通过以下几行轻松开始使用此技术:
1) git init --bare $HOME/.dotfiles 2) alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME' 3) dotfiles config --local status.showUntrackedFiles no 4) dotfiles config --local core.excludesFile=.dotfilesignore 5) echo ". ~/.zsh_aliases" >> $HOME/.zshrc 6) echo "alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'" >> $HOME/.zsh_aliases 7) echo "alias dfg=dotfiles" >> $HOME/.zsh_aliases
- 第一行创建一个文件夹
~/.dotfiles
,它是一个 Git 裸存储库,用于跟踪您的文件。- 然后我们创建一个新命令
dotfiles
,它只不过是git
命令的自定义别名,配置为仅适用于您的.dotfiles
存储库。git
当我们想要与配置存储库交互时, 我们将使用它而不是常规命令。- 我们设置存储库本地的标志
status.showUntrackedFiles no
来隐藏我们尚未明确跟踪的文件。这样,当您dotfiles status
稍后键入命令和其他命令时,您不感兴趣跟踪的文件将不会显示为未跟踪。- 为了使事情更加连贯,我使用自定义
.dotfilesignore
的 Git 忽略文件而不是常见的.gitignore
文件。这样可以更轻松地记住在哪里编写排除项。- 我通常将别名存储在一个单独的文件中,例如
.zsh_aliases
,然后将其包含在.zshrc
附加此行的内容中:. ~/.zsh_aliases
。- 手动添加
dotfiles
别名定义或使用为方便起见提供的命令。- 我通常会为新创建的命令创建另一个别名,称为
dfg
;我会这样称呼它,但是,你知道, Unix 盒子上df
已经有一个 命令了:) 所以我选择了缩写词 ,它(至少对我来说)易于记忆且方便,因为在 QWERTY 键盘中这三个字母是相邻的。df
dot files git
dfg
作为 Zsh 用户,在这些示例中我使用
.zshrc
和.zsh_aliases
文件;如果您打算使用 Bash 作为您的首选 shell,.bashrc
请 随意替换它们.bash_aliases
:它们的工作方式相同。执行安装后,
$HOME
文件夹中的任何文件都可以使用普通的 Git 命令进行版本控制,并替换git
为新创建的dotfiles
别名:dotfiles status dotfiles add .vimrc dotfiles commit -m "Add vimrc" dotfiles add .bashrc dotfiles commit -m "Add bashrc" dotfiles push
将点文件安装到新系统上
安装之前,请确保您已
dotfiles
按照步骤 5)、6) 和 7) 提交了别名。然后确保您的存储库忽略您将克隆它的文件夹,这样就不会产生奇怪的递归问题:
echo ".dotfiles" >> .dotfilesignore
.dotfiles
现在将您的 Dotfiles 存储库克隆到您的 dot 文件夹中的裸存储库中$HOME
:git clone --bare <git-repo-url> $HOME/.dotfiles
在当前 shell 作用域中定义别名:
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
将裸存储库中的实际内容检出到您的
$HOME
:dotfiles checkout master
上述步骤可能会失败,并显示如下消息:
error: The following untracked working tree files would be overwritten by checkout: .zshrc Please move or remove them before you can switch branches. Aborting
这是因为您的
$HOME
文件夹可能已经有一些库存配置文件,这些文件将被 Git 覆盖(就像.zshrc
我的情况一样)。解决方案很简单:如果您关心文件,则备份它们;如果您不关心文件,则删除它们。 Nicola 为我们提供了一个可能的粗略快捷方式,将所有有问题的文件自动移动到备份文件夹:mkdir -p .dotfiles-backup && \ dotfiles checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | \ xargs -I{} mv {} .dotfiles-backup/{}
如果遇到问题,请重新运行检查:
dotfiles checkout master
将标志设置
showUntrackedFiles
为no
在此特定(本地)存储库上:dotfiles config --local status.showUntrackedFiles no
将标志设置
core.excludesFile
为.dotfilesignore
在此特定(本地)存储库上:dotfiles config --local core.excludesFile=.dotfilesignore
现在您有两个选择:为您正在安装的全新机器创建一个新分支,或者签出现有分支并使用它。
创建一个新分支
dotfiles checkout -b <my-new-machine-branch-name>
此时,您可以开始自定义点文件并将它们提交到这个新分支。您还可以将文件与其他分支进行比较,择优挑选你喜欢的东西来自其他分支。
签出现有分支
在前面的步骤中,我们检查了
master
分支,在我的个人 dotfiles 存储库中仅包含我喜欢在所有计算机上拥有的共享文件和配置(我的计算机并非都是 100% 相等)。
但是您可以在分支中提交您喜欢的所有点文件master
并始终使用它,或者如果您愿意,可以将现有的(另一台机器)检出到新的中:只需像这样切换分支:dotfiles checkout <existing-machine-branch-name>
当然,您会遇到一些冲突,就像我们之前提到的那样:使用提供的脚本处理它们或删除您计划覆盖的当前点文件。
概括
大功告成,从现在开始,您可以输入
dotfiles
或dfg
命令来添加和更新您的点文件:dotfiles status dotfiles add .vimrc dotfiles commit -m "Add vimrc" dotfiles add .bashrc dotfiles commit -m "Add bashrc" dotfiles push
安装脚本
作为不必在要设置的任何新计算机上记住所有这些步骤的快捷方式,您可以创建一个简单的脚本,如下所示:
git clone --bare <url-of-your-repo> $HOME/.dotfiles function dotfiles { /usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME $@ } mkdir -p .dotfiles-backup dotfiles checkout if [ $? = 0 ]; then echo "Checked out dotfiles repository."; else echo "Backing up pre-existing dot files."; dotfiles checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | xargs -I{} mv {} .dotfiles-backup/{} fi; dotfiles checkout dotfiles config --local status.showUntrackedFiles no dotfiles config --local core.excludesFile=.dotfilesignore
我将其存储为 BitBucket 片段,所以现在我可以这样调用它:
curl -Lks https://bitbucket.org/snippets/fsantacroce/qedGpx | /bin/bash
附录 您可能会知道的其他一些事情。
哪些点文件值得进行版本控制?
没有唯一的答案,这取决于:)
这些是我总是包含的一些文件:
.dotfilesignore
, 当然- 外壳配置文件:
.zshrc
- 别名文件:
.zshrc_aliases
- 哦我的zsh:
.oh-my-zsh/
文件夹- 我常用的 Git 配置和别名:
.gitconfig
- ... 待续 ...
桌面环境和应用程序点文件
我通常甚至对我的桌面环境点文件进行版本控制(我通常使用凯德)以及我使用的所有 K* 应用程序的配置;要考虑的文件夹是:
.kde/
对于 KDE 相关的东西.config/
对于应用程序,甚至是非 KDE 的应用程序.local/share/
这个命令:
kf5-config --path config
显示当前 KDE 安装使用的配置文件夹。
不幸的是,恢复这些文件并不容易,因为要覆盖现有文件;在KDE中,有一个众所周知的票这要求开发团队为此实施一些临时措施,但据了解,目前还没有实施任何措施。不管怎样,当从一台机器迁移到一台新机器时,我通常会手工挑选我需要的一个(例如 KDE 全局快捷方式、Dolphin 自定义等)。
哪些点文件需要被忽略?
是的,有可能缓存,温度和机器相关不需要包含的文件(或者包含起来可能很危险),例如:
Zsh 临时文件和缓存文件 :
**.zsh_history
.zsh_save
Bash 临时文件和缓存文件 :
**.bash_history
.bash_logout
还有其他的,比如:
*.config/chromium/*
*.config/session/*
*.config/pulse/*
*.m2/*
、Maven 存储库缓存
*.IntelliJ*/*
、IntelliJ 设置:我为这些设置了一个存储库 :)
*... 待续 ...每当我发现一些无用的东西需要跟踪时,我都会添加新的文件夹和文件。
您也对某些 /etc 文件进行版本控制吗?
我并不总是对
/etc
文件进行版本控制,但当我这样做时,我会进行版本控制: * Nano 配置文件:参见官方手册页了解如何处理 Nano 配置文件,以及哪些文件需要版本控制。
*... 待续 ...
答案3
查看src
,一个用于本地独立文件的简单版本控制系统。