git 什么是 GIT_WORK_TREE,为什么我从来不需要设置这个 ENV 变量,为什么现在?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5283262/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:20:32  来源:igfitidea点击:

What is GIT_WORK_TREE, why have I never needed to set this ENV var, why now?

git

提问by Joern Akkermann

I'm using Git under Ubuntu Linux to sync and deploy my projects.

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

I have Repo on my local Linux working machine and two repos on my server, one bare repo and the one as a deployed app.

我在我的本地 Linux 工作机器上有 Repo,在我的服务器上有两个 repo,一个是裸仓库,一个作为部署的应用程序。

It always worked fine, but now I created another repo for my other website and now I get this error:

它总是工作正常,但现在我为我的另一个网站创建了另一个 repo,现在我收到了这个错误:

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

So I have to set a GIT_WORKING_TREE ENV-Var, but what is this exactly, where to set it?

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

This is my repo's .git/config:

这是我的 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/*

There is another repo with bare = trueand a repo on my local working machine.

bare = true在我的本地工作机器上还有另一个 repo和一个 repo。

Then I removed all the repos, but the initial one, now I get:

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

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'

I solved the git initproblem by unsetting GIT_WORK_TREE, which was set to blank. GIT_WORK_TREE and GIT_DIR are unset. git initworks again, still there is a problem with git add .and so on when it comes to git actions in the cloned repo, which was set to bare.

git init通过取消设置为空白的 GIT_WORK_TREE解决了这个问题。GIT_WORK_TREE 和 GIT_DIR 未设置。git init再次工作,git add .当涉及到克隆的 repo 中的 git 操作时,仍然存在问题,等等,它被设置为裸。

Thanks, Joern.

谢谢,乔恩。

回答by Mark Longair

If you have a non-bare git repository, there are two parts to it: the git directory and the working tree. The working tree has your checked out source code, with any changes you might have made. The git directory is normally called .git, and is in the top level of your working tree - this contains all the history of your project, configuration settings, pointers to branches, the index (staging area) and so on. Your git directory is the one that contains files and directories that look like a bit like this:

如果您有一个非裸 git 存储库,它有两个部分:git 目录和工作树。工作树包含您检出的源代码,以及您可能进行的任何更改。git 目录通常称为.git,位于工作树的顶层 - 这包含项目的所有历史记录、配置设置、指向分支的指针、索引(暂存区)等。你的 git 目录是包含文件和目录的目录,看起来有点像这样:

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

While what I've described above is the default layout of a git repository, you can actually set anydirectories in the filesystem to be your git directory and working tree. You can change these directories from their defaults either with the --work-treeand --git-diroptions to gitor by using the GIT_DIRand GIT_WORK_TREEenvironment variables. Usually, however, you shouldn't need to set these.

虽然我上面描述的是 git 存储库的默认布局,但您实际上可以将文件系统中的任何目录设置为您的 git 目录和工作树。您可以使用--work-treeand--git-dir选项git或使用GIT_DIRandGIT_WORK_TREE环境变量将这些目录从它们的默认值更改。但是,通常您不需要设置这些。

The error that you see is from one of the first checks that git pulldoes - it must be run from a working tree. I assume that this is due to you having set the GIT_DIRor GIT_WORK_TREEenvironment variables. Otherwise, my best guess is that your .gitdirectory is not accessible or corrupted in some way. If you list the contents of /var/www/ninethsky/.git, does it look like the listing I quoted above? Are all of those files and directories readable and writable by the user you're running the command as, or might they have had their permissions changed?

您看到的错误来自执行的第一个检查git pull- 它必须从工作树运行。我认为这是由于您设置了GIT_DIRGIT_WORK_TREE环境变量。否则,我最好的猜测是您的.git目录无法访问或以某种方式损坏。如果列出 的内容/var/www/ninethsky/.git,它看起来像我上面引用的列表吗?您运行命令的用户是否可以读取和写入所有这些文件和目录,或者他们的权限是否已更改?



Update:In answer to the points in the additional information you updated your question with:

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

  • git initpresumably fails because you still have the GIT_WORK_TREEenvironment variable set, and, as the error message says, if you're specifying the work tree, you also have to specify the git directory.
  • The second variant (git init --git-dir=/var/www/ninethsky) fails because the --git-dirshould come before the init.
  • git init可能会失败,因为您仍然设置了GIT_WORK_TREE环境变量,并且如错误消息所述,如果您指定工作树,则还必须指定 git 目录。
  • 第二个变体 ( git init --git-dir=/var/www/ninethsky) 失败,因为--git-dir应该出现在 之前init

However, in this situation, you don't need to specify the work tree at all, 1so I would make sure that you unsetthe GIT_WORK_TREEand GIT_DIRenvironment variables.

然而,在这种情况下,你并不需要在所有指定的工作树,1所以我想确保你取消设置GIT_WORK_TREEGIT_DIR环境变量。

1That said, it could be considered a bad idea to keep your .gitdirectory under /var/wwwin case you accidentally set the permissions such that it is web accessible, so this might be an instance where you want to keep the git directory elsewhere - however, since these options are clearly already causing confusion for you, perhaps it's better to keep the git part simple and deny access to the .gitdirectory with other means.

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

回答by crd23

Perhaps it's better to keep the git part simple and deny access to the .git directory with other means.

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

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

您可以使用 .htaccess 拒绝对 .git 目录的公共访问

回答by Code Commander

You may also run into this error if you've renamed the path (working-tree) of a git submodule. In my case I had updated the path in .gitmodulesto match my new path and thought I was good. But when I did a git pulllater it added new files in the old path. This is because there are two places the module path is defined. You need to also update your "working-tree" as defined in the .git/modules/{modulename}/configfile.

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