2017-03-26 40 views
0

我希望你们在你的生活中做得很棒。我并不擅长git,但自从我开始使用它以来,我非常喜欢它。git post-receive hook似乎没有处理其他分支

我有我的客户的服务器即live.gitbeta.git上,并通过互联网我能够设置挂钩,对以下一些教程两个储存后收到,以创建文件(工作目录//beta/目录分别)。该项目是一个Web应用程序,所以无论我何时进行更改,只需将它们推送到存储库,并且post-receive挂钩将更新工作目录中的文件。

的问题是我最近建立了一个新的分支(称为Angular),现在如果我做

git push beta Angular 

它推更新到资料库,但现在的工作目录不受影响。工作目录仍显示master分支的更改。

这是我的后收到钩的内容:

#!/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提及或任何分支机构这里,这就是为什么我不能,甚至尝试一些不同的东西在这里。

有人可以帮我理解我该如何做到这一点,以便不管哪个分支被推送,它只是根据推送的最后一个分支更新工作目录中的文件?

谢谢大家提前和你的时间。

编辑: 我的问题是:

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

2)是否有任何配置指定只有master分支默认使用git --work-tree命令进行处理?

3)有无论如何硬编码写入work-tree的分支?因为我几乎总是可能只推送分支到beta.git和另一个分支到live.git

回答

0

是否有人可以帮助我了解我怎样才能让这个无论哪个分支被按下时,它只是更新推基于过去的分支工作目录中的文件?

如果我跑,例如:

git push origin branch1 branch2 branch3 

?你想部署哪个分支,因为我只用一次更新就更新了三个分支?

无论如何,答案有点复杂。部分很容易:任何后接收钩可以,最应该从标准输入读取每行。每条这样的线路都起着指导作用,如the githooks manual所述。输入格式与the pre-receive hook相同,所以请阅读该部分。

您可以通过google search找到许多post-receive部署挂钩,但其中很多已被破坏 - 有些微妙。前三个我检查都错了:一个能有你不(不读标准输入)相同的问题,和两个读标准输入,但检查的参考master结束,这意味着,如果我这样做:

git push origin sneaky/master 

他们会把我的分支sneaky/master看作是正常的旧的master分支。此外,任何参考,包括一个标记,以master命名或结尾将做同样的事情。当然,创建一个名为master的标签通常是非常邪恶的,但为什么要马虎?有一个refs/notes/master将是非常合理的,也将打破这些部署脚本。

固定也不困难:只需确保引用名refs/heads/继续与您想要的分支名结束的开始。例如:

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函数)。

如果你真的想只是最后分支(忽略标签和注释),但:

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” 做了明显的事情。 (这是这样一个事情想,那我让你实现它,并找出当它是一个特别糟糕的想法;看到未来部署的例子。)

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

# 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 
} 

它可以由基本票友,但它的主要项目:

  • 当然,我们需要多种部署区域($tree)。
  • 由于存在多个部署分支,我们必须使用多个索引文件,或者每次重建索引。此代码使用每个部署区域的一个索引(​​)。
  • 更新非master树时最好不要更改HEAD,所以我们避免git checkout。使用git read-tree --reset -u从指定的提交散列更新我们的索引和工作树。
  • 如果分支本身刚刚被删除,我们不能检查任何东西。如果它刚刚创建,那可能是好的:这是你可能想要调整的东西。例如,您可能需要为这种情况创建树。您可能需要删除分支删除部署树,就此而言。这样做的地点和方式应该很明显。
+0

我可以指定要处理哪个分支吗?如在特定分支的硬代码中一样,并使过程简单? –

+0

当然。看看我的第一个读取'stdin'的代码片段:它检查名为'master'或'test'-plus-any-single-character的分支。但是,如果要将多个分支部署到*多个目录,*您需要小心索引,因为服务器端裸存储库仍然只有一个标准索引,并且您计划部署到*两个*(或更多)目录。 – torek