git post-receive钩子似乎不处理其他分支 [英] git post-receive hook doesn't seem to process other branches

查看:76
本文介绍了git post-receive钩子似乎不处理其他分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望你们的生活做得很棒.我不是git的专家,但是自从我开始使用它以来,我就非常喜欢它.

I hope you guys are doing wonderful in your lives. I am not very expert with git but I love it very very much ever since I started using it.

我在客户端服务器上有两个存储库,分别是live.gitbeta.git,并且通过遵循Internet上的一些教程,我能够设置钩子(接收后),以创建文件的工作目录(以//beta/目录).该项目是一个Web应用程序,因此每当我进行更改时,我都将其推送到存储库中,并且接收后挂钩会更新工作目录中的文件.

I have two repositories on my client's server namely live.git and beta.git and by following some tutorials on the internet I was able to setup hooks, post-receive one, to create a working directory for the files (to / and /beta/ directories respectively). The project is a web app so whenever I make changes I simply push them to the repositories and the post-receive hook updates the files in the working directory.

问题是我最近创建了一个新分支(称为Angular),现在创建了一个分支

The issue is I recently created a new branch (called Angular) and now if I do

git push beta Angular 

它确实将更新推送到存储库,但是现在工作目录不受影响.工作目录仍显示master分支中的更改.

It does push the updates to the repository, but now the working directory is not affected. The working directory still shows the changes from the master branch.

这些是我的接收后挂钩的内容:

These are the contents of my post-receive hook:

#!/bin/sh
echo "Performing post-receive actions on beta.."
git --work-tree=/home/webapp/public_html/beta --git-dir=/home/webapp/public_html/beta.git checkout -f

我在这里看不到任何关于master或分支的信息,这就是为什么我什至无法在这里尝试其他东西的原因.

I do not see any mention of master or any branch here that's why I am unable to even try something different here.

有人可以帮助我了解如何制作该文件,以便无论推送哪个分支,它都只会根据推送的最后一个分支来更新工作目录中的文件?

Can someone please help me understand how can I make it so that no matter which branch is pushed, it simply updates the files in the working directory based on the last branch that was pushed?

提前谢谢大家,并抽出宝贵的时间.

Thank you all in advance and for your time.

修改: 我的问题是:

1)为什么要处理我默认的master分支?

1) Why does it process master branch my default?

2)是否有任何配置指定默认情况下仅使用git --work-tree命令仅处理master分支的地方?

2) Is there any config that specifies somewhere that only master branch is processed by default with the git --work-tree command?

3)是否仍然可以硬编码要写入work-tree的哪个分支?因为我大概只会总是将分支推到beta.git上,将另一个分支推到live.git上.

3) Is there anyway to perhaps hardcode which branch to write to the work-tree? Because I will probably only push on branch to the beta.git and another branch to the live.git almost always.

推荐答案

有人可以帮助我了解如何制作该文件,以便无论推送哪个分支,它都只会根据推送的最后一个分支来更新工作目录中的文件?

Can someone please help me understand how can I make it so that no matter which branch is pushed, it simply updates the files in the working directory based on the last branch that was pushed?

如果我跑步怎么办?例如:

What if I run, e.g.:

git push origin branch1 branch2 branch3

?假设我只用一次推送就更新了三个分支,您想部署哪个分支?

? Which branch do you want deployed, given that I just updated three branches with a single push?

无论如何,答案有点复杂.其中的一部分非常容易:任何接收后钩子都可以而且最应该从标准输入中读取每行.如 the githooks手册中所述,每一行都充当指令. .输入格式与 -接收钩子,因此也请阅读该部分.

In any case, the answer is a little bit complicated. Part of it is very easy: any post-receive hook can, and most should, read each line from the standard input. Each such line acts as a directive, as documented in the githooks manual. The input format is the same as for the pre-receive hook, so read that section as well.

您可以通过 Google搜索找到许多接收后部署挂钩,但其中许多损坏了-有些微妙了.我检查的前三个都是错误的:一个有您遇到的相同问题(不读取stdin),两个读取了stdin但检查了结尾 master的引用,这意味着如果我这样做了:

You can find many post-receive deployment hooks through google search, but many of them are broken—some a bit subtly. The first three I checked were all wrong: one had the same issue yours does (not reading stdin), and two read stdin but checked for references ending in master, which means that if I did:

git push origin sneaky/master

他们会将我的分支sneaky/master视为常规的旧master分支.此外,任何引用(包括标签)以master命名或结尾都将执行相同的操作.当然,创建一个名为master的标签通常很邪恶,但是为什么要草率?拥有refs/notes/master是非常合理的,而且还会破坏这些部署脚本.

