双方向ミラーリング

13.9でGitLab Premiumに移行しました。

caution
双方向ミラーリングは競合を引き起こす可能性があります。

双方向ミラーリングは、2つのリポジトリが互いにプル、プッシュするように設定します。どちらのリポジトリもエラーなく更新できる保証はありません。

双方向ミラーリングで競合を減らす

双方向ミラーリングを設定する場合、コンフリクトに備えてリポジトリを準備してください。コンフリクトを減らす設定と、コンフリクトが発生した場合の解決方法について説明します:

  • 保護されたブランチのみをミラーします。ミラーリングされたコミットをどちらかのリモートで書き換えると、コンフリクトが発生し、ミラーリングが失敗します。
  • 両方のリモートでミラーしたいブランチを保護し、履歴の書き換えによるコンフリクトを防ぎましょう。
  • プッシュイベントの Webhook を使って、ミラーリングの遅延を減らしましょう。双方向ミラーリングを行うと、同じブランチへのコミットが近いところで競合が発生するという競合状態が発生します。プッシュイベント Webhook を使えば、競合状態を緩和することができます。GitLabからのプッシュミラーリングは、保護されたブランチのみをプッシュミラーリングする場合、1分間に1回にレートが制限されます。
  • 受信前フックを使って競合を防ぎましょう。

GitLabへの即時プルをトリガーするWebhookの設定

ダウンストリームインスタンスでプッシュイベントの Webhook を使うと、変更をより頻繁に同期して競合状態を減らすことができます。

前提条件:

ダウンストリームインスタンスで Webhook を作成するには、次のようにします:

  1. API スコープで個人アクセストークンを作成します。
  2. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  3. 左サイドバーで、[設定] > [Webhooks]を選択します。
  4. WebhookURL を追加します。(この場合)Pull Mirror APIリクエストを使用して、リポジトリ更新後に即時プルをトリガーします:

    https://gitlab.example.com/api/v4/projects/:id/mirror/pull?private_token=<your_access_token>
    
  5. Push Events を選択します。
  6. Webhookを追加]を選択します。

インテグレーションをテストするには、Testを選択し、GitLabがエラーメッセージを返さないことを確認します。

事前受信フックを使ってコンフリクトを防ぎましょう

caution
Git のプッシュオペレーションはアップストリームの Git リポジトリにプロキシされるので、この解決策はパフォーマンスに悪影響を及ぼします。

この設定では、一方の Git リポジトリが権威あるアップストリーム、もう一方がダウンストリームとして振る舞います。このサーバー側のpre-receive フックは、まずアップストリームリポジトリにコミットをプッシュした後にのみプッシュを受け付けます。このフックをダウンストリームリポジトリにインストールしましょう。

使用例:

#!/usr/bin/env bash

# --- Assume only one push mirror target
# Push mirroring remotes are named `remote_mirror_<id>`.
# This line finds the first remote and uses that.
TARGET_REPO=$(git remote | grep -m 1 remote_mirror)

proxy_push()
{
  # --- Arguments
  OLDREV=$(git rev-parse $1)
  NEWREV=$(git rev-parse $2)
  REFNAME="$3"

  # --- Pattern of branches to proxy pushes
  allowlist=$(expr "$branch" : "\(master\)")

  case "$refname" in
    refs/heads/*)
      branch=$(expr "$refname" : "refs/heads/\(.*\)")

      if [ "$allowlist" = "$branch" ]; then
        # handle 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 " Error: updates were rejected by upstream server"
          echo >&2 "   This is usually caused by another repository pushing changes"
          echo >&2 "   to the same ref. You may want to first integrate remote changes"
          echo >&2 ""
          return
        fi
      fi
      ;;
  esac
}

# Allow dual mode: run from the command line just like the update hook, or
# if no arguments are given, then run as a hook script:
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
  # Output to the terminal in command line mode. If someone wanted to
  # resend an email, they could redirect the output to sendmail themselves
  PAGER= proxy_push $2 $3 $1
else
  # Push is proxied upstream one ref at a time. It is possible for some refs
  # to succeed, and others to fail. This results in a failed push.
  while read oldrev newrev refname
  do
    proxy_push $oldrev $newrev $refname
  done
fi

このサンプルにはいくつかの制限があります:

  • このサンプルにはいくつかの制限があります:
    • ミラーのさまざまな種類の認証メカニズムに対応していません。
    • 強制更新 (履歴の書き換え) では動作しません。
    • allowlist パターンにマッチするブランチだけがプロキシプッシュされます。
  • このスクリプトは Git のフック検疫環境を回避します。$TARGET_REPO の更新は ref update とみなされ、Git が警告を表示するからです。

Perforce Helix と Git Fusion のミラーリング

13.9でGitLab Premiumに移行しました。

caution
双方向ミラーリングは永続的な設定として使用しないでください。別のマイグレーション方法については、Perforce Helixからのマイグレーションを参照してください。

Git Fusionは、Perforce Helix への Git インターフェースを提供します。GitLabは、Perforce Helixインターフェイスを使用してプロジェクトを双方向ミラーリングすることができます。Perforce HelixからGitLabにマイグレーションする際、重複するPerforce Helixワークスペースを同時にマイグレーションできない場合に役立ちます。

Perforce Helix でミラーする場合は、保護されたブランチのみをミラーしてください。Perforce Helix は、履歴を書き換えるようなプッシュを拒否します。Git Fusion のパフォーマンス制限のため、ミラーリングするブランチは最少数にしてください。

Git Fusion を使用して Perforce Helix とのミラーリングを設定する場合は、以下の Git Fusion 設定を推奨します:

  • change-pusher を無効にします。そうしないと、すべてのコミットが、既存の Perforce Helix ユーザーやunknown_git ユーザーにマッピングされるのではなく、ミラーリングアカウントによってコミットされたものとして書き換わります。
  • GitLab ユーザーが Perforce Helix に存在しない場合は、unknown_git ユーザーをコミット作成者として使用します。

Git Fusion の設定については、Perforce.com を参照してください。