양방향 미러링

Tier: Premium, Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated
History
  • Moved to GitLab Premium in 13.9.
caution
양방향 미러링은 충돌을 발생시킬 수 있습니다.

양방향 미러링은 두 리포지터리가 서로에게 풀 및 푸시하는 방식으로 구성됩니다. 어느 리포지터리도 오류 없이 업데이트될 수 있다는 보장은 없습니다.

양방향 미러링에서의 충돌 감소

양방향 미러링을 구성하면 충돌을 준비하세요. 충돌을 줄이도록 구성하고 발생시에는 어떻게 해결할지 구성합니다:

  • 보호된 브랜치만 미러링. 어느 원격 리포지터리에서든 미러링된 커밋을 다시 작성하면 충돌이 발생하고 미러링이 실패합니다.
  • 충돌을 방지하려면 양쪽 원격 리포지터리에 브랜치를 보호하세요. 이를 통해 히스토리를 다시 작성하면서 발생하는 충돌을 방지할 수 있습니다.
  • 푸시 이벤트 웹훅으로 미러링 지연을 줄입니다. 양방향 미러링은 동시에 같은 브랜치에 가까운 시점에 만든 커밋이 충돌을 발생시킬 수 있는 경합 조건을 만듭니다. 푸시 이벤트 웹훅은 경합 조건을 완화하는 데 도움이 됩니다. GitLab에서의 푸시 미러링은 보호된 브랜치에 대해서만 분당 한 번으로 제한됩니다.
  • 충돌을 방지하기 위해 프리-리시브 후크를 사용하세요.

GitLab에서 즉시 풀을 트리거하기 위한 웹훅 구성

다운스트림 인스턴스의 푸시 이벤트 웹훅은 변경 사항을 더 자주 동기화하여 경합 조건을 줄일 수 있습니다.

전제 조건:

  • 원격 GitLab 인스턴스에서 푸시 미러를 구성했습니다.

다음과 같이 다운스트림 인스턴스에서 웹훅을 생성하세요:

  1. API 스코프로 개인 액세스 토큰을 구성하세요.
  2. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  3. 설정 > 웹훅을 선택합니다.
  4. (이 경우) 풀 미러링 API 요청을 사용하여 리포지터리 업데이트 후 즉시 풀을 트리거하는 웹훅 URL을 추가합니다:

    https://gitlab.example.com/api/v4/projects/:id/mirror/pull?private_token=<your_access_token>
    
  5. 푸시 이벤트를 선택합니다.
  6. 웹훅 추가를 선택합니다.

통합을 테스트하려면 테스트를 선택하고 GitLab에서 오류 메시지를 반환하지 않는지 확인합니다.

프리-리시브 후크를 사용하여 충돌 방지

caution
이 해결책은 Git 푸시 작업의 성능에 부정적인 영향을 미칩니다. 왜냐하면 이것들은 상류 Git 리포지터리에 프록시됩니다.

이 구성에서 한 Git 리포지터리가 권위 있는 상류로 동작하고 다른 리포지터리가 하류로 동작합니다. 이 서버 측 프리-리시브 후크는 처음에는 커밋을 상류 리포지터리에 푸시한 후에만 푸시를 허용합니다. 이 후크를 다운스트림 리포지터리에 설치하세요.

예를 들면:

#!/usr/bin/env bash

# --- Assume only one push mirror target
# 푸시 미러링 원격 리포지터리는 `remote_mirror_<id>`로 이름이 지어집니다.
# 이 줄은 첫 번째 원격을 찾아 사용합니다.
TARGET_REPO=$(git remote | grep -m 1 remote_mirror)

