저장소에 git hooks 넣기


197

.git / hooks를 프로젝트 저장소에 넣는 것은 나쁜 습관으로 간주됩니다 (예 : 심볼릭 링크 사용). 그렇다면 다른 git 사용자에게 동일한 후크를 제공하는 가장 좋은 방법은 무엇입니까?

답변:


143

나는 일반적으로 Scytale에 동의하고 별도의 답변을 할 가치가있는 몇 가지 추가 제안을합니다.

먼저, 적절한 후크를 생성하는 스크립트를 작성해야합니다. 특히 이러한 후크가 정책을 시행하거나 유용한 알림을 생성하는 것과 관련이있는 경우입니다. 사람들은 bin/create-hook-symlinks스스로해야하는 것보다 타이핑 할 수 있다면 후크를 훨씬 더 많이 사용할 것입니다.

둘째, 직접 연결 고리는 사용자가 자신의 개인 고리를 추가하지 못하게합니다. 예를 들어 샘플 프리 커밋 후크를 선호하므로 공백 오류가 없어야합니다. 이 문제를 해결하는 가장 좋은 방법은 리포지토리에 후크 래퍼 스크립트를 넣고 모든 후크를 심볼릭 링크 하는 것입니다. 그런 다음 래퍼는 $0(bash 스크립트이고 다른 것과 동등한 것으로 가정 argv[0]) 호출 된 후크를 파악한 다음 repo 내에서 적절한 후크를 호출하고 적절한 사용자 후크를 호출하여 이름을 바꿔야합니다. 모든 인수를 각각에 전달합니다. 메모리의 빠른 예 :

#!/bin/bash
if [ -x $0.local ]; then
    $0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
    tracked_hooks/$(basename $0) "$@" || exit $?
fi

설치 스크립트는 기존의 모든 후크를 측면으로 옮기고 ( .local이름에 추가 ) 알려진 모든 후크 이름을 위 스크립트로 symlink합니다.

#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks

for hook in $HOOK_NAMES; do
    # If the hook already exists, is executable, and is not a symlink
    if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
        mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
    fi
    # create the symlink, overwriting the file if it exists
    # probably the only way this would happen is if you're using an old version of git
    # -- back when the sample hooks were not executable, instead of being named ____.sample
    ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done

