我可以将.git文件夹存储在我想跟踪的文件之外吗?
我有一个不寻常的想法,使用git作为备份系统。 所以我们可以说我有一个目录./backup/myfiles,我想用git来支持它。 为了保持干净,我不想在myfiles文件夹中有一个.git目录,所以我想我可以创build./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
你可以看到我到达那里的错误消息。 我究竟做错了什么?
git --git-dir=../repo --work-tree=. add foo
这将做你想做的事情,但是当你必须使用每一个你使用的git命令来指定它的时候,这显然会很糟糕。
你可以导出GIT_WORK_TREE=.
和GIT_DIR=../backup
,Git会在每个命令中select它们。 尽pipe如此,这只能让你在每个shell的单个仓库中工作。
我宁愿build议将.git目录符号链接到其他位置,或者从主备份目录创build.git目录的符号链接。
您只需确保存储库知道工作树在哪里,反之亦然。
要让存储库知道工作树在哪里,请设置configuration值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-dir
命令,你可以省略.git文件,因此不需要在工作目录中创build任何文件。 另请参阅青less狮的答案
git init
(和git clone
)的--separate-git-dir
选项可以用来在我的git版本( 1.7.11.3
)上完成这个1.7.11.3
。 该选项将git存储库与工作树分开,并在工作树的根目录下创build文件系统不可知的git符号链接(以名为.git
的文件forms)。 我认为结果和尼克斯的答案是一致的。
git init --separate-git-dir path/to/repo.git path/to/worktree
传统的做法是将一个名为git仓库的目录命名为git仓库,该仓库的工作树位置非常不寻常,带有.git扩展名,就像裸仓库一样。
mkdir ../git_repos/myfiles.git
如果你在init时提供了--work-tree
选项,那么这将会自动设置core.worktree
configurationvariables,这意味着一旦你指定了git目录,git就会知道在哪里find工作树。
git --git-dir=../git_repos/myfiles.git --work-tree=. init
但是你也可以在事后设置这个variables。
git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"
一旦你完成了这个,add命令应该按照预期工作。
git --git-dir=../git_repos/myfiles.git add foo
我发现把niks的答案中使用的--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
文件。 您只需从存储库的根目录中正常运行。 - 它允许您即使不拥有文件系统也可以对文件系统进行版本pipe理。 Git只会写入存储库位置。
我遇到的唯一的警告是,而不是使用.gitignore
文件,你编辑info/exclude
。
然后,您可以使用存储库read_only_repos/foo
作为您自己的存储库中的远程,即使原始文件不受版本控制。
在回购中使用git
:
cd ./backup/git_repos/myfiles git init --bare git config core.worktree ../myfiles git config core.bare false
从现在开始,你可以在./backup/git_repos/myfiles
目录下使用git
,而不需要设置任何环境variables或者附加参数。
假设你的myfiles
目录已经存在,并有一些内容,你可以住这个:
cd ~/backup git init git add myfiles
.git
目录将在backup
,而不是在myfiles
。
你可以用类似的方式创build一个“nodgit”脚本(没有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来设置variables。 例如,假设您在/ usr / local / gits / __ home__foo_wibbles中有(裸)回购,并且您位于/ home / foo / wibbles /中,则会find正确的工作目录(/ home / foo / wibbles)和回购。
哦,你也可以使用“nodgitshell”得到一个正确的瓦尔设置的shell,所以你可以使用普通的旧Git命令。
我创build了看起来像的脚本
〜/斌/ 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是多余的,但是提醒我也可以在脚本之外设置环境variables。
上面的例子用于跟踪对cygwin系统文件的本地更改。
可以为任何需要此function的重大项目制作一个这样的脚本 – 但/无/.git是我的主要用途。
如果你消除了冗余,上面的内容足够小,可以构成shell别名或者函数。
如果我经常这样做,我会恢复工作空间的存储库映射
"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System", in Workshop Proceedings of the Software Management Conference. 1989.
其最接近的现代对应物是Perforce映射或观点 ,支持部分结账以及非工作区和回购的托pipe。