proxy_push()
{
  # --- 인수
  OLDREV=$(git rev-parse $1)
  NEWREV=$(git rev-parse $2)
  REFNAME="$3"
  
  # --- 프로키시 푸시할 브랜치 패턴
  allowlist=$(expr "$branch" : "\(master\)")
  
  case "$refname" in
    refs/heads/*)
      branch=$(expr "$refname" : "refs/heads/\(.*\)")
      
      if [ "$allowlist" = "$branch" ]; then
        # https://git-scm.com/docs/git-receive-pack#_quarantine_environment 처리
        unset GIT_QUARANTINE_PATH
        error="$(git push --quiet $TARGET_REPO $NEWREV:$REFNAME 2>&1)"
        fail=$?
        
        if [ "$fail" != "0" ]; then
          echo >&2 ""
          echo >&2 " 에러: 업스트림 서버에 의해 업데이트가 거부되었습니다"
          echo >&2 "   일반적으로 동일한 레퍼런스로 변경사항을 푸시하는 다른 리포지터리에 의해 발생합니다"
          echo >&2 "   원격 변경 사항을 먼저 통합하는 것이 좋습니다"
          echo >&2 ""
          return
        fi
      fi
      ;;
  esac
}

# 이 스크립트에는 몇 가지 제한 사항이 있습니다:
# - 이때 개정없이 여러 가지 사용 사례에 적합하지 않을 수 있습니다.
#   - 미러링에 대해 다른 인증 메커니즘을 고려하지 않습니다.
#   - 강제 업데이트(히스토리 다시 쓰기)와 작동하지 않습니다.
#   - `allowlist` 패턴에 일치하는 브랜치만 프록시 푸시됩니다.
# - 스크립트는 Git 후크 격리 환경을 우회합니다. 왜냐하면 `$TARGET_REPO`의 업데이트가 레퍼런스 업데이트로 인식되고 Git에서 그에 대해 경고를 표시하기 때문입니다.

# 듀얼 모드 허용: 명령줄에서 업데이트 후크처럼 실행하거나
# 인수가 주어지지 않으면 후크 스크립트로 실행하세요:
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
  # 명령행 모드에서 터미널에 출력합니다. 누군가는
  # 직접 `/usr/sbin/sendmail`로 출력을 리디렉션할 수 있습니다.
  PAGER= proxy_push $2 $3 $1
else
  # 푸시는 한 번에 한 번씩 상류로 프록시됩니다. 일부 레퍼런스가 성공하고, 다른 레퍼런스가 실패할 수 있습니다. 이는 실패한 푸시로 이어집니다.
  while read oldrev newrev refname
  do
    proxy_push $oldrev $newrev $refname
  done
fi

이 샘플은 몇 가지 제한 사항이 있습니다:

  • 수정 없이 사용 사례에 적합하지 않을 수 있습니다:
    • 미러링의 다른 인증 메커니즘을 고려하지 않습니다.
    • 강제 업데이트(히스토리 다시 쓰기)와 작동하지 않습니다.
    • allowlist 패턴과 일치하는 브랜치만 프록시 푸시됩니다.
  • 이 스크립트는 Git 후크 격리 환경을 우회합니다. 왜냐하면 $TARGET_REPO의 업데이트가 레퍼런스 업데이트로 인식되고 Git에서 그에 대해 경고를 표시하기 때문입니다.

Git Fusion을 사용한 Perforce Helix와의 미러링

Tier: Premium, Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated
History
  • Moved to GitLab Premium in 13.9.
caution
양방향 미러링은 영구적인 구성으로 사용해서는 안 됩니다. 대체 마이그레이션 접근 방법을 위해 Perforce Helix에서의 마이그레이션을 참조하세요.

Git FusionPerforce Helix에 대한 Git 인터페이스를 제공합니다. GitLab은 Perforce Helix 프로젝트를 양방향 미러링할 수 있도록 Perforce Helix 인터페이스를 사용할 수 있습니다. Perforce Helix 작업공간이 중첩되어 동시에 마이그레이션할 수 없는 경우에 GitLab으로부터 Perforce Helix로 마이그레이션할 때 도움이 될 수 있습니다.

Perforce Helix로 미러링하는 경우 보호된 브랜치만 미러링하세요. Perforce Helix는 히스토리를 다시 쓰는 푸시를 거부합니다. Git Fusion의 성능 제한 때문에 가능한 최소한의 수의 브랜치만 미러링해야 합니다.

Perforce Helix를 사용한 미러링(Git Fusion 사용)을 구성할 때 다음과 같은 Git Fusion 설정을 권장합니다:

  • change-pusher를 비활성화하세요. 그렇지 않으면 모든 커밋이 미러링된 계정으로 커밋된 것으로 다시 작성되며, 기존 Perforce Helix 사용자 또는 unknown_git 사용자에 맵핑되지 않습니다.
  • GitLab 사용자가 Perforce Helix에 존재하지 않는 경우 unknown_git 사용자를 커밋 작성자로 사용하세요.

Perforce.com에서 Git Fusion 설정에 대해 읽어보세요.

관련 주제