6
나는 그것을 chmod +x .git/hooks/*당신의 bin/create-hook-symlinks일에 추가 했습니다.
guneysus

6
@guneysus 후크는 이미 실행 가능해야하며 (그러한 방식으로 확인해야 함) 링크에는 링크가 파일 인 특별한 권한이 필요하지 않기 때문에 필요하지 않습니다.
Cascabel

13
후크 디렉토리를 얻는 더 좋은 방법은 HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks입니다.
Arnold Daniels

2
나는 이것을 기반으로 간단한 시스템을 만들어 프로젝트의 후크를 관리했다. ell.io/tt$Paws.js/blob/Master/Scripts/install-git-hooks.sh
ELLIOTTCABLE

6
난 그냥 필수했다 및 환매 특약에 넣어 github.com/sjungwirth/githooks
스콧 Jungwirth에게

111

아니요, 저장소에 넣는 것이 좋습니다. 다른 사람들에게도 유용한 경우 제안하는 것이 좋습니다. 사용자는 명시 적으로 활성화해야합니다 (예 : 심볼릭 링크로 말하면). 이는 약간의 고통이지만 다른 한편으로는 사용자가 동의없이 임의 코드를 실행하지 못하게합니다.


13
그것이 회사 정책 일이라면, 코드가 "임의"하지 않다면 이것은 필수 코드이므로 추적되는 다른 (사전 정의 된) 디렉토리가 없기 때문에 GIT의 제한으로 간주됩니다. 일반 후크와 함께 실행
Tobias Hagenbeek

14
후크를 자동으로 제공하는 것은 보안 문제입니다. Git은 팀 / 회사 정책을 시행하거나 서버 측에서 후크를 사용하거나 사용자가 @scy가 설명하는대로 수동으로 후크를 사용하도록 결정할 수 있도록하기 위해 직접하지 않습니다 :)
Mark K Cowan

4
"사용자의 동의없이 [...] 사용자가 임의의 코드를 실행하지 못하도록 보호합니다." 개발자가 제안 (심볼릭 링크)을 원한다면 다른 사람이 후크를 변경하고 "동의없이 임의 코드"를 실행할 수 있습니다.
MiniGod

24
MiniGod : 물론입니다. 편집증이 충분하면 후크를 연결하는 대신 후크를 복사 한 다음 감사 한 다음 활성화해야합니다. 그러나 대부분의 (인용 필요) Git 리포지토리에는 사용자 컴퓨터에서 실행되는 소스 코드가 포함되므로 어쨌든 끊임없이 변경되고 감사되지 않은 코드를 실행할 수 있습니다. 하지만 그렇습니다. ;)
scy

46

요즘에는 버전 제어를받는 디렉토리를 git hooks 디렉토리로 설정하기 위해 다음을 수행 할 수 MY_REPO_DIR/.githooks있습니다.

git config --local core.hooksPath .githooks/

여전히 직접적으로 시행 할 수는 없지만 README (또는 무엇이든)에 메모를 추가하면 각 개발자가 최소한의 노력을 기울여야합니다.


3
viget.com/articles/two-ways-to-share-git-hooks-with-your-team 에서 찾은 한 가지 비법 은 Makefile / CMake config / what 에서 옵션을 설정하는 것입니다.
Julius Bullinger

6

에서 http://git-scm.com/docs/git-init#_template_directory , 당신은 / 각 새로 생성 된 자식의 repo의 디렉토리 잇는 .git를 업데이트 이러한 메커니즘 중 하나를 사용할 수 있습니다 :

템플리트 디렉토리에는 파일 및 디렉토리가 작성된 후 $ GIT_DIR에 복사 될 디렉토리가 있습니다.

템플릿 디렉토리는 다음 중 하나입니다 (순서대로).

  • --template 옵션으로 주어진 인수;

  • $ GIT_TEMPLATE_DIR 환경 변수의 내용;

  • init.templateDir 구성 변수; 또는

  • 기본 템플릿 디렉토리 : / usr / share / git-core / templates


5

프로젝트에 저장하고 빌드에 설치

다른 사람들이 답변에서 언급했듯이 후크가 특정 프로젝트에 고유 한 경우 git이 관리하는 프로젝트 자체에 후크를 포함시킵니다. 나는 이것을 더 나아가서 하나의 스크립트 또는 명령을 사용하여 프로젝트를 빌드하는 것이 좋으면 빌드 중에 후크를 설치해야한다고 말하고 싶습니다.

좀 더 깊이 이해하려면 git hooks 관리에 대한 기사를 썼습니다 .

자바와 메이븐

면책 조항 아래에 설명 된 Maven 플러그인을 작성했습니다.

Java 프로젝트 용 Maven으로 빌드 관리를 처리하는 경우 다음 Maven 플러그인은 프로젝트의 위치에서 후크 설치를 처리합니다.

https://github.com/rudikershaw/git-build-hook

모든 Git 후크를 프로젝트의 디렉토리에 넣은 후 pom.xml다음 플러그인 선언, 목표 및 구성을 포함하도록 구성하십시오.

<build>
  <plugins>
    <plugin>
      <groupId>com.rudikershaw.gitbuildhook</groupId>
      <artifactId>git-build-hook-maven-plugin</artifactId>
      <configuration>
        <gitConfig>
          <!-- The location of the directory you are using to store the Git hooks in your project. -->
          <core.hooksPath>hooks-directory/</core.hooksPath>
        </gitConfig>
      </configuration>
      <executions>
        <execution>
          <goals>       
            <!-- Sets git config specified under configuration > gitConfig. -->
            <goal>configure</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
      <!-- ... etc ... -->
  </plugins>
</build>

프로젝트 빌드를 실행할 때 플러그인은 지정된 디렉토리에서 후크를 실행하도록 git을 구성합니다. 이렇게하면 프로젝트에서 작업하는 모든 사람을 위해 해당 디렉토리에 후크를 효과적으로 설정할 수 있습니다.

자바 스크립트 및 NPM

NPM의 경우 Husky 라는 종속성 이 있으므로 JavaScript로 작성된 후크를 포함하여 후크를 설치할 수 있습니다.

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  }
}

기타

또한 Python 프로젝트에 대한 사전 커밋 , Ruby 프로젝트에 대한 오버 커밋 및 Ruby 또는 노드 프로젝트에 대한 Lefthook 이 있습니다.


1
이 플러그인을 작성해 주셔서 감사합니다. 사전 커밋 파일을 매우 쉽게 통합 할 수있었습니다.
Michiel Bugher


1

Composer 기반 PHP 프로젝트의 경우 엔지니어에게 자동으로 배포 할 수 있습니다. 사전 커미트 및 commit-msg 후크에 대한 예는 다음과 같습니다.

hookscomposer.json에 폴더를 작성하십시오 .

 },
 "scripts": {
     "post-install-cmd": [
         "cp -r 'hooks/' '.git/hooks/'",
         "php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
         "php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
         "php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
         "php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
     ],

그런 다음 모든 사람이 composer install정기적으로 실행되면서 프로젝트가 계속됨에 따라 업데이트 할 수도 있습니다 .


0

다음은 add-git-hook.sh 스크립트입니다.이 스크립트는 리포지토리에 일반 파일로 제공 될 수 있으며 스크립트 파일에 git hook을 추가하기 위해 실행될 수 있습니다. 사용할 후크 (사전 커밋, 사후 커밋, 사전 푸시 등)와 고양이 heredoc에서 후크 정의를 조정하십시오.

#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
# Note: CWD must be inside target repository

HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit

# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
        echo '#!/usr/bin/bash' >> "$HOOK_FILE"
        chmod 700 "$HOOK_FILE"
fi

# Append hook code into script
cat >> "$HOOK_FILE" <<EOF

########################################
# ... post-commit hook script here ... #
########################################

EOF

이 스크립트는 실행 권한이 있거나 사용자가 직접 실행할 수 있습니다. 나는 이것을 사용하여 다른 컴퓨터에서 자동으로 git-pull을 사용했습니다.

편집-나는 묻지 않았고 OP가 찾고있는 것이 아닌 쉬운 질문에 대답했습니다. 아래 주석에서 외부 스크립트를 관리하는 것보다 repo에서 후크 스크립트를 배송하는 유스 케이스 및 인수에 동의했습니다. 그것이 당신이 찾고있는 것보다 많기를 바랍니다.


귀하의 노력에 감사 드리며 여기에 귀중한 정보가 있다고 생각합니다. 명시된 질문에 대한 답변은 아닙니다.
shabunc

제 생각에는 후크가 특정 리포지토리에 고유하거나 사용 된 워크 플로의 필수 구성 요소 인 경우 리포지토리에 파일로 속합니다. 해결하는 것보다 더 많은 문제를 일으키지 않고 다른 곳에 두는 것은 어렵습니다. 일반 후크는 자체 저장소 또는 공유 드라이브에 저장하여 프로젝트 저장소를 깨끗하게 유지하지만 실용성이 떨어질 수 있습니다. 후크를 쉽게 추가 할 수 있어야한다는 다른 사용자의 의견에 동의합니다. 심볼릭 링크는 특정 시스템이나 파일 구조에 불필요한 의존성을 만들 수 있습니다.
mathewguest

또한 기호 링크는 사용자가 자신의 후크를 추가 할 수 없게합니다. .git / hooks 디렉토리는 추적되지 않으므로 소스는 저장소에서 시작하여 다른 방법이 아닌 hooks 스크립트로 들어가야합니다. 반대 주장은 git hooks이 프로젝트가 아닌 워크 플로우 또는 팀과 더 관련되어 저장소에 속하지 않는다고 생각합니다. 특정 유스 케이스에 따라 관련성이 적은 후크로 git 저장소를 잠재적으로 오염시키는 것이 더 괜찮습니까?
mathewguest

0

pre-commit과 같은 pre-commit hook 관리를 위해 관리 형 솔루션을 사용할 수 있습니다 . 또는 Datree.io 와 같은 서버 측 git-hook에 대한 중앙 집중식 솔루션 . 다음과 같은 기본 제공 정책이 있습니다.

  1. 비밀 병합 감지 및 방지 .
  2. 적절한 Git 사용자 구성을 시행하십시오 .
  3. 적용 락스 티켓 통합 - 풀 요청 이름을 언급 티켓 번호 / 메시지를 커밋합니다.

모든 후크를 대체하지는 않지만 모든 개발자 컴퓨터 / 리포지토리에 후크를 설치하지 않고도 구성이 가장 분명한 개발자에게 도움이 될 수 있습니다.

면책 조항 : 저는 Datrees 설립자 중 하나입니다


3
나는 당신이 흥미로운 제품을 만들고 있다고 생각하지만 이것은 또한 질문에 대한 답이 아니며 기본적으로 자체 홍보이며 더 이상은 아니라고 생각합니다.
shabunc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.