2011-09-08 26 views
87

Đây là móc hiện tại của tôi trong một repo trần sống trong máy chủ của công ty: git push origin master Móc này đẩy vào Assembla. Những gì tôi cần là chỉ đẩy một chi nhánh (chủ, lý tưởng) khi ai đó đẩy các thay đổi đến nhánh đó trên máy chủ của chúng tôi và bỏ qua các lần đẩy tới các nhánh khác. Có thể chọn chi nhánh từ một repo trần và chỉ đẩy nhánh đó vào Assembla?Viết một móc git sau khi nhận để xử lý một chi nhánh cụ thể

+0

Ý của bạn là gì? 'git push origin master' sẽ chỉ đẩy nhánh' master' tới điều khiển từ xa 'origin' mà tôi giả định được định nghĩa là Assembla. Bạn đang nói rằng bạn cần phải * kích hoạt * móc chỉ khi ai đó đẩy đến 'chủ', trái ngược với' feature1', hoặc một cái gì đó như thế? –

+0

@Stefan Chính xác điều đó. Tôi không thể tìm thấy từ đó, hehe. –

+0

Duplicate http://stackoverflow.com/questions/6372334/git-commit-hooks-per-branch – insign

Trả lời

7

Tham số cuối cùng mà móc hậu nhận được trên stdin là những gì ref đã được thay đổi, vì vậy chúng tôi có thể sử dụng để kiểm tra xem giá trị đó là "refs/heads/master". Một chút ruby ​​giống như những gì tôi sử dụng trong một bài-nhận móc:

STDIN.each do |line| 
    (old_rev, new_rev, ref_name) = line.split 
    if ref_name =~ /master/ 
     # do your push 
    end 
end 

Lưu ý rằng nó được một dòng cho mỗi ref đã được đẩy, vì vậy nếu bạn đẩy nhiều hơn chỉ là bậc thầy, nó vẫn sẽ làm việc.

+0

Cảm ơn ví dụ về Ruby. Tôi sẽ làm một cái gì đó tương tự như thế này. – Leif

5

câu trả lời Stefan không làm việc cho tôi, nhưng this đã làm:

#!/bin/bash 

echo "determining branch" 

if ! [ -t 0 ]; then 
    read -a ref 
fi 

IFS='/' read -ra REF <<< "${ref[2]}" 
branch="${REF[2]}" 

if [ "master" == "$branch" ]; then 
    echo 'master was pushed' 
fi 

if [ "staging" == "$branch" ]; then 
    echo 'staging was pushed' 
fi 

echo "done" 
+0

Làm việc cho tôi cho các chi nhánh với một tên đơn giản (chủ, kiểm tra, vv), Nhưng khi tôi có tên chi nhánh như vậy: prod12/proj250/ropesPatch12. nó không hoạt động tốt. Bạn có một giải pháp có thể làm việc với những nhân vật đặc biệt đó không? –

335

Một hậu nhận móc được đối số của nó từ stdin, dưới hình thức <oldrev> <newrev> <refname>. Vì các đối số này đến từ stdin, không phải từ đối số dòng lệnh, bạn cần sử dụng read thay vì $1 $2 $3.

Móc hậu nhận có thể nhận nhiều nhánh cùng một lúc (ví dụ nếu ai đó làm git push --all), vì vậy chúng tôi cũng cần bọc read trong vòng lặp while.

Một đoạn làm việc trông giống như sau:

#!/bin/bash 
while read oldrev newrev refname 
do 
    branch=$(git rev-parse --symbolic --abbrev-ref $refname) 
    if [ "master" == "$branch" ]; then 
     # Do something 
    fi 
done 
+48

Điều này sẽ được đánh dấu là câu trả lời đúng. – jackyalcine

+2

"==" không hoạt động đối với tôi. Với duy nhất "=" hoạt động tốt cho tôi. – Ray

+0

