Git Hooks收到后不按预期工作

时间:2017-07-20 10:45:58

标签: git bitbucket

我在服务器上设置了一个git repo,在/var/repo/app.example.com.git目录上运行git init --bare并添加代码为

的post-receive文件
#!/bin/bash
git --work-tree=/var/www/app.example.com --git-dir=/var/repo/app.example.com.git checkout -f

然后做

sudo chmod +x post-receive

然后在我的本地回购中添加了一个远程

git remote add deploy-dev ssh://user@serverip/var/repo/app.example.com.git

当我第一次运行它时效果很好。

git push deploy-dev dev

我在开发分支上添加了更改然后我推送开发。

git push -u origin dev

成功推送开发分支后我运行

git push deploy-dev dev

它没有应用我对dev分支的最后一次推送

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

概率为99.997%,问题是您要结帐master,而不是dev

每个存储库都有自己的当前分支

所有Git存储库(包括服务器上的存储库)都包含以下部分:

  • 存储库数据库本身,它为refs/heads/master分支存储master之类的对象和引用;
  • HEAD,存储当前分支;
  • index ,您可以在其中构建下一个提交;和
  • 一个可选的工作树,这是您工作的地方。

--bare存储库,core.bare配置为true的存储库,省略了工作树,但您可以暂时设置一个。)

当前分支一如既往地存储在HEAD中。

bare 存储库中,索引没有直接使用:因为索引的主要用途是将它与工作树一起使用来构建 next 提交要创建,并且裸存储库没有工作树,除非你编写一个post-receive部署脚本,否则它的索引不会运行。

想想当前的分支

你的post-receive挂钩,只是一行,非常简单:这意味着每次服务器都有东西 - 可能是一个新的标签 - 例如推送到它,它运行一行命令:< / p>

git --work-tree=/var/www/app.example.com \
    --git-dir=/var/repo/app.example.com.git \
    checkout -f

(为了显示/讨论目的,我将一行分成三行)。想想这些部分的作用:

--work-tree=...

分配工作树,以便您的git命令在该路径上作为其工作树工作。这会覆盖任何core.bare设置:生成的Git命令具有工作树。下一个:

--git-dir=...

这将覆盖查找Git目录的默认方法。它将在给定的存储库中运行,无论$GIT_DIR设置为什么,并且无论它在启动时实际运行在哪个目录中。

checkout -f

您应该熟悉此命令。它做了什么?

您已经知道git checkout检出分支。 -f选项(可以拼写为--force)告诉Git,即使结帐会覆盖未保存的工作树文件,它也应该继续并覆盖它们。但是:这个检查的分支是什么?

The git checkout documentation有一些可读性问题,但 包含答案:

  

git checkout &lt; branch&gt;

     
    要准备处理&lt; branch&gt;,请通过更新工作树中的索引和文件,并将HEAD指向分支来切换到它。保留对工作树中文件的本地修改,以便可以将它们提交到&lt; branch&gt;   ...
      您可以省略&lt; branch&gt;,在这种情况下命令退化为“检出当前分支” ...

(粗体我的)。

如果您打算部署某个特定分支,那么最好是当前分支,如果您使用此git checkout形式。

请注意,git checkout 也取决于当前索引:它假定当前索引在某种意义上描述了当前工作树。这就是索引也被称为缓存的原因。 Git在索引中缓存关于工作树的信息,并使用它来避免仔细查看工作树,如果可以的话。这是Git的速度秘密之一:通过比较一些有关工作树的快速查找信息和存储在类缓存索引中的一些快速查找信息,Git可以跳过一些 slow 工作树上的操作。

如果你使用--work-tree=从Git下面交换工作树,那么索引最好现在描述这个工作树,而不是其他的。如果您的接收后部署脚本始终使用单个工作树并始终从裸存储库进行部署,那就没问题,但如果没有,则不是。

还有其他更好的方式来进行具有不同或没有限制的Git部署,但这里的主要内容是:

  • 仅在裸存储库中使用此功能。
  • 仅使用一个--work-tree参数。如果您需要更多,请使用更高级的部署脚本。
  • 请记住,无论推送什么内容,都会部署当前分支。如果您需要不同的东西,请不要使用此部署脚本。如果只有一个分支要部署,请在运行此部署脚本之前作为当前分支,或者修改此部署脚本以将git checkout <branch-name>读取到 make 每个部署期间的当前分支。 (无论哪种方式,你现在都坚持使用它作为底层存储库的当前分支,所以确保 也可以!)

答案 1 :(得分:0)

让我解释一下你在做什么: 首先,您为远程分支deploy-dev添加了一个远程URL。然后,您将本地分支dev推送到远程分支deploy-dev

然后你犯了一个错误:

  

git push -u origin dev

git push -u origin <branch>表示您将当前分支dev推送到名为dev的远程分支。之前您将远程分支命名为deploy-dev。所以我想当你运行git fetch --all时,你会看到2个远程分支。

并提供您的信息: 如果添加了远程URL,则将远程分支设置为本地分支的上游。您最后只是检查您是否在正确的分支上并且可以使用git push