2

问题:如果该工作树不是裸露的,我如何将本地提交推送到我的开发服务器?

我的情况:

  1. 我在我的开发服务器上设置了 git,这样当我推送本地更改时,它们会被添加到一个分离的工作树中(如此处所述,很像这篇文章)。
  2. 然后我在开发服务器上运行 git 时遇到了问题(例如,git status),因为 git 找不到工作树。
  3. 我询问了 SO 并得到了我需要bare = false在我的配置文件中设置并指定工作树的提示。甜的。

但是现在当我尝试将我的提交推送到开发服务器时,我收到了这个错误:

$ git push origin master
xxxx@xxx.xxx.xxx.xxx's password:
Counting objects: 26, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 2.56 KiB, done.
Total 18 (delta 8), reused 0 (delta 0)

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

To ssh://xxxx@xxx.xxx.xxx.xxx/xxx/xxx/xxxxxx.git
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'ssh://xxxx@xxx.xxx.xxx.xxx/xxx/xxx/xxxxxx.git'

我看到这个其他用户有同样的问题。不幸的是,对他有用的解决方案是bare = true在他的配置中设置,这将重现我在上面第 3 步中遇到的问题。

错误消息说

您可以将“receive.denyCurrentBranch”配置变量设置为远程:错误:“忽略”或“警告”

就我而言,我可以这样做吗?这对我来说听起来不错,但我对 git 还不够熟悉,还没有意识到当它出现时是个坏主意......

编辑

为了清楚起见,我已经添加了一个 post-receive 钩子,它工作顺利。问题是我似乎必须在bare=true(并且能够推送到开发服务器)和bare=false(并且能够在开发服务器上运行 git 命令)之间进行选择。

4

4 回答 4

3

为什么不:

  • 将您的提交推送到一个裸仓库
  • 在该开发存储库上设置一个接收后挂钩,然后将其转到非裸开发存储库并检查正确的分支,从裸存储库中提取新提交?

这就是您的链接所描述的(使用分离的工作树),但它在一个裸仓库中设置了钩子:

$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
$ chmod +x hooks/post-receive
于 2012-06-05T18:54:58.030 回答
0

使用存储库不是您想要做的。您需要在您的开发服务器上的裸存储库中有一个接收后挂钩,该挂钩对您的 Web 服务器的目录执行 git checkout-index。这样,它只是文件。您不必担心它是否是一个裸存储库、是否有工作树或其他任何与 git 相关的东西。

类似的东西git checkout-index -f -a --prefix=/var/www/htdocs/mywebsite/(注意斜杠 - 这很重要)

-f 标志将强制覆盖任何现有文件,而 -a 标志将包括所有文件。

于 2012-06-05T19:10:21.700 回答
0

你只需要小心你正在尝试做的事情。

git status用于告诉您工作树的状态。这在您的情况下应该没有用。

另一方面,git push在裸存储库上完全有效。这应该适合你。

如果您想查看更改,可以使用 git diff。您只需要指定两个哈希git diff $oldref $newref

如果要列出在特定提交中更改的文件,请使用git show --pretty="format:" --name-only $newref.

如果要列出文件的内容,请使用git show $newref -- $filepath

于 2012-06-25T17:31:47.330 回答
0

我已经制定了一个可以接受但不太理想的解决方案。基本上,当我需要将开发更改推送到我的实时服务器时,我只是通过编辑我的配置文件来规避这个问题。

允许开发人员将本地更改推送到 dev 的配置文件:

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

将开发更改推送到实时时的配置文件:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        worktree = /var/www/example.com/httpd/

优点

  1. 作品
  2. 一旦我将配置文件更改为推送,repo 将被“锁定”,其他开发人员无法推送更改
  3. 这不是一个大问题,因为无论如何我都必须登录到 dev 来处理数据库迁移

缺点:基本上,如果我知道如何正确地完成它,我确信它可以自动化。

注意:我喜欢@vonC 的建议,即设置接收后挂钩以有条件地推送到实时服务器。对接收后挂钩进行更改很简单,但我不明白挂钩会响应什么触发器。不过我很想听听建议:)

于 2012-07-13T14:26:35.590 回答