使用 git 备份配置文件
Using git to back up configuration files
我想使用 git 作为一种备份方式,并保留我在桌面上使用的软件配置文件的更改历史记录。这将是具有 git.
本地安装的本地存储库
但是我不确定这些:
是否可以将文件添加到存储库,就好像它在与真实路径不同的路径中一样?
My concern is that if I add files naively, by copying them to the repository and updating the repo, I'd end up using double the space for each file. While it isn't going to be a lot of space, I would still prefer a cleaner solution. I've looked into git-add
, git-mv
and git-filter-branch
but they don't seem to provide a clean solution to this. Both add
and mv
mechanics can be used to accomplish this task, but don't really get around the problem of duplicating files. filter-branch
seems way too big of a hammer for this task.
添加文件后可以修改路径吗?
git-filter-branch
seems capable of doing this, but I'm unsure of the side-effects.
假设 git 不能满足我的明确需求,符号链接或硬链接是否可以避免复制文件的需要?这会工作 cross-platform,还是 git 在不同平台上以不同方式处理链接?
在 2017 年编辑 - 接受了我得到的答案,因为现在我对 git 有了更好的理解,我意识到没有比复制文件或只拥有 git 回购更好的解决方案祖父母目录。那个不优雅,意味着复制文件是最佳解决方案,symlinks/hardlinks 与这个问题无关。评论和答案可能对寻找类似但不相同的东西的人有用,所以我鼓励检查这些内容。
根据评论中的讨论,我得出结论,问题确实是:
在一个大目录层次结构中(我的完整主目录)我想将选定的文件(配置文件)置于 git 版本控制之下,而大多数其他文件("normal" 文件)不在版本中控制。
我从来没有这样做过,但我想到了 2 个选项:
1.) 使整个目录层次结构成为一个 git 工作区,但是通过使用 .git 忽略规则排除所有文件,除非它们被明确包含。因此,您需要列出配置目录或文件以对其进行版本控制。
这是一个构建小型示例目录层次结构的演示脚本。一切都被排除在 git 版本控制之外,除了配置 directories/files 明确包含(您可以从名称中猜出它们是什么。)
#! /bin/sh
time=$(date +%H-%M-%S)
mkdir example-$time
cd example-$time
touch a b c
touch conf1
mkdir d1
touch d1/a
touch d1/b
touch d1/conf
mkdir d2
touch d2/f1
touch d2/f2
mkdir conf-d
touch conf-d/conf1
touch conf-d/conf2
git init
cat >.gitignore <<EOF
# ignore all files
*
# but not directories (if a directory is once ignored, git will never
# look what is inside)
!*/
# of course .gitignore must never be ignored
!.gitignore
# list configuration files
!conf1
EOF
cat >d1/.gitignore <<EOF
# list the configuration files in this "mixed" directory
!conf
EOF
cat >conf-d/.gitignore <<EOF
# this is a configuration directory, include everthing...
!*
# ... but ignore editor backup files
*~
EOF
git add -A
git status
我在现实生活中从未这样做过,但从这个例子来看似乎可行。但是,当您的目录树中有其他 git 存储库时,您可能需要将它们作为子模块包含在内。有各种与子模块相关的陷阱,所以最后可能会变得非常棘手。
2.) 你没有提到你在什么文件系统上。如果你在 Linux 文件系统上,你可以使用 hardlinks。在某处为您的备份创建一个 git 存储库,并为所有配置文件添加 hardlinks。
这个演示脚本展示了这个想法:
#! /bin/sh
time=$(date +%H-%M-%S)
mkdir hl-example-$time
cd hl-example-$time
touch a b c
touch conf1
mkdir d1
touch d1/a
touch d1/b
touch d1/conf
mkdir d2
touch d2/f1
touch d2/f2
mkdir conf-d
touch conf-d/conf1
touch conf-d/conf2
mkdir hl-backup
cd hl-backup
git init
ln ../conf1 .
mkdir d1
ln ../d1/conf d1
mkdir conf-d
ln ../conf-d/* conf-d
git add -A
git status
同样,我在现实生活中没有这样做过,而且困难link总是有他们的陷阱。一个程序可能会取消 link 它现有的配置文件并创建一个同名的新文件而不是更新现有的(实际上这可能是一个很好的实现,因为它有助于避免损坏的配置文件)。所以你需要一个脚本来检查所有配置文件是否仍然是硬linked。并且因为您不能硬 link 目录,所以您需要一个脚本来在配置目录中搜索新的配置文件。我不知道 git 在结账时的表现如何。因此,在 git 修改(例如恢复)硬 link 备份文件之前,请确保您有另一个级别的备份。不要在生产系统上尝试这个,除非你真的知道你在做什么。
我想使用 git 作为一种备份方式,并保留我在桌面上使用的软件配置文件的更改历史记录。这将是具有 git.
本地安装的本地存储库但是我不确定这些:
是否可以将文件添加到存储库,就好像它在与真实路径不同的路径中一样?
My concern is that if I add files naively, by copying them to the repository and updating the repo, I'd end up using double the space for each file. While it isn't going to be a lot of space, I would still prefer a cleaner solution. I've looked into
git-add
,git-mv
andgit-filter-branch
but they don't seem to provide a clean solution to this. Bothadd
andmv
mechanics can be used to accomplish this task, but don't really get around the problem of duplicating files.filter-branch
seems way too big of a hammer for this task.添加文件后可以修改路径吗?
git-filter-branch
seems capable of doing this, but I'm unsure of the side-effects.假设 git 不能满足我的明确需求,符号链接或硬链接是否可以避免复制文件的需要?这会工作 cross-platform,还是 git 在不同平台上以不同方式处理链接?
在 2017 年编辑 - 接受了我得到的答案,因为现在我对 git 有了更好的理解,我意识到没有比复制文件或只拥有 git 回购更好的解决方案祖父母目录。那个不优雅,意味着复制文件是最佳解决方案,symlinks/hardlinks 与这个问题无关。评论和答案可能对寻找类似但不相同的东西的人有用,所以我鼓励检查这些内容。
根据评论中的讨论,我得出结论,问题确实是:
在一个大目录层次结构中(我的完整主目录)我想将选定的文件(配置文件)置于 git 版本控制之下,而大多数其他文件("normal" 文件)不在版本中控制。
我从来没有这样做过,但我想到了 2 个选项:
1.) 使整个目录层次结构成为一个 git 工作区,但是通过使用 .git 忽略规则排除所有文件,除非它们被明确包含。因此,您需要列出配置目录或文件以对其进行版本控制。
这是一个构建小型示例目录层次结构的演示脚本。一切都被排除在 git 版本控制之外,除了配置 directories/files 明确包含(您可以从名称中猜出它们是什么。)
#! /bin/sh
time=$(date +%H-%M-%S)
mkdir example-$time
cd example-$time
touch a b c
touch conf1
mkdir d1
touch d1/a
touch d1/b
touch d1/conf
mkdir d2
touch d2/f1
touch d2/f2
mkdir conf-d
touch conf-d/conf1
touch conf-d/conf2
git init
cat >.gitignore <<EOF
# ignore all files
*
# but not directories (if a directory is once ignored, git will never
# look what is inside)
!*/
# of course .gitignore must never be ignored
!.gitignore
# list configuration files
!conf1
EOF
cat >d1/.gitignore <<EOF
# list the configuration files in this "mixed" directory
!conf
EOF
cat >conf-d/.gitignore <<EOF
# this is a configuration directory, include everthing...
!*
# ... but ignore editor backup files
*~
EOF
git add -A
git status
我在现实生活中从未这样做过,但从这个例子来看似乎可行。但是,当您的目录树中有其他 git 存储库时,您可能需要将它们作为子模块包含在内。有各种与子模块相关的陷阱,所以最后可能会变得非常棘手。
2.) 你没有提到你在什么文件系统上。如果你在 Linux 文件系统上,你可以使用 hardlinks。在某处为您的备份创建一个 git 存储库,并为所有配置文件添加 hardlinks。
这个演示脚本展示了这个想法:
#! /bin/sh
time=$(date +%H-%M-%S)
mkdir hl-example-$time
cd hl-example-$time
touch a b c
touch conf1
mkdir d1
touch d1/a
touch d1/b
touch d1/conf
mkdir d2
touch d2/f1
touch d2/f2
mkdir conf-d
touch conf-d/conf1
touch conf-d/conf2
mkdir hl-backup
cd hl-backup
git init
ln ../conf1 .
mkdir d1
ln ../d1/conf d1
mkdir conf-d
ln ../conf-d/* conf-d
git add -A
git status
同样,我在现实生活中没有这样做过,而且困难link总是有他们的陷阱。一个程序可能会取消 link 它现有的配置文件并创建一个同名的新文件而不是更新现有的(实际上这可能是一个很好的实现,因为它有助于避免损坏的配置文件)。所以你需要一个脚本来检查所有配置文件是否仍然是硬linked。并且因为您不能硬 link 目录,所以您需要一个脚本来在配置目录中搜索新的配置文件。我不知道 git 在结账时的表现如何。因此,在 git 修改(例如恢复)硬 link 备份文件之前,请确保您有另一个级别的备份。不要在生产系统上尝试这个,除非你真的知道你在做什么。