我可以将.git文件夹存储在我想要跟踪的文件之外吗?

Ror*_*ory 139 git

我有一个不寻常的想法,使用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
Run Code Online (Sandbox Code Playgroud)

您可以看到我到达的错误消息.我究竟做错了什么?

nik*_*iks 166

您只需要确保存储库知道工作树的位置,反之亦然.

要让存储库知道工作树的位置,请设置配置值core.worktree.要让工作树知道它的git目录在哪里,添加一个名为.git的文件(不是文件夹!)并添加一行像

gitdir: /path/to/repo.git
Run Code Online (Sandbox Code Playgroud)

从git 1.7.5开始,init命令为此学习了一个额外的选项.

您可以使用初始化新的单独存储库

git init --separate-git-dir /path/to/repo.git
Run Code Online (Sandbox Code Playgroud)

这将在单独的目录中初始化git存储库,并将.git文件添加到当前目录中,该目录是新存储库的工作目录.

在1.7.5之前,您必须使用稍微不同的参数并自行添加.git文件.

要初始化单独的存储库,以下命令将工作树与存储库链接:

git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git
Run Code Online (Sandbox Code Playgroud)

您当前的目录将是工作树,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"
Run Code Online (Sandbox Code Playgroud)

在只读工作目录上使用git版本控制

根据上述知识,您甚至可以为工作目录设置git版本控制,而无需具有写入权限.如果您--git-dir在每个git命令上使用或从存储库(而不是工作目录)中执行每个命令,则可以省略.git文件,因此不需要在工作目录中创建任何文件.另见青少狮答案

  • 您也可以对现有的repo执行此操作:将.git文件夹移动到您想要的位置,添加.git文件以指向它,然后您可以像往常一样继续使用repo (7认同)
  • 解决这个问题的方法是在实际的git配置文件中指定'core.worktree',即你在.git中指向的文件夹中的那个. (2认同)
  • 是的,这就是我在答案第二句中描述的内容.配置值`core.worktree`当然存储在.git文件夹的配置文件中,.git文件指向的位置. (2认同)

Bom*_*mbe 99

git --git-dir=../repo --work-tree=. add foo
Run Code Online (Sandbox Code Playgroud)

这将做你想要的,但是当你必须用你曾经使用的每个git命令指定它时,显然会很糟糕.

你可以导出GIT_WORK_TREE=.,GIT_DIR=../backupGit会在每个命令中选择它们.但是,这只会让您轻松地在每个shell的单个存储库中工作.

我宁愿建议将.git目录符号链接到其他地方,或者从主备份目录创建.git目录的符号链接.

  • 此外,如果OP在他的工作树中不想要一个.git子目录,为什么他想要一个符号链接? (2认同)

小智 58

(和)的--separate-git-dir选项可用于在我的git()版本上完成此操作.该选项将git存储库与工作树分开,并在工作树的根目录中创建与文件系统无关的git符号链接(以文件名的形式).我认为结果与niks的答案相同.git initgit clone1.7.11.3.git

git init --separate-git-dir path/to/repo.git path/to/worktree
Run Code Online (Sandbox Code Playgroud)

  • +1使用`init`命令行选项本身看起来更清晰,更清晰 (2认同)

Leo*_*Leo 24

我发现在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
        ...
Run Code Online (Sandbox Code Playgroud)

这种方法有两个优点:

  • 它不需要任何命令行选项或.git文件.您只需从存储库的根目录中正常运行即可.
  • 它允许您即使您不拥有文件系统也可以对其进行版本控制.Git只会写入存储库位置.

我遇到的唯一警告是.gitignore,您可以编辑而不是使用文件info/exclude.

然后,read_only_repos/foo即使原始文件不受版本控制,您也可以将存储库用作您自己的存储库中的远程存储库.

  • 我喜欢这个 - 它允许我在我与Dropbox共享的目录上使用git,而其他参与者甚至不知道git正在使用中. (3认同)
  • 你说对了.关键是在工作目录之外创建repo. (2认同)

CB *_*ley 18

通常命名一个git存储库的目录,该存储库的工作树位于一个带有".git"扩展名的不寻常的地方,就像一个裸存储库.

mkdir ../git_repos/myfiles.git
Run Code Online (Sandbox Code Playgroud)

如果您--work-tree在初始化时提供了该选项,那么这将自动设置core.worktree配置变量,这意味着一旦您指定git目录,git就会知道在哪里可以找到工作树.

git --git-dir=../git_repos/myfiles.git --work-tree=. init
Run Code Online (Sandbox Code Playgroud)

但是你也可以在事后设置这个变量.

git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"
Run Code Online (Sandbox Code Playgroud)

完成此操作后,add命令应该按预期工作.

git --git-dir=../git_repos/myfiles.git add foo
Run Code Online (Sandbox Code Playgroud)


To1*_*1ne 6

git在仓库内使用:

cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false
Run Code Online (Sandbox Code Playgroud)

从现在开始,您可以git./backup/git_repos/myfiles目录内部使用,而无需设置任何环境变量或其他参数。