they would treat my branch sneaky/master as if it were the regular old master branch. Moreover, any reference, including a tag, named or ending with master would do the same thing. Of course, it's generally pretty evil to create a tag named master, but why be sloppy? Having a refs/notes/master would be quite reasonable and would also break these deployment scripts.

修复 也不困难:只需确保引用名称​​以 refs/heads/开头,并且继续以您期望的结尾分店名称.例如:

Fixing that is not difficult either: simply make sure the reference name begins with refs/heads/ and goes on to conclude with your desired branch name. For instance:

while read ohash nhash refname; do
    case "$refname" in
    refs/heads/master) deploy master $ohash $nhash;;
    refs/heads/test?) deploy ${refname#refs/heads/} $ohash $nhash;;
    # ignore all others
    esac
done

(其中deploy是适当的shell函数).

(where deploy is an appropriate shell function).

但是,如果您只想要 last 分支(忽略标签和注释),则:

If you really want just the last branch (ignoring tags and notes), though:

update=  # by default, nothing
while read ohash nhash refname; do
    case "$refname" in
    refs/heads/*) update=$nhash;;
    # ignore all others
    esac
done
if [ -n "$update" ]; then deploybyhash $update; fi

其中"deploybyhash"做明显的事情. (这是一件奇怪的事情,我留给您实施它,并弄清何时是一个特别糟糕的主意;请参阅下一个部署示例.)

where "deploybyhash" does the obvious thing. (This is such an odd thing to want, that I leave it to you to implement it—and to figure out when it's an especially bad idea; see the next deploy example.)

真正棘手的部分是良好的多分支部署功能.这是未经测试的,但可能是正确的:

The really tricky part is a good multi-branch deployment function. This one is quite untested, but probably correct:

# deploy - deploy a branch to a per-branch deployment area
# arguments: $1 - branch name, $2 - old hash, $3 - new hash
deploy() {
    local branch=$1 ohash=$2 nhash=$3 op tree

    if expr $ohash : '00*$' >/dev/null; then
        op=create
    elif expr $nhash : '00*$' >/dev/null; then
        op=delete
    else
        op=update
    fi
    # if creating or deleting a branch, probably should
    # not do anything here
    if [ $op != update ]; then
        echo $op branch $branch - no deployment action
        return
    fi
    # check whether there's a place to deploy this branch
    tree=/path/for/deployment/$branch
    if [ -d $tree ]; then
        # set up a per-branch index, except maybe for master
        # (this does it for all deployed branches)
        export GIT_INDEX_FILE="$GIT_DIR/index.$branch"
        # if there's no index yet, create it from the tree
        [ -f "$GIT_INDEX_FILE" ] || git --work-tree=$tree reset
        # and check out the appropriate commit w/o changing HEAD
        git --work-tree=$tree read-tree --reset -u $nhash
        unset GIT_INDEX_FILE # clean up after ourselves
    else
        echo "deployment tree $tree is missing, not checking it out"
    fi
}

它可以做得更好,但是可以做到以下关键项目:

It could be made substantially fancier, but it does the key items:

  • 当然,我们需要多个部署区域($tree).
  • 由于存在多个部署分支,因此我们必须使用多个索引文件,否则每次都将重建索引.此代码在每个部署区域($GIT_INDEX_FILE)使用一个索引.
  • 在更新非master树时,最好不要更改HEAD,因此我们避免使用git checkout.使用git read-tree --reset -u从指定的提交哈希值更新索引和工作树.
  • 如果分支本身刚刚被删除,我们将无法检出任何内容.如果刚刚创建它,那可能没问题:这是您可能需要调整的东西.例如,您可能要为此情况创建树.为此,您可能想要在分支删除时删除部署树.这样做的地方和方法应该很明显.
  • Of course, we need multiple deployment areas ($tree).
  • Since there is more than one deployment branch, we must use more than one index file, or otherwise rebuild the index every time. This code uses one index per deployment area ($GIT_INDEX_FILE).
  • It's probably best not to alter HEAD when updating a non-master tree, so we avoid git checkout. Using git read-tree --reset -u updates our index and work tree from the specified commit hash.
  • If the branch itself has just been deleted, we cannot check anything out. If it has just been created, that might be OK: this is something you may want to tune. You might want to create the tree for this case, for instance. You might want to delete the deployment tree on branch deletion, for that matter. The places and ways to do this should be obvious.

这篇关于git post-receive钩子似乎不处理其他分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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