저장소와 함께 Git 후크 스크립트를 관리 할 수 ​​있습니까?


336

커밋 메시지를 미리 포맷팅하는 것과 같이 공유 할 수있는 몇 가지 기본 후크 스크립트를 만들고 싶습니다. Git에는 일반적으로 아래에 저장되는 후크 스크립트가 있습니다 <project>/.git/hooks/. 그러나 사람들이 복제 작업을 수행 할 때 해당 스크립트는 전파되지 않으며 버전이 제어되지 않습니다.

모두가 올바른 후크 스크립트를 얻도록 돕는 좋은 방법이 있습니까? 해당 후크 스크립트를 내 리포지토리의 버전 제어 스크립트를 가리 키도록 할 수 있습니까?


5
좋은 질문입니다. 더 나은 답변이 있기를 바랍니다. (@ mipadi에 불만이 없으면 git이 git clone에 지정된 옵션 만 있더라도 git이 더 자동적 인 방법 으로이 작업을 수행 할 수 있기를 바랍니다)
lindes

동의합니다, @lindes! 그러나 의도적으로 이러한 후크 공유를 제한합니까? Windows 사용자에게는 문제가 발생할 수 있습니다.
kristianlm

@kristianlm : 때때로 혼란 스러울 수있는 모든 종류의 이유가 있습니다 ... 그리고 거기에있는 것이 좋을 때도 있습니다. 나는 후크를 복사 할 수있는 옵션이나 무언가가 있었으면 좋겠다. git-core 코드를 언젠가 확인하고 패치를 작성해야 할 것 같습니다. :) (또는 다른 사람이 ... 또는 mipadi의 답변 등으로 해결 방법을 함께 살기를 바랍니다 .)
lindes

pre-commit사전 커밋 후크에 쉽게 사용할 수 있습니다. 임의의 git hook 관리에 대한 OP의 질문에 대답하지 않지만 사전 커미트 후크는 코드 품질 목적으로 가장 자주 사용됩니다.
ericsoco

답변:


143

이론적으로 hooks는 모든 스크립트를 사용하여 프로젝트 디렉토리에 디렉토리 (또는 원하는 이름)를 만든 다음에서 심볼릭 링크 할 수 있습니다 .git/hooks. 물론 리포지토리를 복제 한 각 사용자는 이러한 심볼릭 링크를 설정해야합니다 (실제로 화려하고 복제자가 반자동으로 설정하기 위해 실행할 수있는 배포 스크립트를 보유 할 수는 있음).

* nix에서 symlink를 수행하려면 다음을 수행하십시오.

root="$(pwd)"
ln -s "$root/hooks" "$root/.git/hooks"

ln -sf내용을 덮어 쓸 준비가 된 경우 사용.git/hooks


38
이것은 사소한 것이 아니므로 제대로 symlink하는 방법에 대한 링크를 포함하고 있습니다 : stackoverflow.com/questions/4592838/…
David T.

17
git 버전 2.9에는 이제 core.hooksPath.git 외부에 파일을 설정하여 hooks 폴더에 연결 하는 구성 옵션이 있습니다.
Aaron Rabinowitz

215

에서 힘내 2.9 , 구성 옵션은 core.hooksPath사용자 정의 후크 디렉토리를 지정합니다.

후크를 hooks저장소 의 추적 된 디렉토리로 이동하십시오 . 그런 다음 리포지토리의 각 인스턴스 가 다음 hooks대신 추적을 사용 하도록 구성 하십시오 $GIT_DIR/hooks.

git config core.hooksPath hooks

일반적으로 경로는 절대적이거나 후크가 실행되는 디렉토리 (일반적으로 작업 트리 루트;의 설명 섹션 참조)에 상대적 일 수 있습니다 man githooks.


15
... 그리고 hooks 디렉토리는 별도의 hooks 저장소가 될 수 있습니다.)
René Link

10
글쎄, git clone을 할 때이 구성 매개 변수가 자동으로 설정됩니까?
Ring

4
일반적으로 git config 변수는 복제하려는 리포지토리에서 설정할 수 없습니다. 나는 이것이 임의 코드의 실행을 막는 것이라고 생각합니다. git config는 후크, 커밋 메시지의 사용자 이름 및 기타 중요한 기능을 통해 코드 실행을 제어합니다.
Max Shenfield

