【问题标题】:What is GIT_WORK_TREE, why have I never needed to set this ENV var, why now?什么是 GIT_WORK_TREE,为什么我从来不需要设置这个 ENV 变量,为什么是现在?
【发布时间】:2011-03-12 15:01:30
【问题描述】:

我在 Ubuntu Linux 下使用 Git 来同步和部署我的项目。

我的本​​地 Linux 工作机器上有一个存储库,我的服务器上有两个存储库,一个是裸存储库,一个是已部署的应用程序。

它一直运行良好,但现在我为我的其他网站创建了另一个 repo,但出现此错误:

root@vserver5:/var/www/ninethsky# git pull origin master
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.

所以我必须设置一个GIT_WORKING_TREE ENV-Var,但这究竟是什么,在哪里设置?

这是我的 repo 的 .git/config:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = /home/git/ninethsky/.git
        fetch = +refs/heads/*:refs/remotes/origin/*

在我的本地工作机器上有另一个带有bare = true 的仓库和一个仓库。

然后我删除了除了最初的所有 repos,现在我得到了:

root@vserver5:/var/www/ninethsky# git init
fatal: GIT_WORK_TREE (or --work-tree=<directory>) not allowed without specifying GIT_DIR (or --git-dir=<directory>)
root@vserver5:/var/www/ninethsky# git init --git-dir=/var/www/ninethsky
error: unknown option `git-dir=/var/www/ninethsky'

我通过取消设置 GIT_WORK_TREE(设置为空白)解决了 git init 问题。 GIT_WORK_TREEGIT_DIR 未设置。 git init 再次工作,git add . 仍然存在问题,当涉及到克隆存储库中的 git 操作时,它被设置为裸露。

谢谢, 乔恩。

【问题讨论】:

  • /var/www/ninethsky 是工作目录吗,即/var/www/ninethsky/.git 是否存在?还是/var/www/ninethsky 本身就是一个 git 目录?
  • /var/www/ninethsky/.git 存在
  • /var/www/ninethsky 中的其他 git 操作是否有效?例如git status 也会产生错误吗?当您收到该错误时,您是否设置了任何其他 git 环境变量? (env|egrep GIT)
  • @Joern Akkermann:我已经更新了我的答案以回应您的补充意见。
  • 仍然缺少的最关键信息是您在环境中设置的内容 - env|grep GIT 显示了什么?

标签: git


【解决方案1】:

如果你有一个非裸 git 存储库,它有两个部分:

  • 工作树。
    工作树包含您签出的源代码,以及您可能所做的任何更改。

  • git 目录。
    git 目录通常称为.git,位于工作树的顶层 - 它包含项目的所有历史记录、配置设置、指向分支的指针、索引(暂存区)等。
    您的 git 目录包含的文件和目录看起来有点像这样:

    branches description HEAD index logs ORIG_HEAD refs config FETCH_HEAD hooks info objects packed-refs


虽然我上面描述的是 git 存储库的默认布局,但您实际上可以将文件系统中的 any 目录设置为您的 git 目录和工作树。

您可以更改这些目录的默认设置

  • 使用--work-tree--git-dir 选项到git
  • 或使用GIT_DIRGIT_WORK_TREE 环境变量。但是,通常您不需要设置这些。

您看到的错误来自git pull 所做的第一次检查 - 它必须从工作树中运行。我认为这是由于您设置了 GIT_DIRGIT_WORK_TREE 环境变量。
否则,我最好的猜测是您的 .git 目录无法访问或以某种方式损坏。

  • 如果你列出/var/www/ninethsky/.git的内容,它看起来像我上面引用的列表吗?
  • 运行命令的用户是否可以读写所有这些文件和目录,或者他们的权限是否已更改?

更新:在回答附加信息中的要点时,您更新了问题:

  • git init 可能会失败,因为您仍然设置了 GIT_WORK_TREE 环境变量,并且如错误消息所述,如果您要指定工作树,则还必须指定 git 目录。
  • 第二个变体 (git init --git-dir=/var/www/ninethsky) 失败,因为 --git-dir 应该在 init 之前。

但是,在这种情况下,您根本不需要指定工作树1,因此我会确保您取消设置 GIT_WORK_TREEGIT_DIR 环境变量。

1 也就是说,将.git 目录保留在/var/www 下可能被认为是一个坏主意,以防您不小心设置了权限使其可通过网络访问。 因此,这可能是您希望将 git 目录保留在其他地方的实例。 但是,由于这些选项显然已经让您感到困惑,也许最好让 git 部分保持简单并通过其他方式拒绝访问 .git 目录。

【讨论】:

  • 你如何取消设置 GIT_WORK_TREE?
  • @Sisir:嗯,暂时(在 bash、dash 等中)使用unset GIT_WORK_TREE,但如果这是一个问题,那么它可能已在启动文件中设置(例如~/.bashrc)或一个包装脚本,所以你需要从那里删除设置。
  • 随着 git 2.5 中 git worktree 的发布,我认为应该谨慎使用 GIT_DIR 环境变量,您可能需要使用工作树中的 GIT_COMMON_DIR。这是发布此答案后发生的最新进展,值得一提。
【解决方案2】:

也许最好保持 git 部分简单,并通过其他方式拒绝访问 .git 目录。

You can use .htaccess to deny public access to the .git directory

【讨论】:

  • 既然创建符号链接如此简单,只需将公共和服务的 Web 目录指向公共目录下某处的存储库的构建文件,您为什么要这样做?
  • 因为这是关于已接受答案的最后一个建议,并且 crd23 发布了有关如何执行此操作的链接。 @crd23 可能应该更新其他帖子并将链接放在引用的文本下,但他们仍然是菜鸟,所以我们会原谅他们!
【解决方案3】:

如果您重命名了 git 子模块的路径(工作树),您也可能会遇到此错误。就我而言,我已经更新了.gitmodules 中的路径以匹配我的新路径并认为我很好。但是当我后来做了git pull 时,它在旧路径中添加了新文件。这是因为有两个地方定义了模块路径。您还需要更新 .git/modules/{modulename}/config 文件中定义的“工作树”。

【讨论】:

    猜你喜欢
    • 2014-10-28
    • 2011-10-04
    • 2010-12-08
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多