Thật lạ lùng. Đôi bằng và đơn bằng đều nên làm việc tốt ở đây (xem http://stackoverflow.com/questions/2600281/what-is-the-difference-between-operator-and-in-bash). Bạn có thể sử dụng một cái gì đó khác hơn là bash? Bất kể, vui mừng bạn tìm thấy một sửa chữa cho nó. – pauljz

3

Cả trong những giải pháp nêu trên làm việc cho tôi. Sau nhiều, gỡ lỗi nhiều, nó chỉ ra rằng bằng cách sử dụng lệnh 'đọc' không hoạt động - thay vào đó, phân tích cú pháp đối số dòng lệnh theo cách thông thường hoạt động tốt.

Dưới đây là móc chính xác sau khi cập nhật mà tôi vừa thử nghiệm thành công ngay bây giờ trên CentOS 6.3.

#!/bin/bash 

echo "determining branch" 

branch=`echo $1 | cut -d/ -f3` 

if [ "master" == "$branch" ]; then 
    echo "master branch selected" 
fi 

if [ "staging" == "$branch" ]; then 
    echo "staging branch selected" 
fi 

exec git update-server-info 

UPDATE: trên một lưu ý, ngay cả người lạ, các pre-nhận móc mất đầu vào của nó qua stdin, do đó đọc với 'đọc' (wow, không bao giờ nghĩ rằng tôi muốn nói rằng). Móc sau khi cập nhật vẫn hoạt động với $ 1 cho tôi.

+2

Đối với những gì nó có giá trị, các giải pháp trên có thể không có tác dụng vì chúng đặc biệt cho các móc móc sau khi nhận, không phải là móc sau khi cập nhật. Họ lấy ý kiến ​​của họ theo nhiều cách khác nhau. – pauljz

+0

'sau khi nhận' mất stdin như đã lưu ý ở đây: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks – h4xnoodle

0

Tôi đã viết một kịch bản PHP cho bản thân mình để thực hiện chức năng này.

https://github.com/fotuzlab/githubdump-php

chủ tập tin này trên máy chủ của bạn, tốt nhất là rễ repo và xác định các url trong webhooks github. Thay đổi 'allcommits' trên dòng 8 bằng tên chi nhánh của bạn và thêm mã/chức năng của bạn tại dòng 18.

ví dụ:

function githubdump($payload_object) { 
    // Write your code here. 
    exec('git push origin master'); 
} 
0

cách tiếp cận đơn giản, trong git hook ghi

read refname 
echo $refname 

đơn giản - thông tin thêm về liên kết tuyệt vời này hooking system

0

Câu trả lời từ @pauljz hoạt động tốt cho móc git nhất định như pre-push, nhưng pre-commit làm không có quyền truy cập vào các biến đó oldrev newrev refname

Vì vậy, tôi đã tạo phiên bản thay thế này làm việc cho tiền cam kết, hoặc thực sự và móc. Đây là móc pre-commit sẽ chạy tập lệnh husky nếu chúng tôi KHÔNG ở trên chi nhánh master.

#!/bin/bash 
# git 'commit' does not have access to these variables: oldrev newrev refname 
# So get the branch name off the head 

branchPath=$(git symbolic-ref -q HEAD) # Something like refs/heads/myBranchName 
branch=${branchPath##*/}  # Get text behind the last/of the branch path 

echo "Head: $branchPath"; 
echo "Current Branch: $branch"; 

if [ "master" != "$branch" ]; then 

    # If we're NOT on the Master branch, then Do something 
    # Original Pre-push script from husky 0.14.3 

    command_exists() { 
    command -v "$1" >/dev/null 2>&1 
    } 

    has_hook_script() { 
    [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:" 
    } 

    cd "frontend" # change to your project directory, if .git is a level higher 

    # Check if precommit script is defined, skip if not 
    has_hook_script precommit || exit 0 

    # Node standard installation 
    export PATH="$PATH:/c/Program Files/nodejs" 

    # Check that npm exists 
    command_exists npm || { 
    echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json" 
    exit 0 
    } 

    # Export Git hook params 
    export GIT_PARAMS="$*" 

    # Run npm script 
    echo "husky > npm run -s precommit (node `node -v`)" 
    echo 

    npm run -s precommit || { 
    echo 
    echo "husky > pre-commit hook failed (add --no-verify to bypass)" 
    exit 1 
    } 
fi 

Tôi hy vọng sẽ giúp ai đó. Bạn có thể dễ dàng sửa đổi cho nhu cầu của mình, bất kỳ điều gì ở giữa các câu hỏi iffi.

Các vấn đề liên quan