Commit 702f4282 authored by Amy Qualls's avatar Amy Qualls Committed by Suzanne Selhorn

CTRT edits to bidirectional page

parent fd692476
...@@ -12,68 +12,73 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/repository_mirroring.htm ...@@ -12,68 +12,73 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/repository_mirroring.htm
WARNING: WARNING:
Bidirectional mirroring may cause conflicts. Bidirectional mirroring may cause conflicts.
If you configure a GitLab repository to both pull from, and push to, the same remote source, there Bidirectional [mirroring](index.md) configures two repositories to both pull from,
is no guarantee that either repository updates correctly. If you set up a repository for and push to, each other. There is no guarantee that either repository can update
bidirectional mirroring, you should prepare for the likely conflicts by deciding who resolves without errors.
them and how.
## Reduce conflicts in bidirectional mirroring
If you configure bidirectional mirroring, prepare your repositories for
conflicts. Configure them to reduce conflicts, and how to settle them when they occur:
- [Mirror only protected branches](index.md#mirror-only-protected-branches). Rewriting
any mirrored commit on either remote causes conflicts and mirroring to fail.
- [Protect the branches](../../protected_branches.md) you want to mirror on both
remotes to prevent conflicts caused by rewriting history.
- Reduce mirroring delay with a [push event webhook](../../integrations/webhook_events.md#push-events).
Bidirectional mirroring creates a race condition where commits made close together
to the same branch cause conflicts. Push event webhooks can help mitigate the race
condition. Push mirroring from GitLab is rate limited to once per minute when only
push mirroring protected branches.
- Prevent conflicts [using a pre-receive hook](#prevent-conflicts-by-using-a-pre-receive-hook).
Rewriting any mirrored commit on either remote causes conflicts and mirroring to fail. This can ## Configure a webhook to trigger an immediate pull to GitLab
be prevented by [mirroring only protected branches](index.md#mirror-only-protected-branches).
You should [protect the branches](../../protected_branches.md) you wish to mirror on both
remotes to prevent conflicts caused by rewriting history.
Bidirectional mirroring also creates a race condition where commits made close together to the same A [push event webhook](../../integrations/webhook_events.md#push-events) in the downstream
branch causes conflicts. The race condition can be mitigated by reducing the mirroring delay by using instance can help reduce race conditions by syncing changes more frequently.
a [Push event webhook](../../integrations/webhook_events.md#push-events) to trigger an immediate
pull to GitLab. Push mirroring from GitLab is rate limited to once per minute when only push mirroring
protected branches.
## Configure a webhook to trigger an immediate pull to GitLab Prerequisites:
Assuming you have already configured the [push](push.md#set-up-a-push-mirror-to-another-gitlab-instance-with-2fa-activated) - You have configured the [push](push.md#set-up-a-push-mirror-to-another-gitlab-instance-with-2fa-activated)
and [pull](pull.md#pull-from-a-remote-repository) mirrors in the upstream GitLab instance, to trigger an and [pull](pull.md#pull-from-a-remote-repository) mirrors in the upstream GitLab instance.
immediate pull as suggested above, you must configure a [Push Event Web Hook](../../integrations/webhook_events.md#push-events)
in the downstream instance.
To do this: To create the webhook in the downstream instance:
1. Create a [personal access token](../../../profile/personal_access_tokens.md) with `API` scope. 1. Create a [personal access token](../../../profile/personal_access_tokens.md) with `API` scope.
1. In your project, go to **Settings > Webhooks**. 1. On the top bar, select **Menu > Projects** and find your project.
1. Add the webhook URL which (in this case) uses the [Pull Mirror API](../../../../api/projects.md#start-the-pull-mirroring-process-for-a-project) 1. On the left sidebar, select **Settings > Webhooks**.
request to trigger an immediate pull after updates to the repository. 1. Add the webhook **URL**, which (in this case) uses the
[Pull Mirror API](../../../../api/projects.md#start-the-pull-mirroring-process-for-a-project)
request to trigger an immediate pull after a repository update:
```plaintext ```plaintext
https://gitlab.example.com/api/v4/projects/:id/mirror/pull?private_token=<your_access_token> https://gitlab.example.com/api/v4/projects/:id/mirror/pull?private_token=<your_access_token>
``` ```
1. Ensure the **Push Events** checkbox is selected. 1. Select **Push Events**.
1. Select **Add Webhook** to save the webhook. 1. Select **Add Webhook**.
To test the integration, select the **Test** button and confirm GitLab doesn't return an error message. To test the integration, select **Test** and confirm GitLab doesn't return an error message.
## Prevent conflicts using a pre-receive hook ## Prevent conflicts by using a pre-receive hook
WARNING: WARNING:
The solution proposed negatively affects the performance of This solution negatively affects the performance of Git push operations, because
Git push operations because they are proxied to the upstream Git they are proxied to the upstream Git repository.
repository.
A server-side `pre-receive` hook can be used to prevent the race condition In this configuration, one Git repository acts as the authoritative upstream, and
described above by only accepting the push after first pushing the commit to the other as downstream. This server-side `pre-receive` hook accepts a push only
the upstream Git repository. In this configuration one Git repository acts as after first pushing the commit to the upstream repository. Install this hook on
the authoritative upstream, and the other as downstream. The `pre-receive` hook your downstream repository.
is installed on the downstream repository.
Read about [configuring Server hooks](../../../../administration/server_hooks.md) on the GitLab server. For example:
A sample `pre-receive` hook is provided below.
```shell ```shell
#!/usr/bin/env bash #!/usr/bin/env bash
# --- Assume only one push mirror target # --- Assume only one push mirror target
# Push mirroring remotes are named `remote_mirror_<id>`, this finds the first remote and uses that. # 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) TARGET_REPO=$(git remote | grep -m 1 remote_mirror)
proxy_push() proxy_push()
...@@ -91,7 +96,8 @@ proxy_push() ...@@ -91,7 +96,8 @@ proxy_push()
branch=$(expr "$refname" : "refs/heads/\(.*\)") branch=$(expr "$refname" : "refs/heads/\(.*\)")
if [ "$allowlist" = "$branch" ]; then if [ "$allowlist" = "$branch" ]; then
unset GIT_QUARANTINE_PATH # handle https://git-scm.com/docs/git-receive-pack#_quarantine_environment # 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)" error="$(git push --quiet $TARGET_REPO $NEWREV:$REFNAME 2>&1)"
fail=$? fail=$?
...@@ -109,16 +115,14 @@ proxy_push() ...@@ -109,16 +115,14 @@ proxy_push()
} }
# Allow dual mode: run from the command line just like the update hook, or # 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 no arguments are given, then run as a hook script:
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
# Output to the terminal in command line mode - if someone wanted to # Output to the terminal in command line mode. If someone wanted to
# resend an email; they could redirect the output to sendmail # resend an email, they could redirect the output to sendmail themselves
# themselves
PAGER= proxy_push $2 $3 $1 PAGER= proxy_push $2 $3 $1
else else
# Push is proxied upstream one ref at a time. Because of this it is possible # Push is proxied upstream one ref at a time. It is possible for some refs
# for some refs to succeed, and others to fail. This will result in a failed # to succeed, and others to fail. This results in a failed push.
# push.
while read oldrev newrev refname while read oldrev newrev refname
do do
proxy_push $oldrev $newrev $refname proxy_push $oldrev $newrev $refname
...@@ -126,9 +130,9 @@ else ...@@ -126,9 +130,9 @@ else
fi fi
``` ```
Note that this sample has a few limitations: This sample has a few limitations:
- This example may not work verbatim for your use case and might need modification. - It may not work for your use case without modification:
- It doesn't regard different types of authentication mechanisms for the mirror. - It doesn't regard different types of authentication mechanisms for the mirror.
- It doesn't work with forced updates (rewriting history). - It doesn't work with forced updates (rewriting history).
- Only branches that match the `allowlist` patterns are proxy pushed. - Only branches that match the `allowlist` patterns are proxy pushed.
...@@ -144,20 +148,24 @@ Bidirectional mirroring should not be used as a permanent configuration. Refer t ...@@ -144,20 +148,24 @@ Bidirectional mirroring should not be used as a permanent configuration. Refer t
[Migrating from Perforce Helix](../../import/perforce.md) for alternative migration approaches. [Migrating from Perforce Helix](../../import/perforce.md) for alternative migration approaches.
[Git Fusion](https://www.perforce.com/manuals/git-fusion/#Git-Fusion/section_avy_hyc_gl.html) provides a Git interface [Git Fusion](https://www.perforce.com/manuals/git-fusion/#Git-Fusion/section_avy_hyc_gl.html) provides a Git interface
to [Perforce Helix](https://www.perforce.com/products) which can be used by GitLab to bidirectionally to [Perforce Helix](https://www.perforce.com/products). GitLab can use the Perforce Helix
mirror projects with GitLab. This can help you in some situations when migrating from Perforce Helix interface to bidirectionally mirror projects. It can help when migrating from Perforce Helix
to GitLab where overlapping Perforce Helix workspaces cannot be migrated simultaneously to GitLab. to GitLab, if overlapping Perforce Helix workspaces cannot be migrated simultaneously.
If using mirroring with Perforce Helix, you should only mirror protected branches. Perforce Helix If you mirror with Perforce Helix, mirror only protected branches. Perforce Helix
rejects any pushes that rewrite history. Only the fewest number of branches should be mirrored rejects any pushes that rewrite history. Only the fewest number of branches should be mirrored
due to the performance limitations of Git Fusion. due to the performance limitations of Git Fusion.
When configuring mirroring with Perforce Helix via Git Fusion, the following Git Fusion When you configure mirroring with Perforce Helix by using Git Fusion, we recommend these Git Fusion
settings are recommended: settings:
- `change-pusher` should be disabled. Otherwise, every commit is rewritten as being committed - Disable `change-pusher`. Otherwise, every commit is rewritten as being committed
by the mirroring account, rather than being mapped to existing Perforce Helix users or the `unknown_git` user. by the mirroring account, rather than mapping to existing Perforce Helix users or the `unknown_git` user.
- `unknown_git` user is used as the commit author if the GitLab user doesn't exist in - Use the `unknown_git` user as the commit author, if the GitLab user doesn't exist in
Perforce Helix. Perforce Helix.
Read about [Git Fusion settings on Perforce.com](https://www.perforce.com/manuals/git-fusion/Content/Git-Fusion/section_vss_bdw_w3.html#section_zdp_zz1_3l). Read about [Git Fusion settings on Perforce.com](https://www.perforce.com/manuals/git-fusion/Content/Git-Fusion/section_vss_bdw_w3.html#section_zdp_zz1_3l).
## Related topics
- [Configure server hooks](../../../../administration/server_hooks.md) on a GitLab server.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment