InfoGrab DocsInfoGrab Docs

Git 서버 훅

요약

Git 서버 훅은 GitLab 서버에서 사용자 정의 로직을 실행합니다. Git 서버 훅은 pre-receive, post-receive, update Git 서버 사이드 훅을 사용합니다. GitLab 관리자는 gitaly 명령으로 서버 훅을 구성합니다.

Git 서버 훅은 GitLab 서버에서 사용자 정의 로직을 실행합니다. 다음과 같은 Git 관련 작업을 실행하는 데 사용할 수 있습니다.

  • 특정 커밋 정책 적용
  • 리포지터리 상태에 따른 작업 수행

Git 서버 훅은 pre-receive, post-receive, update Git 서버 사이드 훅을 사용합니다.

GitLab 관리자는 gitaly 명령으로 서버 훅을 구성합니다. 이 명령은 다음 역할도 합니다.

  • Gitaly 서버를 실행합니다.
  • 여러 하위 명령을 제공합니다.
  • Gitaly gRPC API에 연결합니다.

gitaly 명령을 사용할 수 없다면 서버 훅의 대안은 다음과 같습니다.

GitLab Helm 차트 인스턴스는 Gitaly 차트의 글로벌 서버 훅 정보를 참고합니다.

Note

Geo는 보조 노드로 서버 훅을 복제하지 않습니다.

사전 요구 사항#

  • 리포지터리의 스토리지 이름, Gitaly 구성 파일 경로 (Linux 패키지 인스턴스의 기본값은 /var/opt/gitlab/gitaly/config.toml), 리포지터리 상대 경로가 필요합니다.
  • 훅에 필요한 언어 런타임과 유틸리티를 Gitaly를 실행하는 각 서버에 설치해야 합니다.

리포지터리에 서버 훅 설정#

리포지터리에 서버 훅을 설정하는 방법은 다음과 같습니다.

  1. 사용자 정의 훅이 담긴 tar 파일을 생성합니다.

    1. 서버 훅이 의도대로 동작하도록 코드를 작성합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 맨 위의 shebang이 언어 유형과 맞는지 확인합니다. 예를 들어 스크립트가 Ruby라면 shebang은 대개 #!/usr/bin/env ruby입니다.

      • 서버 훅을 하나만 만들려면 훅 유형과 이름이 같은 파일을 만듭니다. 예를 들어 pre-receive 서버 훅이라면 파일 이름은 확장자 없이 pre-receive여야 합니다.
      • 서버 훅을 여러 개 만들려면 훅 유형과 이름이 같은 디렉터리를 만듭니다. 예를 들어 pre-receive 서버 훅이라면 디렉터리 이름은 pre-receive.d여야 합니다. 훅 파일은 그 디렉터리에 넣습니다.
    2. 서버 훅 파일이 실행 가능하고 백업 파일 패턴(*~)과 일치하지 않는지 확인합니다. 서버 훅은 tar 파일 루트의 custom_hooks 디렉터리에 있어야 합니다.

    3. tar 명령으로 사용자 정의 훅 아카이브를 생성합니다. 예를 들면 tar -cf custom_hooks.tar custom_hooks입니다.

  2. 리포지터리의 Git 훅을 설정하도록 필요한 옵션과 함께 hooks set 하위 명령을 실행합니다. 예를 들면 다음과 같습니다.

    cat custom_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
    
    • 노드에 연결하려면 해당 노드의 유효한 Gitaly 구성 경로가 필요하며, 이 경로를 --config 플래그에 전달합니다.

    • 사용자 정의 훅 tar 파일은 stdin으로 전달해야 합니다. 예를 들면 다음과 같습니다.

      cat custom_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
      
  3. Gitaly 클러스터(Praefect)를 사용한다면 모든 Gitaly 노드에서 hooks set 하위 명령을 실행해야 합니다.

서버 훅 코드를 올바르게 구현했다면 Git 훅이 다음에 트리거될 때 실행됩니다.

Gitaly 클러스터(Praefect)의 서버 훅#

Gitaly 클러스터(Praefect)를 사용하면 하나의 리포지터리가 Praefect의 여러 Gitaly 스토리지로 복제될 수 있습니다. 따라서 훅 스크립트를 해당 리포지터리의 복제본이 있는 모든 Gitaly 노드에 복사해야 합니다. 해당 버전의 사용자 정의 리포지터리 훅 설정 절차를 그대로 따르되 스토리지마다 반복합니다.

