git缺少工作树 [英] git missing work tree

查看:183
本文介绍了git缺少工作树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到[远程拒绝]主分支目前检出错误 - 基本上与本文中的OP相同的问题( Git push error'[remote rejected] master - > master(branch is currently checked out)'),以下是我迄今为止所做的修复它的方法,但现在看起来我可以选择是否有上述问题或新的问题 - 缺少工作树错误,如下所述,这是我目前卡住的地方。



另请注意,我有与另一个问题不同的要求。我不想要两个仓库,一个仓库和一个非仓库 - 只有单个仓库(起源/远程仓库),本地机器将从中抽取/推送代码 - 这是一个实时Web服务器。另一篇文章没有具体说明这方面的任何要求(这个选项并没有在那里讨论),但是我的需求是非常具体的,因此这个问题。

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


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

  git init --bare 

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

  git add。 
git commit -minitial commit

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

  git config receive.denyCurrentBranch忽略

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

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

[receive]
denyCurrentBranch = false

我能够成功推送提交,但是如果我尝试应用这个:

  git checkout -f 

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

 致命:该操作必须在工作树中运行

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



有什么我需要做的,我失踪了?



我已经广泛阅读了stackoverflow关于这个主题,包括:
Git init --bare - 不工作在工作树上
致命的:此操作必须在工作树中运行
HEAD / Working Tree / Git中的索引之间的区别
Pro-Git书(特别是这里: http://git-scm.com/book/ch2-2.html
Git-Flow(nvie): http://nvie.com / posts / a-successful-git-branchching-model /



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

解决方案

你已经创建了一个纯粹的git仓库(它本身没有工作树)。当你想推送更改时,推荐使用一个纯粹的git存储库。



从你的问题中,我知道你有某种服务器设置,并且每次你做一个 git push ,你希望服务器上的文件被更新以反映新推送的更改。



是的,它是可行的,但你需要分开裸回购和工作树。工作树位置应与您的文件需要在服务器上部署的位置相对应。假设它是 / foor / bar 。通过设置接收后挂接,您可以在每次自动推送后将新文件部署到此工作树位置。



以下是此设置的步骤: 创建如果它尚不存在,工作树目录。

  mkdir -p / foo / bar 
  • 创建以下脚本并将其复制为裸回购的挂钩/ post-receive

     #! / bin / sh 
    GIT_WORK_TREE = / foo / bar git checkout -f


  • 将此脚本标记为可执行文件:

      chmod + x hooks / post-receive 


  • 这就是所有需要的。现在尝试一下 git push ,你的新改动将自动部署到 / foo / bar 位置。



    注意:> git checkout -f 在任何被跟踪的文件中在 / foo / bar 中的任何这样的更改将在新的结帐-f 中丢失。任何未在git中跟踪但在 / foo / bar 下创建/生成的文件都不应受到影响。



    另外我会建议摆脱你在 .git / config 中所做的更改,尤其是对于 receive.denyCurrentBranch

    你的配置应该看起来像这样IMO:

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


    I am receiving the "[remote rejected] master branch is currently checked out" error - essentially the same problem as the OP at this post (Git push error '[remote rejected] master -> master (branch is currently checked out)'), and following is what I have done so far to fix it, but now it seems I have a choice between having the above-stated problem or a new one - the "missing work-tree" error, and as explained below, this is where I am currently stuck.

    Please also note that I have a different requirement than the other question. I do NOT want two repos, one bare and one non-bare - just the single repo (origin/remote), from which the local machines will be pulling/pushing code - and which is a live web server. The other post did not specify any requirement along these lines (and this option was not addressed there), but my needs are very specific, hence this question.

    Also note that it is unavoidable that sometimes there may be direct edits to this directory's files on the server (albeit still using Git), rather than being pushed from a local workstation to the server (remote).

    First I reset the repo, setting it to to bare (the developer who originally set Git up on the server only used the git init command when he set up the repo):

        git init --bare    
    

    Then, because all my server files were already present (it is not an empty directory), I did an initial commit, by this method (the usual):

        git add .
        git commit -m "initial commit"
    

    Then I edited the .git/config file thusly:

        git config receive.denyCurrentBranch ignore    
    

    My current server .git/config file looks like this:

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

    I am able to push commits successfully, BUT if I try to then apply this:

        git checkout -f
    

    as suggested above (presumably to accept all the commits and reset the HEAD to include all my changes?), I receive the following fatal error:

        fatal: This operation must be run in a work tree
    

    Do I need to set the worktree to this directory? If so, how do I do that? And if I do that, will the result still be in keeping with my stated goal (again, no separate bare and non-bare repos - just the single directory, which is ALSO serving a live web site and is located in the web root)?

    Is there anything else I need to do that I am missing?

    I have read widely on stackoverflow on this topic, including: 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 The Pro-Git book (esp here: http://git-scm.com/book/ch2-2.html) Git-Flow (nvie): http://nvie.com/posts/a-successful-git-branching-model/

    All help and comments greatly appreciated. Thank you!

    解决方案

    You've created a bare git repository (which does not by itself have a working tree). A bare git repository is the recommended way to go when you want to push changes.

    And from your question, I understand that you have some sort of server setup, and everytime you do a git push, you want the files on the server to be updated to reflect the newly pushed changes.

    Yes it is do-able, but you need to separate the bare repo and work-tree. The work-tree location should correspond to the location where your files need to be deployed on the server. Let's just assume it is /foor/bar. By setting up a post-receive hook, you can deploy the new files to this worktree location, after every push automatically.

    These are the steps for this setup:

    1. Create the work-tree directory if it does not exist already.

      mkdir -p /foo/bar
      

    2. Create the following script and copy it in as bare-repo's hooks/post-receive

      #! /bin/sh
      GIT_WORK_TREE=/foo/bar git checkout -f
      

    3. Mark this script as executable:

      chmod +x hooks/post-receive
      

    That's all that will be required. Now try a git push and your new changes will be automatically deployed onto /foo/bar location.

    A note of caution: git checkout -f clobbers all local changes in any of the tracked files and any such changes in /foo/bar will be lost on a new checkout -f. Any files that are not tracked in git but created/generated under /foo/bar, should not be affected.

    Also I would suggest to get rid of the changes you've made in the .git/config, especially for receive.denyCurrentBranch.

    Your config should look like this IMO:

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

    这篇关于git缺少工作树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