我可以将 .git 文件夹存储在我想要跟踪的文件之外吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/505467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I store the .git folder outside the files I want tracked?
提问by Rory
I have an unusual idea to use git as a backup system. So let's say I have a directory ./backup/myfiles and I want to back that up using git. To keep things clean I don't want to have a .git directory in the myfiles folder, so I thought I could create ./backup/git_repos/myfiles. From looking at the git docs, I've tried doing this:
我有一个不寻常的想法,即使用 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
You can see the error message I get there. What am I doing wrong?
您可以看到我到达那里的错误消息。我究竟做错了什么?
采纳答案by Bombe
git --git-dir=../repo --work-tree=. add foo
This will do what you want but will obviously suck when you have to specify it with every git command you ever use.
这将执行您想要的操作,但是当您必须使用您曾经使用的每个 git 命令指定它时,显然会很糟糕。
You can export GIT_WORK_TREE=.
and GIT_DIR=../backup
and Git will pick them up on each command. That will only comfortably allow you to work in a single repository per shell, though.
你可以导出GIT_WORK_TREE=.
,GIT_DIR=../backup
并且 Git 会在每个命令上选择它们。但是,这只会让您轻松地在每个 shell 中的单个存储库中工作。
I'd rather suggest symlinking the .git directory to somewhere else, or creating a symlink to the .git directory from your main backup directory.
我宁愿建议将 .git 目录符号链接到其他地方,或者从主备份目录创建到 .git 目录的符号链接。
回答by niks
You just need to ensure that the repository knows where the work tree is and vice versa.
您只需要确保存储库知道工作树在哪里,反之亦然。
To let the repository know where the work tree is, set the configuration value core.worktree
. To let the work tree know where it's git directory is, add a file named .git (not a folder!) and add a line like
要让存储库知道工作树的位置,请设置配置值core.worktree
。为了让工作树知道它的 git 目录在哪里,添加一个名为 .git 的文件(不是文件夹!)并添加一行
gitdir: /path/to/repo.git
Since git 1.7.5 the init command learned an extra option for this.
从 git 1.7.5 开始,init 命令为此学习了一个额外的选项。
You can initialize a new separate repository with
您可以初始化一个新的单独的存储库
git init --separate-git-dir /path/to/repo.git
This will initialize the git repository in the separate directory and add the .git file in the current directory, which is the working directory of the new repository.
这将在单独的目录中初始化 git 存储库,并在当前目录中添加 .git 文件,该文件是新存储库的工作目录。
Previously to 1.7.5you had to use slightly different parameters and add the .git file yourself.
在 1.7.5 之前,您必须使用稍微不同的参数并自己添加 .git 文件。
To initialize a separate repository the following command links the work-tree with the repository:
要初始化一个单独的存储库,以下命令将工作树与存储库链接起来:
git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git
Your current directory will be the working tree and git will use the repository at /path/to/repo.git
. The init command will automatically set the core.worktree
value as specified with the --git-dir
parameter.
您的当前目录将是工作树,git 将使用位于/path/to/repo.git
. init 命令将自动设置参数core.worktree
指定的值--git-dir
。
You could even add an alias for this:
您甚至可以为此添加别名:
[alias]
initexternal = !"f() { git --work-tree=. --git-dir=\"\" init && echo \"gitdir: \" >> .git; }; f"
Use git version control on a read-only working directory
在只读工作目录上使用 git 版本控制
With the knowledge above, you can even set up git version control for an working directory without having write permissions. If you either use --git-dir
on every git command or execute every command from within the repository (instead of the working directory), you can leave out the .git file and therefore do not need to create any files within the working directory. See also Leos answer
有了以上知识,您甚至可以在没有写入权限的情况下为工作目录设置 git 版本控制。如果您--git-dir
在每个 git 命令上使用或从存储库(而不是工作目录)中执行每个命令,则可以省略 .git 文件,因此不需要在工作目录中创建任何文件。另见狮子座回答
回答by Fryer
The --separate-git-dir
option for git init
(and git clone
) can be used to accomplish this on my version of git (1.7.11.3
). The option separates the git repository from the work tree and creates a filesystem agnostic git symbolic link (in the form of a file named .git
) in the root of the work tree. I think the result is identical to niks' answer.
(and )的--separate-git-dir
选项可用于在我的 git ( )版本上完成此操作。该选项将 git 存储库与工作树分开,并在工作树的根目录中创建一个与文件系统无关的 git 符号链接(以名为 的文件的形式)。我认为结果与niks 的答案相同。git init
git clone
1.7.11.3
.git
git init --separate-git-dir path/to/repo.git path/to/worktree
回答by Leo
I find it simpler to reverse the --work-tree
and --git-dir
directories used in niks' answer:
我发现反转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
...
This approach has two advantages:
这种方法有两个优点:
- It removes the need to have any command-line options or
.git
files. You just operate normally from within the root of the repository. - It allows you to version a file system even if you don't own it. Git will only write to the repository location.
- 它不需要任何命令行选项或
.git
文件。您只需从存储库的根目录中正常操作即可。 - 即使您不拥有它,它也允许您对文件系统进行版本控制。Git 只会写入存储库位置。
The only caveat I have encountered is that instead of using a .gitignore
file, you edit info/exclude
.
我遇到的唯一警告是,不是使用.gitignore
文件,而是编辑info/exclude
.
You can then use the repository read_only_repos/foo
as a remote in your own repositories even if the original files are not under version control.
read_only_repos/foo
即使原始文件不受版本控制,您也可以将存储库用作您自己存储库中的远程存储库。
回答by CB Bailey
It's conventional to name a directory that is a git repository that has its working tree in an unusual place with a '.git' extension, much like a bare repository.
通常将目录命名为 git 存储库,该目录的工作树位于带有“.git”扩展名的不寻常位置,很像裸存储库。
mkdir ../git_repos/myfiles.git
If you had provided the --work-tree
option at init time then this would have automatically set up the core.worktree
config variable that means that git will know where to find the working tree once you specify the git directory.
如果您--work-tree
在初始化时提供了该选项,那么这将自动设置core.worktree
配置变量,这意味着一旦您指定了 git 目录,git 将知道在哪里可以找到工作树。
git --git-dir=../git_repos/myfiles.git --work-tree=. init
But you can set this variable after the fact as well.
但是您也可以事后设置此变量。
git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"
Once you've done this, the add command should work as expected.
完成此操作后,添加命令应该会按预期工作。
git --git-dir=../git_repos/myfiles.git add foo
回答by To1ne
Use git
inside the repo:
git
在 repo 中使用:
cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false
From now on, you can use git
inside the ./backup/git_repos/myfiles
directory, without setting any environment variables or additional parameters.
从现在开始,您可以git
在./backup/git_repos/myfiles
目录内部使用,而无需设置任何环境变量或附加参数。
回答by Paul Hedderly
You could create a "nodgit" script (No Dot GIT) with somet like
您可以创建一个“nodgit”脚本(No Dot GIT),类似于
#!/bin/sh
gits=/usr/local/gits
x=`pwd`
testdir() {( cd ; 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 ([ "" = "nodinit" ]); then
mkdir -p "$GIT_DIR"
git init --bare; exit $?
elif ([ "" = "shell" ]); then
bash; exit $?
else
exec git "$@"
fi
fi
x=`testdir "$x/.."`
done
You can call nodgit in place of git and it will set variables as necessary by looking for a git repo. For example say you have a (bare) repo in /usr/local/gits/__home__foo_wibbles and you are in in /home/foo/wibbles/one then it will find the correct working directory (/home/foo/wibbles) and repo.
您可以调用 nodgit 代替 git,它会根据需要通过查找 git repo 来设置变量。例如,假设您在 /usr/local/gits/__home__foo_wibbles 中有一个(裸)repo,并且您在 /home/foo/wibbles/one 中,那么它将找到正确的工作目录(/home/foo/wibbles)和 repo .
Oh you can also use "nodgit shell" to get a shell with the correct vars set so you can use plain old git commands.
哦,您还可以使用“nodgit shell”来获取设置了正确 vars 的 shell,以便您可以使用普通的旧 git 命令。
回答by Abie
Assuming your myfiles
directories already exists and has some content, could you live with this:
假设你的myfiles
目录已经存在并且有一些内容,你能接受这个:
cd ~/backup
git init
git add myfiles
The .git
directory will be in backup
, not in myfiles
.
该.git
目录将在 中backup
,而不是在myfiles
.
回答by Krazy Glew
I create scripts that look like
我创建的脚本看起来像
~/bin/git-slash:
~/bin/git-slash:
#!/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 $?
It's redundant to use --git_dir=$GIT_DIR, but reminds me that I can also set environment variables outside the script.
使用 --git_dir=$GIT_DIR 是多余的,但提醒我我也可以在脚本之外设置环境变量。
The above example is for tracking local changes to cygwin system files.
上面的示例用于跟踪对 cygwin 系统文件的本地更改。
Can make one such script for any major project that needs this - but / without /.git is my main use.
可以为任何需要它的主要项目制作一个这样的脚本 - 但 / 没有 /.git 是我的主要用途。
The above is small enough to make a shell alias or function, if you eliminate the redundancy.
如果消除冗余,上面的内容足够小,可以制作外壳别名或函数。
If I do this often enough, I would revive the workspace to repository mapping of
如果我经常这样做,我会恢复工作区到存储库映射
"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System",
in Workshop Proceedings of the Software Management Conference. 1989.
whose closest modern counterpart is Perforce mappings or views, supporting partial checkouts as well as non-colocation of workspace and repo.
其最接近的现代对应物是Perforce 映射或视图,支持部分结帐以及工作区和存储库的非托管。