git钩子创建分段分支 [英] git hook to create staging branch

查看:263
本文介绍了git钩子创建分段分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Bitbucket上托管我的代码。 webhooks不足以解决我的问题,所以我希望git钩子将工作。因为我不想象他们将工作在服务器端,git钩子应该传播到每个开发人员机器上的每个签出。 (我知道这可能是一个问题,因为它通常是本地文件,但我希望使用来自


I am hosting my code on Bitbucket. The webhooks are not adequate to solve my issue, so I am hoping git hooks will work. Since I don't imagine they will work server-side, the git hook should be propagated to each checkout on each developers machine. (I know this might be an issue since its normally a local file, but I can hopefully solve it using information from here)

I want to create a git hook that will push changes to staging branches.

Meaning, if I am a user named bob and I want to push to production/master, instead of it pushing to the production/master branch it will push to a staging branch like staging/master/bob. Same for another user roy who pushes to production/master it will go to staging/master/roy. And the same for any production branch. So edd pushing to production/2.0 would push to staging/2.0/edd.

I have tried the pre-commit hook, but I can't find a way to direct the target of the push. I know this is possible.

I tried using GIT_WORK_TREE, and I couldn't seem to get it to work.


Clarification

The whole process should be seamless for bob the developer. He should pull from the master and push to the master. (or whatever branch he is working on) and the process will happen in the background. It will push his changes to a staging branch, which will then undergo a CI process, and if successful will be pushed into the main branch. This is the solution that I need.

解决方案

You may use pre-push hook and run another git-push command from within it. This way you can alter a destination ref, hence push data on a staging branch and abort execution of push on a production branch. Here is the sketch of a script:

#!/bin/sh

#You may want to iterate over all refs 
#in case there are more branches that are being pushed
read local_ref local_sha remote_ref remote_sha

#Make sure you are not running the hook ad inifinitum
[[ $remote_ref =~ .*"staging".* ]] && exit 0

#Make sure these are unique
name="$(git config --get user.name | awk '{print $1;}' | tr '[:upper:]' '[:lower:]')"

#Compose a staging branch name accordingly
staging_branch="$(echo "$remote_ref" | sed 's:refs/heads/production/:staging/:')"
staging_branch="$staging_branch/$name"

git push origin master:"$staging_branch"  

#Don't forget that exit status needs to be != 0
#unless you want to push the same changes twice
exit 1

You need to consider some more complex cases, but I guess it should work after few adjustments .

Later you may run whatever tests you want on a CI server, push it to production and delete a staging branch. You probably want to configure each local repository so git-fetch prunes automatically:

 git config remote.origin.prune true

That way devs won't see outdated references to remote staging branches (if you choose to delete them).

Alternatively you could try to set master's upstream to an adequate staging branch. However it would probably get messy if you deleted a remote ref.

Bottom line

I don't think it's the most elegant solution, but I believe it answers your question directly. One of the drawbacks of this approach is the fact that ultimately it doesn't exit with 0. I don't know how it would be handled by some external tools. When you are using a command line it just generates an error line you can ignore.

You may want to consider @VonC's solution or some kind of other policy to prevent from pushing directly to a production branch.

EDIT:

A command line message would look like this:

这篇关于git钩子创建分段分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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