1
팀의 누군가가 다른 지점으로 git checkout을 수행하면 어떻게됩니까? 모든 지점에 포함시켜야합니다.
jokerster

1
사실입니다. 반면, 새로운 커밋에서 후크를 업데이트하면 복제 된 리포지토리가 해당 커밋 위에 빌드 된 브랜치에서 작업 할 때이를 자동으로 가져옵니다. 두 가지 방법 모두 장점과 단점이 있습니다.
fabb

15

프로젝트가 JavaScript 프로젝트이고 npm패키지 관리자로 사용하는 경우 공유 git-hook 을 사용하여 githook을 시행 할 수 있습니다 npm install.


5
이제 나는 누가 그 쓰레기를 추가했는지 알고 .git/hooks있습니다.
gavenkoa

경고-Windows를 지원하지 않습니다 (git bash에서 관리자로 실행되지 않는 한). 간단한 해결책은 "preinstall": "git config core.hooksPath hooks"를 package.json의 스크립트로 추가하는 것입니다. 즉, hooks는 git 스크립트를 포함하는 폴더입니다.
Shane Gannon

8

들어 Nodejs의 사용자가 간단한 솔루션을 업데이트하는 것입니다 package.json 으로

{
  "name": "name",
  "version": "0.0.1",
  ......
  "scripts": {
    "preinstall": "git config core.hooksPath hooks", 

사전 설치는 이전에 실행됩니다

npm 설치

그리고 git을 리디렉션하여 . \ hooks (또는 원하는 이름) 디렉토리 내에서 후크를 찾습니다 . 이 디렉토리는 파일 이름 (.sample 제외) 및 구조 측면에서 . \. git \ hooks 를 모방해야합니다 .

Maven 및 기타 빌드 도구가 사전 설치에 해당한다고 상상해보십시오 .

또한 모든 플랫폼에서 작동해야합니다.

더 많은 정보가 필요하면 https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/을 참조 하십시오.


5

방법에 대한 자식 - 후크 ,이 노선 .git/hooks프로젝트 디렉토리 아래 스크립트로 호출 githooks.

또한 모든 곳에서 복사 및 심볼릭 링크 후크를 최소화 할 수있는 많은 기능이 있습니다.


5

대부분의 최신 프로그래밍 언어 또는 빌드 도구는 git hook을 관리하는 플러그인을 지원합니다. 즉, package.json, pom.xml 등을 구성하기 만하면 팀의 모든 사람이 빌드 파일을 변경하지 않는 한 준수 할 수밖에 없습니다. 플러그인은 .git 디렉토리에 컨텐츠를 추가합니다.

예 :

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

https://github.com/olukyrich/githook-maven-plugin

https://www.npmjs.com/package/git-hooks


나는 그것을 일반적인 방법으로, 내 프로젝트에서 사용하기 위해 노력했기 때문에 다음 도구를 썼습니다 : pypi.org/project/hooks4git
Lovato

3

빌드 전후 이벤트가있는 Visual Studio 솔루션 (및 프로젝트)을 사용하고 있습니다. 'GitHookDeployer'라는 프로젝트를 추가하고 있습니다. 프로젝트는 빌드 후 이벤트에서 파일을 자체 수정합니다. 해당 파일은 빌드 디렉토리로 복사되도록 설정되어 있습니다. 따라서 프로젝트는 매번 빌드되며 건너 뛰지 않습니다. 빌드 이벤트에서는 모든 자식 후크가 제자리에 있는지 확인합니다.

물론 일부 프로젝트는 빌드 할 것이 없기 때문에 이것은 일반적인 솔루션이 아닙니다.


2

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

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

모든 후크를 대체하지는 않지만 모든 개발자 컴퓨터 / 리포지토리에 후크를 설치하지 않고 구성을 사용하지 않고도 개발자가 가장 확실한 것을 도울 수 있습니다.

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


1

후크 폴더를 다른 git 저장소로 만들고 하위 모듈로 링크 할 수 있습니다 ... 정기적으로 변경되는 많은 멤버와 후크가있는 경우에만 가치가 있다고 생각합니다.


1

샘플 파일을 따르는 경우 후크는 bash로 작성하는 것이 가장 좋습니다. 그러나 사용 가능한 모든 언어로 작성하고 실행 가능 플래그가 있는지 확인하십시오.

따라서 목표를 달성하기 위해 Python 또는 Go 코드를 작성하고 hooks 폴더 아래에 배치 할 수 있습니다. 작동하지만 리포지토리와 함께 관리되지는 않습니다.

두 가지 옵션

a) 멀티 스크립트

도움말 내부에 후크를 코딩하고 후크에 작은 코드 조각을 추가하여 다음과 같이 완벽한 스크립트를 호출 할 수 있습니다.

$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/myprecommit.js

b) 단일 스크립트

