수색…
통사론
- .git / hooks / applypatch-msg
- .git / hooks / commit-msg
- .git / hooks / post-update
- .git / hooks / pre-applypatch
- .git / hooks / pre-commit
- .git / hooks / prepare-commit-msg
- .git / hooks / pre-push
- .git / hooks / pre-rebase
- .git / hooks / update
비고
--no-verify
또는 -n
주어진 git 명령의 모든 로컬 후크를 건너 뜁니다.
예 : git commit -n
커밋 - 메시지
이 후크는 prepare-commit-msg
훅과 비슷하지만 사용자가 전에 커밋 메시지를 입력 한 후에 호출됩니다. 이것은 보통 커밋 메시지의 형식이 잘못된 경우 개발자에게 경고하는 데 사용됩니다.
이 후크에 전달되는 유일한 인수는 메시지가 포함 된 파일의 이름입니다. 사용자가 입력 한 메시지가 마음에 들지 않으면이 파일을 내부적으로 변경하거나 ( prepare-commit-msg
와 동일) 0이 아닌 상태로 종료하여 커밋을 완전히 중단 할 수 있습니다.
다음 예는 커밋 메시지에 숫자 뒤에 오는 단어 티켓이 있는지 확인하는 데 사용됩니다
word="ticket [0-9]"
isPresent=$(grep -Eoh "$word" $1)
if [[ -z $isPresent ]]
then echo "Commit message KO, $word is missing"; exit 1;
else echo "Commit message OK"; exit 0;
fi
로컬 후크
로컬 후크는 해당 로컬 저장소에만 영향을 미칩니다. 각 개발자는 자신의 로컬 후크를 변경할 수 있으므로 커밋 정책을 적용하는 방법으로 안정적으로 사용할 수 없습니다. 개발자가 특정 지침을 준수하고 잠재적 인 문제를 쉽게 피할 수 있도록 설계되었습니다.
사전 커밋 (pre-commit), 준비 커밋 (commit) - 메시지, 커밋 - 메시지, 커밋 후 완료, 사후 체크 아웃 및 사전 리베이스 (pre-rebase)의 6 가지 유형의 로컬 후크가 있습니다.
처음 네 개의 후크는 커밋과 관련이 있으며 커밋의 라이프 사이클에서 각 부분에 대한 제어권을 가질 수 있습니다. 마지막 두 명령은 git checkout 및 git rebase 명령에 대한 추가 작업이나 안전성 검사를 수행 할 수있게합니다.
모든 "사전"후크를 사용하면 수행 할 작업을 변경할 수 있으며 "후"후크는 주로 알림을 위해 사용됩니다.
사후 체크 아웃
이 후크는 post-commit
훅과 비슷하게 작동하지만 git checkout
으로 참조를 성공적으로 체크 아웃 할 때마다 호출 git checkout
. 이는 혼동을 일으킬 수있는 자동 생성 파일의 작업 디렉토리를 지우는 데 유용한 도구가 될 수 있습니다.
이 후크는 세 가지 매개 변수를 허용합니다.
- 이전 HEAD의 ref,
- 새로운 HEAD의 ref,
- 분기 체크 아웃인지 또는 파일 체크 아웃인지를 나타내는 플래그 (각각
1
또는0
).
종료 상태는 git checkout
명령에 영향을 미치지 않습니다.
포스트 커밋
이 후크는 commit-msg
훅 바로 다음에 호출됩니다. git commit
작업의 결과를 변경할 수 없기 때문에 주로 통지 목적으로 사용됩니다.
이 스크립트는 매개 변수를 취하지 않으며 종료 상태는 어떤 방식 으로든 커밋에 영향을 미치지 않습니다.
수신 후
이 훅은 푸시 조작이 성공한 후에 호출됩니다. 일반적으로 통지 목적으로 사용됩니다.
스크립트는 매개 변수를 사용하지 않지만 표준 입력을 통해 pre-receive
과 동일한 정보가 전송 pre-receive
.
<old-value> <new-value> <ref-name>
사전 커밋
이 훅은 git commit
을 실행할 때마다 실행되어 git commit
될 내용을 확인합니다. 이 훅을 사용하여 커밋 할 스냅 샷을 검사 할 수 있습니다.
이 유형의 후크는 들어오는 커밋이 프로젝트의 기존 기능을 손상시키지 않도록 자동화 된 테스트를 실행하는 데 유용합니다. 이 유형의 후크는 공백 또는 EOL 오류를 검사 할 수도 있습니다.
인수가 사전 커밋 스크립트에 전달되지 않고 0이 아닌 상태로 종료하면 전체 커밋이 중단됩니다.
Prepare-commit-msg
이 후크는 커밋 메시지로 텍스트 편집기를 채우기 위해 pre-commit
후크 후에 호출됩니다. 이것은 일반적으로 스쿼시 또는 병합 된 커밋에 대해 자동으로 생성 된 커밋 메시지를 변경하는 데 사용됩니다.
이 후크에 1 ~ 3 개의 인수가 전달됩니다.
- 메시지가 들어있는 임시 파일의 이름.
- 커밋 유형.
- 메시지 (
-m
또는-F
옵션), - 템플릿 (
-t
옵션), - 병합 (병합 커밋 인 경우) 또는
- 스쿼시 (다른 커밋을 스쿼시하는 경우)
- 메시지 (
- 해당 커밋의 SHA1 해시입니다. 이것은
-c
,-C
또는--amend
옵션이 주어진 경우에만 제공됩니다.
pre-commit
과 마찬가지로 0이 아닌 상태로 종료하면 커밋이 중단됩니다.
사전 리베이스
이 훅은 git rebase
가 코드 구조를 변경하기 전에 호출됩니다. 이 후크는 일반적으로 rebase 작업이 적절한 지 확인하는 데 사용됩니다.
이 후크는 2 개의 매개 변수를 취합니다.
- 시리즈가 분기 된 상류 지점
- 브랜치가 리베이스됩니다 (현재 브랜치를 리베이스 할 때 비어 있음).
0이 아닌 상태에서 종료하여 rebase 작업을 중단 할 수 있습니다.
미리 수신
이 훅은 git push
를 사용하여 커밋을 저장소로 git push
할 때마다 실행됩니다. 항상 푸시의 대상인 원격 저장소에 있으며 원본 (로컬) 저장소에는 없습니다.
참조가 업데이트되기 전에 후크가 실행됩니다. 일반적으로 모든 종류의 개발 정책을 시행하는 데 사용됩니다.
이 스크립트는 매개 변수를 사용하지 않지만 푸시 된 각 참조는 다음 형식으로 표준 입력의 별도 행에있는 스크립트로 전달됩니다.
<old-value> <new-value> <ref-name>
최신 정보
이 후크는 pre-receive
후에 호출되며 동일한 방식으로 작동합니다. 실제로는 어떤 것이 실제로 업데이트되기 전에 호출되지만, 한번에 모든 참조가 아닌 각 참조에 대해 별도로 호출됩니다.
이 훅은 다음의 3 개의 인수를받습니다 :
- 업데이트되는 참조의 이름,
- ref에 저장된 이전 객체 이름
- ref에 저장된 새로운 객체 이름.
이것은 pre-receive
전달되는 동일한 정보이지만, 각 ref마다 별도로 update
가 호출되기 때문에 일부 ref를 거부하고 다른 ref는 허용 할 수 있습니다.
미리 푸시
Git 1.8.2 이상에서 사용 가능합니다.
푸시를 방지하기 위해 프리 푸시 후크를 사용할 수 있습니다. 유용한 이유는 특정 분기로 실수로 수동 푸시를 차단하거나 설정된 검사가 실패 할 경우 푸시를 차단하는 것입니다 (단위 테스트, 구문).
사전 푸시 훅은 단순히라는 이름의 파일을 생성하여 만든 pre-push
에서 .git/hooks/
: 파일이 실행 가능, 및 (잡았다 경고)를 확인하고 chmod +x ./git/hooks/pre-push
.
다음은 한나 울프 (Hannah Wolfe) 의 예를 보여줍니다.
#!/bin/bash
protected_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [ $protected_branch = $current_branch ]
then
read -p "You're about to push master, is that what you intended? [y|n] " -n 1 -r < /dev/tty
echo
if echo $REPLY | grep -E '^[Yy]$' > /dev/null
then
exit 0 # push will execute
fi
exit 1 # push will not execute
else
exit 0 # push will execute
fi
다음은 푸시를 허용하기 전에 RSpec 테스트가 통과하는지 확인하는 Volkan Unsal 의 예입니다.
#!/usr/bin/env ruby
require 'pty'
html_path = "rspec_results.html"
begin
PTY.spawn( "rspec spec --format h > rspec_results.html" ) do |stdin, stdout, pid|
begin
stdin.each { |line| print line }
rescue Errno::EIO
end
end
rescue PTY::ChildExited
puts "Child process exit!"
end
# find out if there were any errors
html = open(html_path).read
examples = html.match(/(\d+) examples/)[0].to_i rescue 0
errors = html.match(/(\d+) errors/)[0].to_i rescue 0
if errors == 0 then
errors = html.match(/(\d+) failure/)[0].to_i rescue 0
end
pending = html.match(/(\d+) pending/)[0].to_i rescue 0
if errors.zero?
puts "0 failed! #{examples} run, #{pending} pending"
# HTML Output when tests ran successfully:
# puts "View spec results at #{File.expand_path(html_path)}"
sleep 1
exit 0
else
puts "\aCOMMIT FAILED!!"
puts "View your rspec results at #{File.expand_path(html_path)}"
puts
puts "#{errors} failed! #{examples} run, #{pending} pending"
# Open HTML Ooutput when tests failed
# `open #{html_path}`
exit 1
end
보시다시피, 많은 가능성이 있지만 핵심 요소는 좋은 일이 발생하면 exit 0
을 exit 0
하고, 나쁜 일이 발생한 경우 exit 1
것입니다. 언제든지 exit 1
을 exit 1
때 push가 방지되고 코드가 git push...
를 실행하기 전의 상태가됩니다.
클라이언트 측 훅을 사용할 때는 밀어 넣기에서 "--no-verify"옵션을 사용하여 모든 클라이언트 측 훅을 건너 뛸 수 있습니다. 프로세스를 시행하기 위해 훅에 의존한다면 화상을 입을 수 있습니다.
문서 : https://git-scm.com/docs/githooks#_pre_push
공식 샘플 : https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
커밋하기 전에 Maven 빌드 (또는 다른 빌드 시스템) 확인
.git/hooks/pre-commit
#!/bin/sh
if [ -s pom.xml ]; then
echo "Running mvn verify"
mvn clean verify
if [ $? -ne 0 ]; then
echo "Maven build failed"
exit 1
fi
fi
특정 푸시를 다른 저장소로 자동 전달
post-receive
후크를 사용하여 들어오는 푸시를 다른 저장소로 자동 전달할 수 있습니다.
$ cat .git/hooks/post-receive
#!/bin/bash
IFS=' '
while read local_ref local_sha remote_ref remote_sha
do
echo "$remote_ref" | egrep '^refs\/heads\/[A-Z]+-[0-9]+$' >/dev/null && {
ref=`echo $remote_ref | sed -e 's/^refs\/heads\///'`
echo Forwarding feature branch to other repository: $ref
git push -q --force other_repos $ref
}
done
이 예제에서 egrep
regexp는 특정 분기 형식을 찾습니다 (여기에서 JIRA-12345는 Jira 문제의 이름으로 사용됩니다). 물론 모든 지점을 전달하려는 경우이 부분을 벗어날 수 있습니다.