我有一个不寻常的想法,使用git作为备份系统。所以,假设我有一个目录./backup/myfiles,我想用git备份它。为了保持清洁,我不想在myfiles文件夹中有一个.git目录,所以我想我可以创建./backup/git_repos/myfiles。通过查看git文档,我尝试过这样做:
$ cd backup/myfiles
$ mkdir ../git_repos/myfiles
$ git --git-dir=../git_repos/myfiles init
Initialized empty Git repository in backup/git_repos/myfiles/
$ git --git-dir="../git_repos/myfiles/" add foo
fatal: pathspec 'foo' did not match any files
您可以看到我到达的错误消息。我做错了什么?
答案 0 :(得分:161)
您只需要确保存储库知道工作树的位置,反之亦然。
要让存储库知道工作树的位置,请设置配置值core.worktree
。要让工作树知道它的git目录在哪里,添加一个名为.git的文件(不是文件夹!)并添加一行像
gitdir: /path/to/repo.git
从git 1.7.5开始,init命令为此学习了一个额外的选项。
您可以使用
初始化新的单独存储库git init --separate-git-dir /path/to/repo.git
这将初始化单独目录中的git存储库,并将.git文件添加到当前目录中,该目录是新存储库的工作目录。
以前的1.7.5 你必须使用略有不同的参数并自行添加.git文件。
要初始化单独的存储库,以下命令将工作树与存储库链接:
git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git
您当前的目录将是工作树,git将使用/path/to/repo.git
处的存储库。 init命令将自动设置core.worktree
参数指定的--git-dir
值。
您甚至可以为此添加别名:
[alias]
initexternal = !"f() { git --work-tree=. --git-dir=\"$1\" init && echo \"gitdir: $1\" >> .git; }; f"
在只读工作目录上使用git版本控制
根据上述知识,您甚至可以为工作目录设置git版本控制,而无需具有写入权限。如果您在每个git命令上使用--git-dir
或从存储库(而不是工作目录)中执行每个命令,则可以省略.git文件,因此不需要在工作目录中创建任何文件。另请参阅Leos answer
答案 1 :(得分:92)
git --git-dir=../repo --work-tree=. add foo
这会做你想要的,但是当你必须用你曾经使用的每个git命令指定它时,显然会很糟糕。
您可以导出GIT_WORK_TREE=.
和GIT_DIR=../backup
,Git会在每个命令中选择它们。但是,这只会让您轻松地在每个shell的单个存储库中工作。
我建议将.git目录符号链接到其他地方,或者从主备份目录创建.git目录的符号链接。
答案 2 :(得分:56)
--separate-git-dir
(和git init
)的git clone
选项可用于在我的git版本(1.7.11.3
)上完成此操作。该选项将git存储库与工作树分开,并在工作树的根目录中创建与文件系统无关的git符号链接(以名为.git
的文件的形式)。我认为结果与niks' answer相同。
git init --separate-git-dir path/to/repo.git path/to/worktree
答案 3 :(得分:24)
我发现撤消niks' answer:中使用的--work-tree
和--git-dir
目录更简单
$ cd read_only_repos
$ git --work-tree=/some/readonly/location/foo/ --git-dir=foo init
$ cd foo
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.file_foo
bar
...
这种方法有两个好处:
.git
文件。您只需从存储库的根目录中正常运行。我遇到的唯一警告是,您不是使用.gitignore
文件,而是编辑info/exclude
。
然后,您可以将存储库read_only_repos/foo
用作您自己的存储库中的远程存储库,即使原始文件不受版本控制。
答案 4 :(得分:18)
通常命名一个目录,该目录是一个git存储库,其工作树位于一个带有“.git”扩展名的不寻常的地方,就像一个裸存储库。
mkdir ../git_repos/myfiles.git
如果您在初始时提供了--work-tree
选项,那么这将自动设置core.worktree
配置变量,这意味着一旦指定git目录,git就会知道在哪里可以找到工作树
git --git-dir=../git_repos/myfiles.git --work-tree=. init
但你也可以在事后设置这个变量。
git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"
完成此操作后,add命令应该按预期工作。
git --git-dir=../git_repos/myfiles.git add foo
答案 5 :(得分:4)
在repo中使用git
:
cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false
从现在开始,您可以在git
目录中使用./backup/git_repos/myfiles
,而无需设置任何环境变量或其他参数。
答案 6 :(得分:1)
你可以用
之类的东西创建一个“nodgit”脚本(No Dot GIT)#!/bin/sh
gits=/usr/local/gits
x=`pwd`
testdir() {( cd $1; pwd; )}
while [ "$x" != "/" ]; do
y=`echo $x|sed -e "s/\//__/g"`
if ([ -d "$gits/$y" ]); then
export GIT_DIR="$gits/$y"
export GIT_WORK_TREE="$x"
if ([ "$1" = "nodinit" ]); then
mkdir -p "$GIT_DIR"
git init --bare; exit $?
elif ([ "$1" = "shell" ]); then
bash; exit $?
else
exec git "$@"
fi
fi
x=`testdir "$x/.."`
done
您可以调用nodgit代替git,它会根据需要通过查找git repo来设置变量。比如说你在/ usr / local / gits / __ home__foo_wibbles有一个(裸)回购,你在/ home / foo / wibbles / one然后它会找到正确的工作目录(/ home / foo / wibbles)和repo
哦,你也可以使用“nodgit shell”获取一个带有正确vars的shell,这样你就可以使用普通的旧git命令了。
答案 7 :(得分:0)
假设您的myfiles
目录已经存在并且有一些内容,您能否接受这个:
cd ~/backup
git init
git add myfiles
.git
目录位于backup
,而不是myfiles
。
答案 8 :(得分:0)
我创建了类似
的脚本〜/斌/ GIT-斜线:
#!/usr/bin/sh
export GIT_DIR=/home/Version-Control/cygwin-root.git/
export GIT_WORK_TREE=/
git --git-dir=$GIT_DIR --work-tree=$GIT_WORK_TREE "$@"
exit $?
使用--git_dir = $ GIT_DIR是多余的,但是提醒我,我也可以在脚本之外设置环境变量。
以上示例用于跟踪对cygwin系统文件的本地更改。
可以为任何需要这个的主要项目创建一个这样的脚本 - 但是/没有/.git是我的主要用途。
如果消除冗余,上面的内容足够小,可以创建shell别名或函数。
如果我经常这样做,我会将工作区恢复到
的存储库映射"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System",
in Workshop Proceedings of the Software Management Conference. 1989.
其最接近的现代对手是Perforce mappings or views,支持部分结帐以及工作区和回购的非托管。
答案 9 :(得分:0)
在要跟踪的路径之外初始化一个非裸仓库,并将 core.worktree
设置为要跟踪的路径。您可以使用终端命令设置此值或直接编辑存储库配置文件以添加:
worktree = <path to files to backup>
不要将存储库文件夹设为此路径的子文件夹,否则会递归。您可以尝试这个并简单地忽略存储库文件夹,但我认为 git 不会允许这种情况。
在您的情况下,您将转到 backup/git_repos/ to run the
initcommand and could use the
--git-dir=./myfiles` 选项以覆盖默认存储库文件夹名称。命令看起来像这样:
cd backup/git_repos
git init --git-dir=./myfiles
git config core.worktree backup/myfiles
注意:我最近为 Windows 测试了很多 git GUI,只有 Git 扩展支持使用 core.worktree 移动主工作树。
不支持 core.worktree 的 GUISourceTree、Fork、Tower、GitKraken、GitHub Desktop、GitAhead、SmartGit* 和 Git-Cola。使用 core.worktree 时,您需要坚持使用终端。
* SmartGit 将此功能与选项 2 混淆,并要求提供 .git
文件。这对于 core.worktree 不是必需的。
使用初始化位置中的 --separate-git-dir=<path to hold repository data>. This will use the specified path to hold the repository data and create a
.git` 文件在要备份的路径上初始化存储库,其中包含如下一行:
gitdir: <path to hold repository data>
对你来说,命令看起来像这样:
cd backup/myfiles
git init --separate-git-dir=backup/git_repos/myfiles/
您在 .git
中的 backup/myfiles/
文件将包含 gitdir: backup/git_repos/myfiles/
您现在操作 git 将 .git
文件的位置视为存储库位置。