스크립트를 복사할 위치는 리포지터리가 저장된 위치에 따라 달라집니다. 새 리포지터리는 해시 스토리지 경로가 아니라 Praefect가 생성한 복제본 경로로 생성됩니다. 복제본 경로를 확인하려면 -relative-path 옵션으로 예상되는 GitLab 해시 스토리지 경로를 지정해 Praefect 리포지터리 메타데이터를 조회합니다.

모든 리포지터리에 적용되는 글로벌 서버 훅 생성#

모든 리포지터리에 적용되는 Git 훅을 만들려면 글로벌 서버 훅을 설정합니다. 글로벌 서버 훅은 다음에도 적용됩니다.

  • 프로젝트 및 그룹 위키 리포지터리. 스토리지 디렉터리 이름은 <id>.wiki.git 형식입니다.
  • 프로젝트 하위의 디자인 관리 리포지터리. 스토리지 디렉터리 이름은 <id>.design.git 형식입니다.

서버 훅 디렉터리 선택#

글로벌 서버 훅을 만들기 전에 사용할 디렉터리를 먼저 선택해야 합니다.

디렉터리는 gitlab.rb의 gitaly['configuration'][:hooks][:custom_hooks_dir]에서 설정합니다. 다음 중 하나를 선택합니다.

  • 주석을 해제해 기본 제안값인 /var/opt/gitlab/gitaly/custom_hooks 디렉터리를 사용합니다.
  • 직접 설정값을 추가합니다.
  • 디렉터리는 gitaly/config.toml의 [hooks] 섹션에서 설정합니다. 다만 gitaly/config.toml의 값이 비어 있거나 없으면 GitLab은 gitlab-shell/config.yml의 custom_hooks_dir 값을 사용합니다.
  • 기본 디렉터리는 /home/git/gitlab-shell/hooks입니다.

글로벌 서버 훅 생성#

