Read about our upcoming Code of Conduct on this issue

Commit 61202d6a authored by Tiago Botelho's avatar Tiago Botelho
Browse files

Adds remote mirror table migration

parent 64bff8ce6d26
class AddMirrorAvailableToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
add_column_with_default(:application_settings, :mirror_available, :boolean, default: true, allow_null: false) unless column_exists?(:application_settings, :mirror_available)
def down
remove_column(:application_settings, :mirror_available) if column_exists?(:application_settings, :mirror_available)
......@@ -165,6 +165,7 @@
t.boolean "pages_domain_verification_enabled", default: true, null: false
t.boolean "allow_local_requests_from_hooks_and_services", default: false, null: false
t.boolean "enforce_terms", default: false
t.boolean "mirror_available", default: true, null: false
create_table "audit_events", force: :cascade do |t|
......@@ -314,10 +315,10 @@
t.integer "auto_canceled_by_id"
t.boolean "retried"
t.integer "stage_id"
t.boolean "protected"
t.integer "failure_reason"
t.integer "artifacts_file_store"
t.integer "artifacts_metadata_store"
t.boolean "protected"
t.integer "failure_reason"
add_index "ci_builds", ["artifacts_expire_at"], name: "index_ci_builds_on_artifacts_expire_at", where: "(artifacts_file <> ''::text)", using: :btree
......@@ -365,13 +366,13 @@
t.integer "project_id", null: false
t.integer "job_id", null: false
t.integer "file_type", null: false
t.integer "file_store"
t.integer "size", limit: 8
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
t.datetime_with_timezone "expire_at"
t.string "file"
t.binary "file_sha256"
t.integer "file_store"
add_index "ci_job_artifacts", ["expire_at", "job_id"], name: "index_ci_job_artifacts_on_expire_at_and_job_id", using: :btree
......@@ -1593,6 +1594,7 @@
t.boolean "merge_requests_rebase_enabled", default: false, null: false
t.integer "jobs_cache_index"
t.boolean "pages_https_only", default: true
t.boolean "remote_mirror_available_overridden"
add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree
......@@ -1698,6 +1700,27 @@
add_index "releases", ["project_id", "tag"], name: "index_releases_on_project_id_and_tag", using: :btree
add_index "releases", ["project_id"], name: "index_releases_on_project_id", using: :btree
create_table "remote_mirrors", force: :cascade do |t|
t.integer "project_id"
t.string "url"
t.boolean "enabled", default: true
t.string "update_status"
t.datetime "last_update_at"
t.datetime "last_successful_update_at"
t.datetime "last_update_started_at"
t.string "last_error"
t.boolean "only_protected_branches", default: false, null: false
t.string "remote_name"
t.text "encrypted_credentials"
t.string "encrypted_credentials_iv"
t.string "encrypted_credentials_salt"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
add_index "remote_mirrors", ["last_successful_update_at"], name: "index_remote_mirrors_on_last_successful_update_at", using: :btree
add_index "remote_mirrors", ["project_id"], name: "index_remote_mirrors_on_project_id", using: :btree
create_table "routes", force: :cascade do |t|
t.integer "source_id", null: false
t.string "source_type", null: false
......@@ -2233,6 +2256,7 @@
add_foreign_key "protected_tags", "projects", name: "fk_8e4af87648", on_delete: :cascade
add_foreign_key "push_event_payloads", "events", name: "fk_36c74129da", on_delete: :cascade
add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade
add_foreign_key "remote_mirrors", "projects", on_delete: :cascade
add_foreign_key "services", "projects", name: "fk_71cce407f9", on_delete: :cascade
add_foreign_key "snippets", "projects", name: "fk_be41fd4bb7", on_delete: :cascade
add_foreign_key "subscriptions", "projects", on_delete: :cascade
# Repository mirroring
Repository Mirroring is a way to mirror repositories from external sources.
It can be used to mirror all branches, tags, and commits that you have
in your repository.
Your mirror at GitLab will be updated automatically. You can
also manually trigger an update at most once every 5 minutes.
## Overview
Repository mirroring is very useful when, for some reason, you must use a
project from another source.
There are two kinds of repository mirroring features supported by GitLab:
**push** and **pull**, the latter being only available in GitLab Enterprise Edition.
The **push** method mirrors the repository in GitLab to another location.
Once the mirror repository is updated, all new branches,
tags, and commits will be visible in the project's activity feed.
Users with at least [developer access][perms] to the project can also force an
immediate update with the click of a button. This button will not be available if
the mirror is already being updated or 5 minutes still haven't passed since its last update.
A few things/limitations to consider:
- The repository must be accessible over `http://`, `https://`, `ssh://` or `git://`.
- If your HTTP repository is not publicly accessible, add authentication
information to the URL, like: ``.
In some cases, you might need to use a personal access token instead of a
password, e.g., you want to mirror to GitHub and have 2FA enabled.
- The import will time out after 15 minutes. For repositories that take longer
use a clone/push combination.
- The Git LFS objects will not be synced. You'll need to push/pull them
## Use-case
- You have old projects in another source that you don't use actively anymore,
but don't want to remove for archiving purposes. In that case, you can create
a push mirror so that your active GitLab repository can push its changes to the
old location.
## Pushing to a remote repository **[STARTER]**
>[Introduced]( in
GitLab Enterprise Edition 8.7. [Moved to GitLab Community Edition][ce-18715] in 10.8.
For an existing project, you can set up push mirror from your project's
**Settings ➔ Repository** and searching for the "Push to a remote repository"
section. Check the "Remote mirror repository" box and fill in the Git URL of
the repository to push to. Click **Save changes** for the changes to take
![Push settings](repository_mirroring/repository_mirroring_push_settings.png)
When push mirroring is enabled, you are advised not to push commits directly
to the mirrored repository to prevent the mirror diverging.
All changes will end up in the mirrored repository whenever commits
are pushed to GitLab, or when a [forced update](#forcing-an-update) is
Pushes into GitLab are automatically pushed to the remote mirror at least once
every 5 minutes after they are received or once every minute if **push only
protected branches** is enabled.
In case of a diverged branch, you will see an error indicated at the **Mirror
repository** settings.
![Diverged branch](
### Push only protected branches
>[Introduced][ee-3350] in GitLab Enterprise Edition 10.3. [Moved to GitLab Community Edition][ce-18715] in 10.8.
You can choose to only push your protected branches from GitLab to your remote repository.
To use this option go to your project's repository settings page under push mirror.
## Setting up a push mirror from GitLab to GitHub
To set up a mirror from GitLab to GitHub, you need to follow these steps:
1. Create a [GitHub personal access token]( with the "public_repo" box checked:
![edit personal access token GitHub](repository_mirroring/repository_mirroring_github_edit_personal_access_token.png)
1. Fill in the "Git repository URL" with the personal access token replacing the password ``:
![push to remote repo](repository_mirroring/repository_mirroring_gitlab_push_to_a_remote_repository.png)
1. Save
1. And either wait or trigger the "Update Now" button:
![update now](repository_mirroring/repository_mirroring_gitlab_push_to_a_remote_repository_update_now.png)
## Forcing an update
While mirrors are scheduled to update automatically, you can always force an update
by using the **Update now** button which is exposed in various places:
- in the commits page
- in the branches page
- in the tags page
- in the **Mirror repository** settings page
[perms]: ../user/
......@@ -1852,7 +1852,7 @@ def create_build(new_pipeline = pipeline, name = 'test')
it { expect(project.gitea_import?).to be true }
describe '#has_remote_mirror?' do
describe '#has_remote_mirror?' do
let(:project) { create(:project, :remote_mirror, :import_started) }
subject { project.has_remote_mirror? }
......@@ -164,14 +164,6 @@
context 'as a Geo secondary' do
it 'returns nil' do
allow(Gitlab::Geo).to receive(:secondary?).and_return(true)
expect(remote_mirror.sync).to be_nil
context 'with remote mirroring enabled' do
context 'with only protected branches enabled' do
context 'when it did not update in the last minute' do
......@@ -2370,6 +2370,11 @@ def merge(repository, user, merge_request, message)
def create_remote_branch(remote_name, branch_name, target)
rugged = repository.rugged
describe '#ancestor?' do
let(:commit) { repository.commit }
let(:ancestor) { commit.parents.first }
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