더 멋진 옵션은 여러 개의 스크립트 대신 하나의 스크립트 만 추가하여 모두를 지배하는 것입니다. 따라서 hooks / mysuperhook.go를 만들고 원하는 모든 후크를 가리 킵니다.

$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/mysuperhook.go $(basename $0)

이 매개 변수는 어떤 후크가 트리거되었는지 스크립트를 제공하며 코드 내에서 구별 할 수 있습니다. 왜? 예를 들어, 커밋 및 푸시에 대해 동일한 검사를 수행하려는 경우가 있습니다.

그리고?

그런 다음 다음과 같은 추가 기능을 원할 수 있습니다.

  • 커밋 또는 푸시 전에도 후크가 수동으로 트리거되어 모든 것이 정상인지 확인하십시오. 스크립트 (옵션 a 또는 b)를 호출하면 트릭을 수행합니다.
  • CI에서 후크를 트리거하므로 CI에 대해 동일한 검사를 다시 작성할 필요가 없습니다. 예를 들어 커밋 및 푸시 트리거를 호출하는 것입니다. 위와 동일하게 해결해야합니다.
  • 마크 다운 검사기 또는 YAML 검사기와 같은 외부 도구를 호출하십시오. syscall을 수행 할 수 있으며 STDOUT 및 STDERR을 처리해야합니다.
  • 모든 개발자가 후크를 설치하는 간단한 방법을 갖도록하십시오. 따라서 기본 후크를 올바른 후크로 바꾸려면 멋진 스크립트를 저장소에 추가해야합니다.
  • 분기를 개발하고 마스터하기위한 커밋을 차단하기위한 검사와 같은 일부 글로벌 도우미를 보유하고 모든 저장소에 추가하지 않아도됩니다. 글로벌 스크립트가있는 다른 저장소를 사용하여이를 해결할 수 있습니다.

이것이 더 간단 할 수 있습니까?

예, 자식 후크를 관리하는 데 도움이되는 몇 가지 도구가 있습니다. 각각은 다른 관점에서 문제를 해결하기 위해 만들어졌으며, 여러분이나 팀에 가장 적합한 것을 얻기 위해 모든 문제를 이해해야 할 수도 있습니다. GitHooks.com 은 후크에 대한 많은 정보와 오늘날 사용 가능한 몇 가지 도구를 제공합니다.

오늘 현재, git hooks을 관리하기위한 다양한 전략과 함께 21 개의 프로젝트가 나열되어 있습니다. 일부는 단일 후크, 특정 언어 등에 대해서만 수행합니다.

내가 작성한 도구 중 하나이며 오픈 소스 프로젝트로 무료로 제공되는 도구는 hooks4git 입니다. 파이썬으로 작성되었지만 (내가 좋아하기 때문에) 아이디어는 .hooks4git.ini라는 단일 구성 파일에서 위에 나열된 모든 항목을 처리하는 것입니다. .

git hooks를 사용하는 것은 절대적으로 환상적이지만, 제공되는 방식은 일반적으로 사람들을 멀리합니다.


나는 얼마 전에 매우 짧은 버전을 게시했으며 중재자와 합의하여 설명을 제공하며 다른 개발자에게 도움이 될 수 있다고 생각한 도구에 대한 간단한 링크가 있습니다.
Lovato

1

gradle 사용자의 경우

내가 발견 이 스크립트는 Gradle을 프로젝트에 매우 유용합니다.

build.gradle

apply from: rootProject.file('gradle/install-git-hooks.gradle')

gradle / install-git-hooks.gradle

tasks.create(name: 'gitExecutableHooks') {
    doLast {
        Runtime.getRuntime().exec("chmod -R +x .git/hooks/");
    }
}
task installGitHooks(type: Copy) {
    from new File(rootProject.rootDir, 'pre-commit')
    into { new File(rootProject.rootDir, '.git/hooks') }
}
gitExecutableHooks.dependsOn installGitHooks
clean.dependsOn gitExecutableHooks

사전 커밋

.... your pre commit scripts goes here
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.