모든 리포지터리에 적용되는 글로벌 서버 훅을 만드는 방법은 다음과 같습니다.

  1. GitLab 서버에서 구성된 글로벌 서버 훅 디렉터리로 이동합니다.
  2. 구성된 글로벌 서버 훅 디렉터리에 훅 유형과 이름이 같은 디렉터리를 만듭니다. 예를 들어 pre-receive 서버 훅이라면 디렉터리 이름은 pre-receive.d여야 합니다.
  3. 이 새 디렉터리 안에 서버 훅을 추가합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 맨 위의 shebang(#!)이 언어 유형과 맞는지 확인합니다. 예를 들어 스크립트가 Ruby라면 shebang은 대개 #!/usr/bin/env ruby입니다.
  4. 훅 파일을 실행 가능하게 만들고, 소유자가 Git 사용자인지 확인하며, 백업 파일 패턴(*~)과 일치하지 않는지 확인합니다.

서버 훅 코드를 제대로 구현했다면 Git 훅이 다음에 트리거될 때 실행됩니다. 훅은 훅 유형 하위 디렉터리에서 파일 이름의 알파벳 순으로 실행됩니다.

리포지터리의 서버 훅 제거#

서버 훅을 제거하려면 빈 tar 파일을 hook set에 전달해 리포지터리에 훅이 없어야 함을 알립니다. 예를 들면 다음과 같습니다.

cat empty_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>

연결된 서버 훅#

GitLab은 서버 훅을 체인으로 실행할 수 있습니다. GitLab은 다음 순서로 서버 훅을 검색하고 실행합니다.

  • 내장 GitLab 서버 훅. 이 서버 훅은 사용자가 수정할 수 없습니다.
  • <project>.git/custom_hooks/<hook_name>: 프로젝트별 훅. 이 위치는 하위 호환성을 위해 유지됩니다.
  • <project>.git/custom_hooks/<hook_name>.d/*: 프로젝트별 훅 위치.
  • <custom_hooks_dir>/<hook_name>.d/*: 편집기 백업 파일을 제외한 모든 실행 가능한 글로벌 훅 파일 위치.

서버 훅 디렉터리에서 훅은 다음과 같이 동작합니다.

  • 알파벳 순으로 실행됩니다.
  • 훅이 0이 아닌 값으로 종료되면 실행이 중단됩니다.

서버 훅에서 사용할 수 있는 환경 변수#

서버 훅에 어떤 환경 변수든 전달할 수 있지만, 지원되는 환경 변수만 사용하는 것이 안전합니다.

모든 서버 훅에서 다음 GitLab 환경 변수를 지원합니다.

환경 변수 설명
GL_ID 푸시를 시작한 사용자 또는 SSH 키의 GitLab 식별자. 예: user-2234 또는 key-4.
GL_PROJECT_PATH GitLab 프로젝트 경로.
GL_PROTOCOL 이 변경에 사용된 프로토콜. http(HTTP를 사용한 Git push), ssh(SSH를 사용한 Git push), web(그 밖의 모든 작업) 중 하나.
GL_REPOSITORY project- 접두사가 붙은 GitLab 프로젝트 ID. 예: project-1234
GL_USERNAME 푸시를 시작한 사용자의 GitLab 사용자 이름.

pre-receive와 post-receive 서버 훅에서 다음 Git 환경 변수를 지원합니다.

환경 변수 설명
GIT_ALTERNATE_OBJECT_DIRECTORIES 격리 환경의 대체 오브젝트 디렉터리.
GIT_OBJECT_DIRECTORY 격리 환경의 GitLab 프로젝트 경로.
GIT_PUSH_OPTION_COUNT 푸시 옵션의 수.
GIT_PUSH_OPTION_<i> 특정 푸시 옵션의 값. <i>는 0부터 GIT_PUSH_OPTION_COUNT에 정의된 값보다 1 작은 값까지입니다.

사용자 정의 오류 메시지#

서버 훅이 푸시를 거부할 때는 사용자가 거부 사유와 해결 방법을 알 수 있도록 명확한 오류 메시지를 제공합니다. 사용자 정의 오류 메시지는 훅이 푸시를 거부할 때 GitLab UI와 사용자 터미널에 표시됩니다.

사용자 정의 오류 메시지가 없으면 사용자에게는 (pre-receive hook declined) 같은 일반 메시지만 보입니다. 명확한 오류 메시지는 사용자가 다음과 같이 대처하도록 돕습니다.

  • 푸시가 거부된 이유를 파악합니다.
  • 관리자에게 문의하지 않고 문제를 해결합니다.
  • 지원 요청을 줄입니다.

사용자 정의 오류 메시지를 표시하려면 스크립트가 다음을 수행해야 합니다.

  • 사용자 정의 오류 메시지를 스크립트의 stdout 또는 stderr로 전송합니다.
  • 각 메시지 앞에 GL-HOOK-ERR: 접두사를 붙이고, 접두사 앞에는 어떤 문자도 오지 않도록 합니다.

예를 들면 다음과 같습니다.

# Bad: Generic message
echo "GL-HOOK-ERR: Commit rejected.";

# Good: Specific message with action
echo "GL-HOOK-ERR: Commit rejected: Commit message must include an issue reference (for example, #1234).";

관련 주제#

문제 해결#

Git 서버 훅을 다룰 때 다음과 같은 문제가 발생할 수 있습니다.

오류: pre-receive hook declined#

사용자가 GitLab 리포지터리에 푸시할 때 (pre-receive hook declined)가 포함된 오류 메시지를 받을 수 있습니다. 예를 들면 다음과 같습니다.

! [remote rejected] main (pre-receive hook declined)
error: failed to push some refs to 'https://gitlab.example.com/group/project'

이 오류는 pre-receive 훅이 푸시를 거부했음을 의미합니다. pre-receive 훅은 리포지터리에서 참조가 갱신되기 전에 실행됩니다. Git은 푸시를 거부할 수 있는 서버 사이드 훅 세 가지를 제공합니다.

  • pre-receive: 참조가 갱신되기 전에 실행됩니다. 푸시 전체를 거부할 수 있습니다.
  • update: 갱신되는 브랜치마다 한 번씩 실행됩니다. 개별 브랜치를 거부할 수 있습니다.
  • post-receive: 모든 참조가 갱신된 뒤에 실행됩니다. 푸시를 거부할 수는 없지만 훅이 실패하면 오류가 발생할 수 있습니다.

(pre-receive hook declined) 오류는 보통 pre-receive 또는 update 훅에서 발생합니다. 원인을 확인하는 방법은 다음과 같습니다.

  1. (pre-receive hook declined) 메시지 바로 앞의 출력을 확인합니다. 이 출력에는 푸시가 거부된 이유가 담겨 있는 경우가 많습니다. 예를 들면 다음과 같습니다.

    remote: GitLab: The default branch of a project cannot be deleted.
    ! [remote rejected] main (pre-receive hook declined)
    
  2. 훅이 실패한 이유를 자세히 확인하려면 Gitaly 로그를 확인합니다.

    sudo grep PreReceiveHook /var/log/gitlab/gitaly/current | jq .
    
  3. 리포지터리에 사용자 정의 서버 훅이 구성되어 있다면 사용자 정의 훅 코드에 문제가 없는지 검토합니다.

pre-receive 훅 실패의 일반적인 원인은 다음과 같습니다.

  • 기본 브랜치 보호: 기본 브랜치를 삭제하거나 강제로 갱신하는 푸시는 거부됩니다. 소스 리포지터리의 기본 브랜치가 대상 리포지터리와 다를 때 git push --mirror에서 이 상황이 발생합니다.
  • 푸시 규칙: 커밋 메시지 요건, 파일 크기 제한, 작성자 이메일 제한 등 구성된 푸시 규칙을 푸시가 위반한 경우입니다.
  • 사용자 정의 서버 훅: 사용자 정의 서버 훅 스크립트가 푸시를 거부한 경우입니다. 사용자 정의 훅 코드와 오류 메시지를 검토합니다.
  • 타임아웃: 훅 실행이 너무 오래 걸려 중단된 경우입니다. Gitaly 로그에서 타임아웃 오류를 확인합니다.
  • LFS 오브젝트: 필요한 Git LFS 오브젝트가 리포지터리에 없는 경우입니다.

사용자가 훅 실패를 이해하도록 돕고 푸시가 거부된 이유를 명확히 전달하려면 사용자 정의 오류 메시지를 사용합니다. 사용자 정의 오류 메시지는 GitLab UI와 사용자 터미널에 표시됩니다.

Git 서버 훅

GitLab v19.5
Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기

요약

Git 서버 훅은 GitLab 서버에서 사용자 정의 로직을 실행합니다. Git 서버 훅은 pre-receive, post-receive, update Git 서버 사이드 훅을 사용합니다. GitLab 관리자는 gitaly 명령으로 서버 훅을 구성합니다.

Git 서버 훅은 GitLab 서버에서 사용자 정의 로직을 실행합니다. 다음과 같은 Git 관련 작업을 실행하는 데 사용할 수 있습니다.

  • 특정 커밋 정책 적용
  • 리포지터리 상태에 따른 작업 수행

Git 서버 훅은 pre-receive, post-receive, update Git 서버 사이드 훅을 사용합니다.

GitLab 관리자는 gitaly 명령으로 서버 훅을 구성합니다. 이 명령은 다음 역할도 합니다.

  • Gitaly 서버를 실행합니다.
  • 여러 하위 명령을 제공합니다.
  • Gitaly gRPC API에 연결합니다.

gitaly 명령을 사용할 수 없다면 서버 훅의 대안은 다음과 같습니다.

GitLab Helm 차트 인스턴스는 Gitaly 차트의 글로벌 서버 훅 정보를 참고합니다.

Note

Geo는 보조 노드로 서버 훅을 복제하지 않습니다.

사전 요구 사항#

  • 리포지터리의 스토리지 이름, Gitaly 구성 파일 경로 (Linux 패키지 인스턴스의 기본값은 /var/opt/gitlab/gitaly/config.toml), 리포지터리 상대 경로가 필요합니다.
  • 훅에 필요한 언어 런타임과 유틸리티를 Gitaly를 실행하는 각 서버에 설치해야 합니다.

리포지터리에 서버 훅 설정#

리포지터리에 서버 훅을 설정하는 방법은 다음과 같습니다.

  1. 사용자 정의 훅이 담긴 tar 파일을 생성합니다.

    1. 서버 훅이 의도대로 동작하도록 코드를 작성합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 맨 위의 shebang이 언어 유형과 맞는지 확인합니다. 예를 들어 스크립트가 Ruby라면 shebang은 대개 #!/usr/bin/env ruby입니다.

      • 서버 훅을 하나만 만들려면 훅 유형과 이름이 같은 파일을 만듭니다. 예를 들어 pre-receive 서버 훅이라면 파일 이름은 확장자 없이 pre-receive여야 합니다.
      • 서버 훅을 여러 개 만들려면 훅 유형과 이름이 같은 디렉터리를 만듭니다. 예를 들어 pre-receive 서버 훅이라면 디렉터리 이름은 pre-receive.d여야 합니다. 훅 파일은 그 디렉터리에 넣습니다.
    2. 서버 훅 파일이 실행 가능하고 백업 파일 패턴(*~)과 일치하지 않는지 확인합니다. 서버 훅은 tar 파일 루트의 custom_hooks 디렉터리에 있어야 합니다.

    3. tar 명령으로 사용자 정의 훅 아카이브를 생성합니다. 예를 들면 tar -cf custom_hooks.tar custom_hooks입니다.

  2. 리포지터리의 Git 훅을 설정하도록 필요한 옵션과 함께 hooks set 하위 명령을 실행합니다. 예를 들면 다음과 같습니다.

    cat custom_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
    
    • 노드에 연결하려면 해당 노드의 유효한 Gitaly 구성 경로가 필요하며, 이 경로를 --config 플래그에 전달합니다.

    • 사용자 정의 훅 tar 파일은 stdin으로 전달해야 합니다. 예를 들면 다음과 같습니다.

      cat custom_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
      
  3. Gitaly 클러스터(Praefect)를 사용한다면 모든 Gitaly 노드에서 hooks set 하위 명령을 실행해야 합니다.

서버 훅 코드를 올바르게 구현했다면 Git 훅이 다음에 트리거될 때 실행됩니다.

Gitaly 클러스터(Praefect)의 서버 훅#

Gitaly 클러스터(Praefect)를 사용하면 하나의 리포지터리가 Praefect의 여러 Gitaly 스토리지로 복제될 수 있습니다. 따라서 훅 스크립트를 해당 리포지터리의 복제본이 있는 모든 Gitaly 노드에 복사해야 합니다. 해당 버전의 사용자 정의 리포지터리 훅 설정 절차를 그대로 따르되 스토리지마다 반복합니다.

스크립트를 복사할 위치는 리포지터리가 저장된 위치에 따라 달라집니다. 새 리포지터리는 해시 스토리지 경로가 아니라 Praefect가 생성한 복제본 경로로 생성됩니다. 복제본 경로를 확인하려면 -relative-path 옵션으로 예상되는 GitLab 해시 스토리지 경로를 지정해 Praefect 리포지터리 메타데이터를 조회합니다.

모든 리포지터리에 적용되는 글로벌 서버 훅 생성#

모든 리포지터리에 적용되는 Git 훅을 만들려면 글로벌 서버 훅을 설정합니다. 글로벌 서버 훅은 다음에도 적용됩니다.

  • 프로젝트 및 그룹 위키 리포지터리. 스토리지 디렉터리 이름은 <id>.wiki.git 형식입니다.
  • 프로젝트 하위의 디자인 관리 리포지터리. 스토리지 디렉터리 이름은 <id>.design.git 형식입니다.

서버 훅 디렉터리 선택#

글로벌 서버 훅을 만들기 전에 사용할 디렉터리를 먼저 선택해야 합니다.

디렉터리는 gitlab.rb의 gitaly['configuration'][:hooks][:custom_hooks_dir]에서 설정합니다. 다음 중 하나를 선택합니다.

  • 주석을 해제해 기본 제안값인 /var/opt/gitlab/gitaly/custom_hooks 디렉터리를 사용합니다.
  • 직접 설정값을 추가합니다.
  • 디렉터리는 gitaly/config.toml의 [hooks] 섹션에서 설정합니다. 다만 gitaly/config.toml의 값이 비어 있거나 없으면 GitLab은 gitlab-shell/config.yml의 custom_hooks_dir 값을 사용합니다.
  • 기본 디렉터리는 /home/git/gitlab-shell/hooks입니다.

글로벌 서버 훅 생성#

모든 리포지터리에 적용되는 글로벌 서버 훅을 만드는 방법은 다음과 같습니다.

  1. GitLab 서버에서 구성된 글로벌 서버 훅 디렉터리로 이동합니다.
  2. 구성된 글로벌 서버 훅 디렉터리에 훅 유형과 이름이 같은 디렉터리를 만듭니다. 예를 들어 pre-receive 서버 훅이라면 디렉터리 이름은 pre-receive.d여야 합니다.
  3. 이 새 디렉터리 안에 서버 훅을 추가합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 맨 위의 shebang(#!)이 언어 유형과 맞는지 확인합니다. 예를 들어 스크립트가 Ruby라면 shebang은 대개 #!/usr/bin/env ruby입니다.
  4. 훅 파일을 실행 가능하게 만들고, 소유자가 Git 사용자인지 확인하며, 백업 파일 패턴(*~)과 일치하지 않는지 확인합니다.

서버 훅 코드를 제대로 구현했다면 Git 훅이 다음에 트리거될 때 실행됩니다. 훅은 훅 유형 하위 디렉터리에서 파일 이름의 알파벳 순으로 실행됩니다.

리포지터리의 서버 훅 제거#

서버 훅을 제거하려면 빈 tar 파일을 hook set에 전달해 리포지터리에 훅이 없어야 함을 알립니다. 예를 들면 다음과 같습니다.

cat empty_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>

연결된 서버 훅#

GitLab은 서버 훅을 체인으로 실행할 수 있습니다. GitLab은 다음 순서로 서버 훅을 검색하고 실행합니다.

  • 내장 GitLab 서버 훅. 이 서버 훅은 사용자가 수정할 수 없습니다.
  • <project>.git/custom_hooks/<hook_name>: 프로젝트별 훅. 이 위치는 하위 호환성을 위해 유지됩니다.
  • <project>.git/custom_hooks/<hook_name>.d/*: 프로젝트별 훅 위치.
  • <custom_hooks_dir>/<hook_name>.d/*: 편집기 백업 파일을 제외한 모든 실행 가능한 글로벌 훅 파일 위치.

서버 훅 디렉터리에서 훅은 다음과 같이 동작합니다.

  • 알파벳 순으로 실행됩니다.
  • 훅이 0이 아닌 값으로 종료되면 실행이 중단됩니다.

서버 훅에서 사용할 수 있는 환경 변수#

서버 훅에 어떤 환경 변수든 전달할 수 있지만, 지원되는 환경 변수만 사용하는 것이 안전합니다.

모든 서버 훅에서 다음 GitLab 환경 변수를 지원합니다.

환경 변수 설명
GL_ID 푸시를 시작한 사용자 또는 SSH 키의 GitLab 식별자. 예: user-2234 또는 key-4.
GL_PROJECT_PATH GitLab 프로젝트 경로.
GL_PROTOCOL 이 변경에 사용된 프로토콜. http(HTTP를 사용한 Git push), ssh(SSH를 사용한 Git push), web(그 밖의 모든 작업) 중 하나.
GL_REPOSITORY project- 접두사가 붙은 GitLab 프로젝트 ID. 예: project-1234
GL_USERNAME 푸시를 시작한 사용자의 GitLab 사용자 이름.

pre-receive와 post-receive 서버 훅에서 다음 Git 환경 변수를 지원합니다.

환경 변수 설명
GIT_ALTERNATE_OBJECT_DIRECTORIES 격리 환경의 대체 오브젝트 디렉터리.
GIT_OBJECT_DIRECTORY 격리 환경의 GitLab 프로젝트 경로.
GIT_PUSH_OPTION_COUNT 푸시 옵션의 수.
GIT_PUSH_OPTION_<i> 특정 푸시 옵션의 값. <i>는 0부터 GIT_PUSH_OPTION_COUNT에 정의된 값보다 1 작은 값까지입니다.

사용자 정의 오류 메시지#

서버 훅이 푸시를 거부할 때는 사용자가 거부 사유와 해결 방법을 알 수 있도록 명확한 오류 메시지를 제공합니다. 사용자 정의 오류 메시지는 훅이 푸시를 거부할 때 GitLab UI와 사용자 터미널에 표시됩니다.

사용자 정의 오류 메시지가 없으면 사용자에게는 (pre-receive hook declined) 같은 일반 메시지만 보입니다. 명확한 오류 메시지는 사용자가 다음과 같이 대처하도록 돕습니다.

  • 푸시가 거부된 이유를 파악합니다.
  • 관리자에게 문의하지 않고 문제를 해결합니다.
  • 지원 요청을 줄입니다.

사용자 정의 오류 메시지를 표시하려면 스크립트가 다음을 수행해야 합니다.

  • 사용자 정의 오류 메시지를 스크립트의 stdout 또는 stderr로 전송합니다.
  • 각 메시지 앞에 GL-HOOK-ERR: 접두사를 붙이고, 접두사 앞에는 어떤 문자도 오지 않도록 합니다.

예를 들면 다음과 같습니다.

# Bad: Generic message
echo "GL-HOOK-ERR: Commit rejected.";

# Good: Specific message with action
echo "GL-HOOK-ERR: Commit rejected: Commit message must include an issue reference (for example, #1234).";

관련 주제#

문제 해결#

Git 서버 훅을 다룰 때 다음과 같은 문제가 발생할 수 있습니다.

오류: pre-receive hook declined#

사용자가 GitLab 리포지터리에 푸시할 때 (pre-receive hook declined)가 포함된 오류 메시지를 받을 수 있습니다. 예를 들면 다음과 같습니다.

! [remote rejected] main (pre-receive hook declined)
error: failed to push some refs to 'https://gitlab.example.com/group/project'

이 오류는 pre-receive 훅이 푸시를 거부했음을 의미합니다. pre-receive 훅은 리포지터리에서 참조가 갱신되기 전에 실행됩니다. Git은 푸시를 거부할 수 있는 서버 사이드 훅 세 가지를 제공합니다.

  • pre-receive: 참조가 갱신되기 전에 실행됩니다. 푸시 전체를 거부할 수 있습니다.
  • update: 갱신되는 브랜치마다 한 번씩 실행됩니다. 개별 브랜치를 거부할 수 있습니다.
  • post-receive: 모든 참조가 갱신된 뒤에 실행됩니다. 푸시를 거부할 수는 없지만 훅이 실패하면 오류가 발생할 수 있습니다.

(pre-receive hook declined) 오류는 보통 pre-receive 또는 update 훅에서 발생합니다. 원인을 확인하는 방법은 다음과 같습니다.

  1. (pre-receive hook declined) 메시지 바로 앞의 출력을 확인합니다. 이 출력에는 푸시가 거부된 이유가 담겨 있는 경우가 많습니다. 예를 들면 다음과 같습니다.

    remote: GitLab: The default branch of a project cannot be deleted.
    ! [remote rejected] main (pre-receive hook declined)
    
  2. 훅이 실패한 이유를 자세히 확인하려면 Gitaly 로그를 확인합니다.

    sudo grep PreReceiveHook /var/log/gitlab/gitaly/current | jq .
    
  3. 리포지터리에 사용자 정의 서버 훅이 구성되어 있다면 사용자 정의 훅 코드에 문제가 없는지 검토합니다.

pre-receive 훅 실패의 일반적인 원인은 다음과 같습니다.

  • 기본 브랜치 보호: 기본 브랜치를 삭제하거나 강제로 갱신하는 푸시는 거부됩니다. 소스 리포지터리의 기본 브랜치가 대상 리포지터리와 다를 때 git push --mirror에서 이 상황이 발생합니다.
  • 푸시 규칙: 커밋 메시지 요건, 파일 크기 제한, 작성자 이메일 제한 등 구성된 푸시 규칙을 푸시가 위반한 경우입니다.
  • 사용자 정의 서버 훅: 사용자 정의 서버 훅 스크립트가 푸시를 거부한 경우입니다. 사용자 정의 훅 코드와 오류 메시지를 검토합니다.
  • 타임아웃: 훅 실행이 너무 오래 걸려 중단된 경우입니다. Gitaly 로그에서 타임아웃 오류를 확인합니다.
  • LFS 오브젝트: 필요한 Git LFS 오브젝트가 리포지터리에 없는 경우입니다.

사용자가 훅 실패를 이해하도록 돕고 푸시가 거부된 이유를 명확히 전달하려면 사용자 정의 오류 메시지를 사용합니다. 사용자 정의 오류 메시지는 GitLab UI와 사용자 터미널에 표시됩니다.