git缺少工作树

时间:2013-03-27 18:30:37

标签: git workflow

我收到“[远程拒绝]主分支当前已签出”错误 - 与此帖子中的OP(Git push error '[remote rejected] master -> master (branch is currently checked out)')基本相同的问题,以下是我到目前为止所做的修复它,但现在似乎我可以选择上述问题或新问题 - “缺少工作树”错误,如下所述,这是我目前陷入困境的地方。

请注意,我的要求与其他问题不同。我不想要两个repos,一个裸机和一个非裸机 - 只需要单个仓库(原始/远程),本地机器将从中拉动/推送代码 - 这是一个实时Web服务器。另一篇文章没有在这些方面指定任何要求(这个选项没有在那里解决),但我的需求非常具体,因此这个问题。

另请注意,有时可能会对服务器上的此目录文件进行直接编辑(尽管仍使用Git),而不是从本地工作站推送到服务器(远程)。

首先我重置repo,将其设置为bare(最初在服务器上设置Git的开发人员在设置repo时仅使用git init命令):

    git init --bare    

然后,因为我的所有服务器文件都已经存在(它不是一个空目录),我通过这种方法(通常)进行了初始提交:

    git add .
    git commit -m "initial commit"

然后我编辑了.git/config文件:

    git config receive.denyCurrentBranch ignore    

我当前的服务器.git/config文件如下所示:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true

[receive]
        denyCurrentBranch = false

我能够成功推送提交,但是如果我尝试然后应用它:

    git checkout -f

如上所述(可能接受所有提交并重置HEAD以包含我的所有更改?),我收到以下致命错误:

    fatal: This operation must be run in a work tree

我是否需要将工作树设置为此目录?如果是这样,我该怎么做?如果我这样做,结果仍然符合我的既定目标(同样,没有单独的裸露和非裸露的回购 - 只有单个目录,它也是服务于实时网站并位于Web根目录中) ?

我还有什么需要做的吗?

我已经在这个主题的stackoverflow上广泛阅读,包括: Git init --bare - Not Working on working tree fatal: This operation must be run in a work tree Difference between HEAD / Working Tree / Index in Git Pro-Git书(特此在这里:http://git-scm.com/book/ch2-2.html) Git-Flow(nvie):http://nvie.com/posts/a-successful-git-branching-model/

所有帮助和评论都非常感谢。谢谢!

1 个答案:

答案 0 :(得分:3)

您已经创建了一个裸git存储库(它本身没有工作树)。当您想推送更改时,建议使用裸git存储库。

根据您的问题,我了解您有某种服务器设置,每次执行git push时,您都希望更新服务器上的文件以反映新推送的更改。

是的,它是可行的,但你需要分开裸仓库和工作树。工作树位置应对应于您需要在服务器上部署文件的位置。我们假设它是/foor/bar。通过设置post-receive挂钩,您可以在每次推送后自动将新文件部署到此工作树位置。

以下是此设置的步骤:

  1. 如果工作树目录不存在,则创建它。

    mkdir -p /foo/bar
    
  2. 创建以下脚本并将其复制为bare-repo的hooks/post-receive

    #! /bin/sh
    GIT_WORK_TREE=/foo/bar git checkout -f
    
  3. 将此脚本标记为可执行文件:

    chmod +x hooks/post-receive
    
  4. 这就是所需要的。现在尝试git push,您的新更改将自动部署到/foo/bar位置。

    请注意: git checkout -f删除任何跟踪文件中的所有本地更改,/foo/bar中的任何此类更改都将丢失在新checkout -f上}。任何未在git中跟踪但在/foo/bar下创建/生成的文件都不应受到影响。

    另外,我建议您删除.git/config中所做的更改,尤其是receive.denyCurrentBranch

    您的配置应该如下所示:

    [core]
        repositoryformatversion = 0
        filemode = true
        bare = true
        logallrefupdates = true