From 0799e3cad9f7fd191e92ae23c05f3b0c250ae61b Mon Sep 17 00:00:00 2001
From: Manuel Vacelet <manuel.vacelet@enalean.com>
Date: Tue, 26 Jan 2016 15:53:39 +0100
Subject: [PATCH] request #8805: Strength migration to Gerrit

For all new migrations (no change for already migrated repo):
* When there is an error, users see the error message on repository
* Git admin has access to the error stack trace
* Requester get an email to inform him about the error
* Permissions on Tuleap/git are not modified (previously, gerrit had RW+
  access, hence a gerrit user could force replication gerrit side and nuke
  the repository)

Change-Id: I8c5284059bc91efb4a24629b69ebe48663181402
---
 plugins/git/db/install.sql                         |   1 +
 .../201601271109_add_remote_servers_migration.php  |  59 +++++++++
 plugins/git/include/Git.class.php                  |   2 +-
 .../Git/Driver/Gerrit/ProjectCreatorStatus.php     |  88 +++++++++++++
 .../Git/Driver/Gerrit/ProjectCreatorStatusDao.php  |  39 ++++++
 .../Gitolite/ConfigPermissionsSerializer.class.php |  21 ++-
 .../git/include/Git/SystemEventManager.class.php   |   4 +-
 plugins/git/include/GitActions.class.php           |   9 +-
 plugins/git/include/GitDao.class.php               |  28 +++-
 plugins/git/include/GitRepository.class.php        |   9 ++
 .../GitViews/RepoManagement/Pane/Gerrit.class.php  |  66 +++++++---
 .../include/GitViews/ShowRepo/Content.class.php    |  27 +---
 .../include/GitViews/ShowRepo/ContentGerrit.php    | 100 ++++++++++++++
 plugins/git/include/Git_GitoliteDriver.class.php   |   3 +
 plugins/git/include/autoload.php                   |   7 +-
 .../SystemEvent_GIT_GERRIT_MIGRATION.class.php     |  58 +++++++--
 plugins/git/include/gitPlugin.class.php            |   1 +
 plugins/git/site-content/en_US/git.tab             |   5 +
 plugins/git/site-content/fr_FR/git.tab             |   5 +
 .../Git/Driver/Gerrit/ProjectCreatorStatusTest.php | 140 ++++++++++++++++++++
 .../Gitolite/ConfigPermissionsSerializerTest.php   | 143 ++++++++++++++++++++-
 .../tests/Git/Gitolite/ProjectSerializerTest.php   |   5 +
 plugins/git/tests/Git/SystemEventManagerTest.php   |   7 +-
 plugins/git/tests/GitActionsTest.php               |   9 +-
 plugins/git/tests/GitTest.php                      |   2 +-
 plugins/git/tests/Git_GitoliteDriverTest.php       |   1 +
 plugins/git/tests/Git_GitoliteTestCase.class.php   |   1 +
 .../SystemEvent_GIT_GERRIT_MIGRATIONTest.php       |   9 +-
 28 files changed, 770 insertions(+), 79 deletions(-)
 create mode 100644 plugins/git/db/mysql/updates/2016/201601271109_add_remote_servers_migration.php
 create mode 100644 plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatus.php
 create mode 100644 plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatusDao.php
 create mode 100644 plugins/git/include/GitViews/ShowRepo/ContentGerrit.php
 create mode 100644 plugins/git/tests/Git/Driver/Gerrit/ProjectCreatorStatusTest.php

diff --git a/plugins/git/db/install.sql b/plugins/git/db/install.sql
index 557d6ba..b73140e 100644
--- a/plugins/git/db/install.sql
+++ b/plugins/git/db/install.sql
@@ -33,6 +33,7 @@ CREATE TABLE IF NOT EXISTS `plugin_git` (
   `remote_server_disconnect_date` INT(11) NULL,
   `remote_project_deleted` TINYINT DEFAULT '0',
   `remote_project_deleted_date` INT(11) NULL,
+  `remote_server_migration_status` ENUM("QUEUE", "DONE", "ERROR") NULL,
   PRIMARY KEY  (`repository_id`),
   KEY `project_id` (`project_id`)
 );
diff --git a/plugins/git/db/mysql/updates/2016/201601271109_add_remote_servers_migration.php b/plugins/git/db/mysql/updates/2016/201601271109_add_remote_servers_migration.php
new file mode 100644
index 0000000..9a73462
--- /dev/null
+++ b/plugins/git/db/mysql/updates/2016/201601271109_add_remote_servers_migration.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright (c) STMicroelectronics 2012. All rights reserved
+ *
+ * Tuleap is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Tuleap is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class b201601271109_add_remote_servers_migration extends ForgeUpgrade_Bucket {
+
+    /**
+     * Description of the bucket
+     *
+     * @return String
+     */
+    public function description() {
+        return <<<EOT
+Add column to track remote server status
+EOT;
+    }
+
+    /**
+     * Get the API
+     *
+     * @return void
+     */
+    public function preUp() {
+        $this->db = $this->getApi('ForgeUpgrade_Bucket_Db');
+    }
+
+
+    /**
+     * Creation of the table
+     *
+     * @return void
+     */
+    public function up() {
+        $sql = 'ALTER TABLE plugin_git
+                ADD COLUMN remote_server_migration_status ENUM("DONE", "ERROR") NULL AFTER remote_project_deleted_date';
+        $this->execDB($sql, 'An error occured while adding remote_server_migration_status to plugin_git: ');
+    }
+
+    protected function execDB($sql, $message) {
+        $res = $this->db->dbh->exec($sql);
+        if ($res === false) {
+            throw new ForgeUpgrade_Bucket_Exception_UpgradeNotComplete($message.implode(', ', $this->db->dbh->errorInfo()));
+        }
+    }
+}
diff --git a/plugins/git/include/Git.class.php b/plugins/git/include/Git.class.php
index ec2d2c2..063d582 100644
--- a/plugins/git/include/Git.class.php
+++ b/plugins/git/include/Git.class.php
@@ -729,7 +729,7 @@ class Git extends PluginController {
                         if ($project_exists) {
                             $this->addError($this->getText('gerrit_project_exists'));
                         } else {
-                            $this->addAction('migrateToGerrit', array($repo, $remote_server_id, $gerrit_template_id));
+                            $this->addAction('migrateToGerrit', array($repo, $remote_server_id, $gerrit_template_id, $user));
                         }
                     } catch (Git_Driver_Gerrit_Exception $e) {
                         $this->addError($this->getText('gerrit_server_down'));
diff --git a/plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatus.php b/plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatus.php
new file mode 100644
index 0000000..ef76ecf
--- /dev/null
+++ b/plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatus.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright (c) Enalean, 2016. All Rights Reserved.
+ *
+ * This file is a part of Tuleap.
+ *
+ * Tuleap is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Tuleap is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class Git_Driver_Gerrit_ProjectCreatorStatus {
+
+    /** @var Git_Driver_Gerrit_ProjectCreatorStatusDao */
+    private $dao;
+
+    /** @var array */
+    private $cache = array();
+
+    const ERROR = 'ERROR';
+    const QUEUE = 'QUEUE';
+    const DONE  = 'DONE';
+
+    public function __construct(Git_Driver_Gerrit_ProjectCreatorStatusDao $dao) {
+        $this->dao = $dao;
+    }
+
+    public function getStatus(GitRepository $repository) {
+        $event_status = $this->getEventStatus($repository);
+        if (! $repository->isMigratedToGerrit()) {
+            if ($event_status == SystemEvent::STATUS_NEW) {
+                return self::QUEUE;
+            }
+            return null;
+        }
+        if ($repository->getMigrationStatus() != null) {
+            return $repository->getMigrationStatus();
+        }
+        switch($event_status) {
+            case SystemEvent::STATUS_RUNNING:
+                return self::QUEUE;
+
+            case null:
+                return null;
+
+            default:
+                return self::DONE;
+        }
+    }
+
+    private function getEventStatus(GitRepository $repository) {
+        $row = $this->getEvent($repository);
+        if ($row) {
+            return $row['status'];
+        }
+        return null;
+    }
+
+    public function getEventDate(GitRepository $repository) {
+        $row = $this->getEvent($repository);
+        if ($row) {
+            return $row['create_date'];
+        }
+    }
+
+    public function getLog(GitRepository $repository) {
+        $row = $this->getEvent($repository);
+        if ($row) {
+            return $row['log'];
+        }
+    }
+
+    private function getEvent(GitRepository $repository) {
+        if (! isset($this->cache[$repository->getId()])) {
+            $this->cache[$repository->getId()] = $this->dao->getSystemEventForRepository($repository->getId());
+        }
+        return $this->cache[$repository->getId()];
+    }
+}
diff --git a/plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatusDao.php b/plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatusDao.php
new file mode 100644
index 0000000..d5007d5
--- /dev/null
+++ b/plugins/git/include/Git/Driver/Gerrit/ProjectCreatorStatusDao.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright (c) Enalean, 2016. All Rights Reserved.
+ *
+ * This file is a part of Tuleap.
+ *
+ * Tuleap is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Tuleap is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class Git_Driver_Gerrit_ProjectCreatorStatusDao extends DataAccessObject {
+
+    public function getSystemEventForRepository($repository_id) {
+        $repository_id = $this->da->escapeInt($repository_id);
+        $sql = "SELECT status, UNIX_TIMESTAMP(create_date) create_date, log
+                FROM system_event
+                WHERE type = '".SystemEvent_GIT_GERRIT_MIGRATION::NAME."'
+                AND parameters LIKE '$repository_id::%'
+                ORDER BY id DESC
+                LIMIT 1";
+
+        $dar = $this->retrieve($sql);
+        if ($dar && count($dar)) {
+            return $this->retrieve($sql)->getRow();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/plugins/git/include/Git/Gitolite/ConfigPermissionsSerializer.class.php b/plugins/git/include/Git/Gitolite/ConfigPermissionsSerializer.class.php
index d3c90a5..5416f1a 100644
--- a/plugins/git/include/Git/Gitolite/ConfigPermissionsSerializer.class.php
+++ b/plugins/git/include/Git/Gitolite/ConfigPermissionsSerializer.class.php
@@ -20,6 +20,7 @@
 
 class Git_Gitolite_ConfigPermissionsSerializer {
 
+
     const TEMPLATES_PATH = 'gitolite';
 
     /**
@@ -32,14 +33,20 @@ class Git_Gitolite_ConfigPermissionsSerializer {
      */
     private $data_mapper;
 
+    /**
+     * @var Git_Driver_Gerrit_ProjectCreatorStatus
+     */
+    private $gerrit_status;
+
     private static $permissions_types = array(
         Git::PERM_READ  => ' R  ',
         Git::PERM_WRITE => ' RW ',
         Git::PERM_WPLUS => ' RW+'
     );
 
-    public function __construct(Git_Mirror_MirrorDataMapper $data_mapper, $etc_templates_path) {
-        $this->data_mapper       = $data_mapper;
+    public function __construct(Git_Mirror_MirrorDataMapper $data_mapper, Git_Driver_Gerrit_ProjectCreatorStatus $gerrit_status, $etc_templates_path) {
+        $this->data_mapper   = $data_mapper;
+        $this->gerrit_status = $gerrit_status;
         $template_dirs = array();
         if (is_dir($etc_templates_path)) {
             $template_dirs[] = $etc_templates_path . '/' . self::TEMPLATES_PATH;
@@ -92,7 +99,7 @@ class Git_Gitolite_ConfigPermissionsSerializer {
         $repo_config = '';
         $repo_config .= $this->fetchConfigPermissions($project, $repository, Git::PERM_READ);
         $repo_config .= $this->formatPermission(Git::PERM_READ, $this->getMirrorUserNames($repository));
-        if ($repository->isMigratedToGerrit()) {
+        if ($this->isMigrationToGerritCompletedWithSuccess($repository)) {
             $key = new Git_RemoteServer_Gerrit_ReplicationSSHKey();
             $key->setGerritHostId($repository->getRemoteServerId());
             $repo_config .= $this->formatPermission(Git::PERM_WPLUS, array($key->getUserName()));
@@ -103,6 +110,14 @@ class Git_Gitolite_ConfigPermissionsSerializer {
         return $repo_config;
     }
 
+    private function isMigrationToGerritCompletedWithSuccess(GitRepository $repository) {
+        if ($repository->isMigratedToGerrit() &&
+            $this->gerrit_status->getStatus($repository) === Git_Driver_Gerrit_ProjectCreatorStatus::DONE) {
+            return true;
+        }
+        return false;
+    }
+
     private function formatPermission($permission_type, array $granted) {
         if (count($granted)) {
             return self::$permissions_types[$permission_type] . ' = ' . implode(' ', $granted).PHP_EOL;
diff --git a/plugins/git/include/Git/SystemEventManager.class.php b/plugins/git/include/Git/SystemEventManager.class.php
index bc8d6d3..5276162 100644
--- a/plugins/git/include/Git/SystemEventManager.class.php
+++ b/plugins/git/include/Git/SystemEventManager.class.php
@@ -112,10 +112,10 @@ class Git_SystemEventManager {
         );
     }
 
-    public function queueMigrateToGerrit(GitRepository $repository, $remote_server_id, $gerrit_template_id) {
+    public function queueMigrateToGerrit(GitRepository $repository, $remote_server_id, $gerrit_template_id, PFUser $requester) {
         $this->system_event_manager->createEvent(
             SystemEvent_GIT_GERRIT_MIGRATION::NAME,
-            $repository->getId() . SystemEvent::PARAMETER_SEPARATOR . $remote_server_id . SystemEvent::PARAMETER_SEPARATOR . $gerrit_template_id,
+            $repository->getId() . SystemEvent::PARAMETER_SEPARATOR . $remote_server_id . SystemEvent::PARAMETER_SEPARATOR . $gerrit_template_id . SystemEvent::PARAMETER_SEPARATOR . $requester->getId(),
             SystemEvent::PRIORITY_HIGH,
             SystemEvent::OWNER_APP
         );
diff --git a/plugins/git/include/GitActions.class.php b/plugins/git/include/GitActions.class.php
index 78a117f..3812da4 100644
--- a/plugins/git/include/GitActions.class.php
+++ b/plugins/git/include/GitActions.class.php
@@ -502,7 +502,10 @@ class GitActions extends PluginActions {
     }
 
     private function displayFeedbacksOnRepoManagement(GitRepository $repository) {
-        if ($this->git_system_event_manager->isRepositoryMigrationToGerritOnGoing($repository)) {
+        $project_creator_status = new Git_Driver_Gerrit_ProjectCreatorStatus(
+            new Git_Driver_Gerrit_ProjectCreatorStatusDao()
+        );
+        if ($project_creator_status->getStatus($repository) == Git_Driver_Gerrit_ProjectCreatorStatus::QUEUE) {
             $GLOBALS['Response']->addFeedback(Feedback::INFO, $this->getText('gerrit_migration_ongoing'));
         }
 
@@ -841,12 +844,12 @@ class GitActions extends PluginActions {
      * @param Boolean $migrate_access_right if the acess right will be migrated or not
      * @param int $gerrit_template_id the id of template if any chosen
      */
-    public function migrateToGerrit(GitRepository $repository, $remote_server_id, $gerrit_template_id) {
+    public function migrateToGerrit(GitRepository $repository, $remote_server_id, $gerrit_template_id, PFUser $user) {
         if ($repository->canMigrateToGerrit()) {
 
             try {
                 $this->gerrit_server_factory->getServerById($remote_server_id);
-                $this->git_system_event_manager->queueMigrateToGerrit($repository, $remote_server_id, $gerrit_template_id);
+                $this->git_system_event_manager->queueMigrateToGerrit($repository, $remote_server_id, $gerrit_template_id, $user);
 
                 $this->history_dao->groupAddHistory(
                     "git_repo_to_gerrit",
diff --git a/plugins/git/include/GitDao.class.php b/plugins/git/include/GitDao.class.php
index dd30198..4b6317c 100644
--- a/plugins/git/include/GitDao.class.php
+++ b/plugins/git/include/GitDao.class.php
@@ -51,9 +51,10 @@ class GitDao extends DataAccessObject {
     const BACKEND_GITSHELL = 'gitshell';
     const BACKEND_GITOLITE = 'gitolite';
 
-    const REMOTE_SERVER_ID              = 'remote_server_id';
-    const REMOTE_SERVER_DISCONNECT_DATE = 'remote_server_disconnect_date';
-    const REMOTE_SERVER_DELETE_DATE     = 'remote_project_deleted_date';
+    const REMOTE_SERVER_ID               = 'remote_server_id';
+    const REMOTE_SERVER_DISCONNECT_DATE  = 'remote_server_disconnect_date';
+    const REMOTE_SERVER_DELETE_DATE      = 'remote_project_deleted_date';
+    const REMOTE_SERVER_MIGRATION_STATUS = 'remote_server_migration_status';
 
     const NOT_DELETED_DATE             = '0000-00-00 00:00:00';
 
@@ -501,6 +502,7 @@ class GitDao extends DataAccessObject {
         $repository->setRemoteServerId($result[self::REMOTE_SERVER_ID]);
         $repository->setRemoteServerDisconnectDate($result[self::REMOTE_SERVER_DISCONNECT_DATE]);
         $repository->setRemoteProjectDeletionDate($result[self::REMOTE_SERVER_DELETE_DATE]);
+        $repository->setRemoteServerMigrationStatus($result[self::REMOTE_SERVER_MIGRATION_STATUS]);
         $repository->loadNotifiedMails();
         /* Here just for reviewer test, will be replaced by real DB data in a future changeset*/
         $result[self::ENABLE_ONLINE_EDIT] = false;
@@ -570,10 +572,26 @@ class GitDao extends DataAccessObject {
         return $this->update($sql);
     }
 
+    public function setGerritMigrationError($repository_id) {
+        $repository_id    = $this->da->escapeInt($repository_id);
+        $sql = "UPDATE plugin_git
+                SET remote_server_migration_status = 'ERROR'
+                WHERE repository_id = $repository_id";
+        return $this->update($sql);
+    }
+
+    public function setGerritMigrationSuccess($repository_id) {
+        $repository_id    = $this->da->escapeInt($repository_id);
+        $sql = "UPDATE plugin_git
+                SET remote_server_migration_status = 'DONE'
+                WHERE repository_id = $repository_id";
+        return $this->update($sql);
+    }
+
     public function disconnectFromGerrit($repository_id) {
         $repository_id = $this->da->escapeInt($repository_id);
         $sql = "UPDATE plugin_git
-                SET remote_server_disconnect_date = UNIX_TIMESTAMP()
+                SET remote_server_disconnect_date = UNIX_TIMESTAMP(), remote_server_migration_status = NULL
                 WHERE repository_id = $repository_id";
         return $this->update($sql);
     }
@@ -584,7 +602,7 @@ class GitDao extends DataAccessObject {
     public function setGerritProjectAsDeleted($repository_id) {
         $repository_id = $this->da->escapeInt($repository_id);
         $sql = "UPDATE plugin_git
-                SET remote_project_deleted_date = UNIX_TIMESTAMP()
+                SET remote_project_deleted_date = UNIX_TIMESTAMP(), remote_server_migration_status = NULL
                 WHERE repository_id = $repository_id";
         return $this->update($sql);
     }
diff --git a/plugins/git/include/GitRepository.class.php b/plugins/git/include/GitRepository.class.php
index ad140cc..f4ab17d 100644
--- a/plugins/git/include/GitRepository.class.php
+++ b/plugins/git/include/GitRepository.class.php
@@ -71,6 +71,7 @@ class GitRepository implements DVCSRepository {
     private $remote_server_disconnect_date;
     private $remote_project_deletion_date;
     private $remote_project_is_deleted;
+    private $remote_server_migration_status;
 
     private $use_online_edit;
 
@@ -865,6 +866,10 @@ class GitRepository implements DVCSRepository {
             $this->remote_project_deletion_date == false);
     }
 
+    public function getMigrationStatus() {
+        return $this->remote_server_migration_status;
+    }
+
     public function wasPreviouslyMigratedButNotDeleted() {
         return (
             $this->remote_server_id &&
@@ -881,6 +886,10 @@ class GitRepository implements DVCSRepository {
         $this->remote_project_deletion_date = $date;
     }
 
+    public function setRemoteServerMigrationStatus($status) {
+        $this->remote_server_migration_status = $status;
+    }
+
     /**
      * @return string html <a href="/path/to/repo">repo/name</a>
      */
diff --git a/plugins/git/include/GitViews/RepoManagement/Pane/Gerrit.class.php b/plugins/git/include/GitViews/RepoManagement/Pane/Gerrit.class.php
index b406f4e..7dfca95 100644
--- a/plugins/git/include/GitViews/RepoManagement/Pane/Gerrit.class.php
+++ b/plugins/git/include/GitViews/RepoManagement/Pane/Gerrit.class.php
@@ -211,32 +211,63 @@ class GitViews_RepoManagement_Pane_Gerrit extends GitViews_RepoManagement_Pane {
             return $this->getDisconnectFromGerritConfirmationScreen();
         }
 
+        $html  = '';
+        $html .= '<fieldset class="gerrit_disconnect">';
+        $html .= '<legend class="gerrit_disconnect">'.$GLOBALS['Language']->getText('plugin_git', 'gerrit_title').'</legend>';
+        $html .= $this->getMessageAccordingToMigrationStatus();
+        $html .= '</fieldset>';
+
+        $html .= '<form method="POST" action="'. $_SERVER['REQUEST_URI'] .'">';
+        $html .= '<fieldset class="gerrit_disconnect">';
+        $html .= '<legend class="gerrit_disconnect">' . $GLOBALS['Language']->getText('plugin_git', 'disconnect_gerrit_title') . '</legend>';
+        $html .= $this->getDisconnectFromGerritOptions();
+        $html .= '<button type="submit" class="btn" name="'. $btn_name .'" value="1">';
+        $html .= '<i class="icon-off"></i> ' . $GLOBALS['Language']->getText('plugin_git', 'disconnect_gerrit_button');
+        $html .= '</button>';
+        $html .= '</fieldset>';
+        $html .= '</form>';
+        return $html;
+    }
+
+    private function getMessageAccordingToMigrationStatus() {
+        $project_creator_status = new Git_Driver_Gerrit_ProjectCreatorStatus(
+            new Git_Driver_Gerrit_ProjectCreatorStatusDao()
+        );
+        switch ($project_creator_status->getStatus($this->repository)) {
+            case Git_Driver_Gerrit_ProjectCreatorStatus::QUEUE:
+                return '';
+
+            case null:
+            case Git_Driver_Gerrit_ProjectCreatorStatus::DONE:
+                return $this->getMigratedToGerritInfo();
+
+            case Git_Driver_Gerrit_ProjectCreatorStatus::ERROR:
+                return $this->getMigratedToGerritError($project_creator_status);
+        }
+    }
+
+    private function getMigratedToGerritInfo() {
         $driver         = $this->getGerritDriverForRepository($this->repository);
         $gerrit_project = $driver->getGerritProjectName($this->repository);
         $gerrit_server  = $this->getGerritServerForRepository($this->repository);
         $link           = $gerrit_server->getProjectAdminUrl($gerrit_project);
 
         $html  = '';
-        $html .= '<h3>'. $GLOBALS['Language']->getText('plugin_git', 'gerrit_title') .'</h3>';
         $html .= '<p>';
         $html .= $GLOBALS['Language']->getText('plugin_git', 'gerrit_server_already_migrated', array($this->repository->getName(), $gerrit_project, $link));
         $html .= '</p>';
         $html .= '<div class="git_repomanagement_gerrit_more_description">';
         $html .= $GLOBALS['Language']->getText('plugin_git', 'gerrit_migrated_more_description', array($gerrit_project, $gerrit_server->getHost()));
         $html .= '</div>';
-
-        $html .= '<form method="POST" action="'. $_SERVER['REQUEST_URI'] .'">';
-        $html .= '<fieldset class="gerrit_disconnect">';
-        $html .= '<legend class="gerrit_disconnect">' . $GLOBALS['Language']->getText('plugin_git', 'disconnect_gerrit_title') . '</legend>';
-        $html .= $this->getDisconnectFromGerritOptions();
-        $html .= '<button type="submit" class="btn" name="'. $btn_name .'" value="1">';
-        $html .= '<i class="icon-off"></i> ' . $GLOBALS['Language']->getText('plugin_git', 'disconnect_gerrit_button');
-        $html .= '</button>';
-        $html .= '</fieldset>';
-        $html .= '</form>';
         return $html;
     }
 
+    private function getMigratedToGerritError(Git_Driver_Gerrit_ProjectCreatorStatus $status) {
+        $date = DateHelper::timeAgoInWords($status->getEventDate($this->repository), false, true);
+        return '<div class="alert alert-error">'.$GLOBALS['Language']->getText('plugin_git', 'gerrit_server_migration_error', array($date)).'</div>'.
+               '<pre class="pre-scrollable">'.$status->getLog($this->repository).'</pre>';
+    }
+
     private function getDisconnectFromGerritConfirmationScreen() {
         $html  = '';
         $html .= '<h3>'. $GLOBALS['Language']->getText('plugin_git', 'disconnect_gerrit_title') .'</h3>';
@@ -267,18 +298,17 @@ class GitViews_RepoManagement_Pane_Gerrit extends GitViews_RepoManagement_Pane {
 
         $driver = $this->driver_factory->getDriver($gerrit_server);
         if ($driver->isDeletePluginEnabled($gerrit_server)) {
-            $html .= '<input type="radio" name="' . self::OPTION_DISCONNECT_GERRIT_PROJECT . '" value="'.self::OPTION_DELETE_GERRIT_PROJECT.'"/>'
+            $html .= '<label class="radio"><input type="radio" name="' . self::OPTION_DISCONNECT_GERRIT_PROJECT . '" value="'.self::OPTION_DELETE_GERRIT_PROJECT.'"/>'
                 . $GLOBALS['Language']->getText('plugin_git', 'gerrit_project_delete')
-                . '<br />';
+                . '</label>';
         }
 
-        $html .='<input type="radio" name="' . self::OPTION_DISCONNECT_GERRIT_PROJECT . '" value="'.self::OPTION_READONLY_GERRIT_PROJECT.'"/>'
+        $html .='<label class="radio"><input type="radio" name="' . self::OPTION_DISCONNECT_GERRIT_PROJECT . '" value="'.self::OPTION_READONLY_GERRIT_PROJECT.'"/>'
             . $GLOBALS['Language']->getText('plugin_git', 'gerrit_project_readonly')
-            . '<br />'
-            . '<input type="radio" name="' . self::OPTION_DISCONNECT_GERRIT_PROJECT . '"/>'
+            . '</label>'
+            . '<label class="radio"><input type="radio" name="' . self::OPTION_DISCONNECT_GERRIT_PROJECT . '"/>'
             . $GLOBALS['Language']->getText('plugin_git', 'gerrit_project_leave')
-            . '<br />'
-            . '<br />';
+            . '</label>';
 
         return $html;
     }
diff --git a/plugins/git/include/GitViews/ShowRepo/Content.class.php b/plugins/git/include/GitViews/ShowRepo/Content.class.php
index 9803170..e08527b 100644
--- a/plugins/git/include/GitViews/ShowRepo/Content.class.php
+++ b/plugins/git/include/GitViews/ShowRepo/Content.class.php
@@ -124,14 +124,16 @@ class GitViews_ShowRepo_Content {
     }
 
     private function displayHeader() {
+        $gerrit_status = new GitViews_ShowRepo_ContentGerritStatus(
+            $this->driver_factory,
+            $this->gerrit_servers,
+            $this->repository
+        );
+
         $html  = '';
         $html .= '<div id="plugin_git_reference" class="plugin_git_repo_type_'. $this->repository->getBackendType() .'">';
         $html .= $this->getHeader();
-
-        if ($this->repository->isMigratedToGerrit()) {
-            $html .= $this->getRemoteRepositoryInfo();
-        }
-
+        $html .= $gerrit_status->getContent();
         $html .= $this->getCloneUrl();
         $html .= '</div>';
         $html .= $this->getOnlineEditDiv();
@@ -278,21 +280,6 @@ class GitViews_ShowRepo_Content {
         $urls = array_merge($gerrit, $urls);
     }
 
-    private function getRemoteRepositoryInfo() {
-        /** @var $gerrit_server Git_RemoteServer_GerritServer */
-        $gerrit_server  = $this->gerrit_servers[$this->repository->getRemoteServerId()];
-        $driver         = $this->driver_factory->getDriver($gerrit_server);
-        $gerrit_project = $driver->getGerritProjectName($this->repository);
-        $link           = $gerrit_server->getProjectUrl($gerrit_project);
-
-        $html  = '';
-        $html .= '<div class="alert alert-info gerrit_url">';
-        $html .= $GLOBALS['Language']->getText('plugin_git', 'delegated_to_gerrit');
-        $html .= ' <a href="'.$link.'">'.$gerrit_project.'</a>';
-        $html .= '</div>';
-        return $html;
-    }
-
     private function getWaitingForRepositoryCreationInfo() {
         $html = '<div class="alert alert-info wait_creation">';
         $html .= $GLOBALS['Language']->getText('plugin_git', 'waiting_for_repo_creation');
diff --git a/plugins/git/include/GitViews/ShowRepo/ContentGerrit.php b/plugins/git/include/GitViews/ShowRepo/ContentGerrit.php
new file mode 100644
index 0000000..b1a7fba
--- /dev/null
+++ b/plugins/git/include/GitViews/ShowRepo/ContentGerrit.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Copyright (c) Enalean, 2016. All Rights Reserved.
+ *
+ * This file is a part of Tuleap.
+ *
+ * Tuleap is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Tuleap is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class GitViews_ShowRepo_ContentGerritStatus {
+
+    /**
+     * @var GitRepository
+     */
+    private $repository;
+
+    /**
+     * @var Git_Driver_Gerrit_ProjectCreatorStatus
+     */
+    private $project_creator_status;
+
+    /** @var Git_Driver_Gerrit_GerritDriverFactory */
+    private $driver_factory;
+
+    /** @var array */
+    private $gerrit_servers;
+
+
+    public function __construct(Git_Driver_Gerrit_GerritDriverFactory $driver_factory, array $gerrit_servers, GitRepository $repository) {
+        $this->gerrit_servers = $gerrit_servers;
+        $this->driver_factory = $driver_factory;
+        $this->repository     = $repository;
+        $this->project_creator_status = new Git_Driver_Gerrit_ProjectCreatorStatus(
+            new Git_Driver_Gerrit_ProjectCreatorStatusDao()
+        );
+    }
+
+    public function getContent() {
+        switch ($this->project_creator_status->getStatus($this->repository)) {
+            case Git_Driver_Gerrit_ProjectCreatorStatus::QUEUE:
+                return $this->getRemoteRepositoryInfoOnGoing();
+
+            case Git_Driver_Gerrit_ProjectCreatorStatus::DONE:
+                return $this->getRemoteRepositoryInfoDone();
+
+            case Git_Driver_Gerrit_ProjectCreatorStatus::ERROR:
+                return $this->getRemoteRepositoryInfoError();
+
+            default:
+                if ($this->repository->isMigratedToGerrit()) {
+                    return $this->getRemoteRepositoryInfoDone();
+                }
+                return '';
+        }
+    }
+
+    private function getRemoteRepositoryInfoDone() {
+        /** @var $gerrit_server Git_RemoteServer_GerritServer */
+        $gerrit_server  = $this->gerrit_servers[$this->repository->getRemoteServerId()];
+        $driver         = $this->driver_factory->getDriver($gerrit_server);
+        $gerrit_project = $driver->getGerritProjectName($this->repository);
+        $link           = $gerrit_server->getProjectUrl($gerrit_project);
+
+        $html  = '';
+        $html .= '<div class="alert alert-info gerrit_url">';
+        $html .= $GLOBALS['Language']->getText('plugin_git', 'delegated_to_gerrit');
+        $html .= ' <a href="'.$link.'">'.$gerrit_project.'</a>';
+        $html .= '</div>';
+        return $html;
+    }
+
+    private function getRemoteRepositoryInfoOnGoing() {
+        $html  = '';
+        $html .= '<div class="alert alert-info gerrit_url">';
+        $html .= $GLOBALS['Language']->getText('plugin_git', 'delegated_to_gerrit_queue');
+        $html .= '</div>';
+        return $html;
+    }
+
+    private function getRemoteRepositoryInfoError() {
+        $date = DateHelper::timeAgoInWords($this->project_creator_status->getEventDate($this->repository), false, true);
+        $url = GIT_BASE_URL . '/?action=repo_management&group_id='.$this->repository->getProjectId().'&repo_id='.$this->repository->getId().'&pane=gerrit';
+        $html  = '';
+        $html .= '<div class="alert alert-error gerrit_url">';
+        $html .= $GLOBALS['Language']->getText('plugin_git', 'delegated_to_gerrit_error', array($date, $url), CODENDI_PURIFIER_DISABLED);
+        $html .= '</div>';
+        return $html;
+    }
+}
diff --git a/plugins/git/include/Git_GitoliteDriver.class.php b/plugins/git/include/Git_GitoliteDriver.class.php
index 860cb26..6c9d630 100644
--- a/plugins/git/include/Git_GitoliteDriver.class.php
+++ b/plugins/git/include/Git_GitoliteDriver.class.php
@@ -145,6 +145,9 @@ class Git_GitoliteDriver {
         if(empty($permissions_serializer)) {
             $this->permissions_serializer = new Git_Gitolite_ConfigPermissionsSerializer(
                 $this->mirror_data_mapper,
+                new Git_Driver_Gerrit_ProjectCreatorStatus(
+                    new Git_Driver_Gerrit_ProjectCreatorStatusDao()
+                ),
                 $git_plugin->getEtcTemplatesPath()
             );
         } else {
diff --git a/plugins/git/include/autoload.php b/plugins/git/include/autoload.php
index 1a4902c..df1434f 100644
--- a/plugins/git/include/autoload.php
+++ b/plugins/git/include/autoload.php
@@ -2,7 +2,7 @@
 // @codingStandardsIgnoreFile
 // @codeCoverageIgnoreStart
 // this is an autogenerated file - do not edit
-function autoload97a669a77de86bf5abf44c5a8759cdac($class) {
+function autoloade319bb9029e4fb128f4af6f2883f67bd($class) {
     static $classes = null;
     if ($classes === null) {
         $classes = array(
@@ -40,6 +40,8 @@ function autoload97a669a77de86bf5abf44c5a8759cdac($class) {
             'git_driver_gerrit_membershipmanager' => '/Git/Driver/Gerrit/MembershipManager.class.php',
             'git_driver_gerrit_projectcreator' => '/Git/Driver/Gerrit/ProjectCreator.class.php',
             'git_driver_gerrit_projectcreator_projectalreadyexistsexception' => '/Git/Driver/Gerrit/ProjectCreator_ProjectAlreadyexistsException.class.php',
+            'git_driver_gerrit_projectcreatorstatus' => '/Git/Driver/Gerrit/ProjectCreatorStatus.php',
+            'git_driver_gerrit_projectcreatorstatusdao' => '/Git/Driver/Gerrit/ProjectCreatorStatusDao.php',
             'git_driver_gerrit_remotesshcommand' => '/Git/Driver/Gerrit/RemoteSSHCommand.class.php',
             'git_driver_gerrit_remotesshcommandfailure' => '/Git/Driver/Gerrit/RemoteSSHCommandFailure.class.php',
             'git_driver_gerrit_remotesshconfig' => '/Git/Driver/Gerrit/RemoteSSHConfig.class.php',
@@ -188,6 +190,7 @@ function autoload97a669a77de86bf5abf44c5a8759cdac($class) {
             'gitviews_repomanagement_pane_notification' => '/GitViews/RepoManagement/Pane/Notification.class.php',
             'gitviews_showrepo' => '/GitViews/ShowRepo.class.php',
             'gitviews_showrepo_content' => '/GitViews/ShowRepo/Content.class.php',
+            'gitviews_showrepo_contentgerritstatus' => '/GitViews/ShowRepo/ContentGerrit.php',
             'gitviews_showrepo_download' => '/GitViews/ShowRepo/Download.class.php',
             'gitviewsrepositoriestraversalstrategy' => '/GitViewsRepositoriesTraversalStrategy.class.php',
             'gitviewsrepositoriestraversalstrategy_selectbox' => '/GitViewsRepositoriesTraversalStrategy_Selectbox.class.php',
@@ -234,5 +237,5 @@ function autoload97a669a77de86bf5abf44c5a8759cdac($class) {
         require dirname(__FILE__) . $classes[$cn];
     }
 }
-spl_autoload_register('autoload97a669a77de86bf5abf44c5a8759cdac');
+spl_autoload_register('autoloade319bb9029e4fb128f4af6f2883f67bd');
 // @codeCoverageIgnoreEnd
diff --git a/plugins/git/include/events/SystemEvent_GIT_GERRIT_MIGRATION.class.php b/plugins/git/include/events/SystemEvent_GIT_GERRIT_MIGRATION.class.php
index d4d7cd9..5444d54 100644
--- a/plugins/git/include/events/SystemEvent_GIT_GERRIT_MIGRATION.class.php
+++ b/plugins/git/include/events/SystemEvent_GIT_GERRIT_MIGRATION.class.php
@@ -43,6 +43,9 @@ class SystemEvent_GIT_GERRIT_MIGRATION extends SystemEvent {
     /** @var Git_GitRepositoryUrlManager */
     private $url_manager;
 
+    /** @var UserManager */
+    private $user_manager;
+
     public function process() {
         $repo_id           = (int)$this->getParameter(0);
         $remote_server_id  = (int)$this->getParameter(1);
@@ -50,7 +53,7 @@ class SystemEvent_GIT_GERRIT_MIGRATION extends SystemEvent {
 
         $repository = $this->repository_factory->getRepositoryById($repo_id);
         if (! $repository) {
-            $this->warning('Unable to find repository, perhaps it was deleted in the mean time?');
+            $this->error('Unable to find repository, perhaps it was deleted in the mean time?');
             return;
         }
 
@@ -59,25 +62,45 @@ class SystemEvent_GIT_GERRIT_MIGRATION extends SystemEvent {
             $gerrit_template_id    = $this->getParameter(2);
             $gerrit_project        = $this->project_creator->createGerritProject($server, $repository, $gerrit_template_id);
             $this->project_creator->removeTemporaryDirectory();
-            $repository->getBackend()->updateRepoConf($repository);
             $this->project_creator->finalizeGerritProjectCreation($server, $repository, $gerrit_template_id);
+            $this->dao->setGerritMigrationSuccess($repository->getId());
+            $repository->setRemoteServerMigrationStatus(Git_Driver_Gerrit_ProjectCreatorStatus::DONE);
+            $repository->getBackend()->updateRepoConf($repository);
 
             $this->done("Created project $gerrit_project on ". $server->getHost());
             return true;
         } catch (Git_Driver_Gerrit_ProjectCreator_ProjectAlreadyExistsException $e) {
-            $this->logError("gerrit: ", "Gerrit failure: ", $e);
+            $this->logError($repository, "gerrit: ", "Gerrit failure: ", $e);
         } catch (Git_Driver_Gerrit_Exception $e) {
-            $this->logError("gerrit: ", "Gerrit failure: ", $e);
+            $this->logError($repository, "gerrit: ", "Gerrit failure: ", $e);
         } catch (Git_Command_Exception $e) {
-            $this->logError("gerrit: ", "Gerrit failure: ", $e);
+            $this->logError($repository, "gerrit: ", "Gerrit failure: ", $e);
         } catch (Exception $e) {
-            $this->logError("", "An error occured while processing event: ", $e);
+            $this->logError($repository, "", "An error occured while processing event: ", $e);
         }
     }
 
-    private function logError($sysevent_prefix, $log_prefix, Exception $e) {
+    private function logError(GitRepository $repository, $sysevent_prefix, $log_prefix, Exception $e) {
+        $this->dao->setGerritMigrationError($repository->getId());
         $this->error($sysevent_prefix . $e->getMessage());
         $this->logger->error($log_prefix . $this->verbalizeParameters(null), $e);
+        $this->sendErrorNotification($repository);
+    }
+
+    private function sendErrorNotification(GitRepository $repository) {
+        $user = $this->getRequester();
+        if (! $user->isAnonymous()) {
+            $factory = new BaseLanguageFactory();
+            $language = $factory->getBaseLanguage($user->getLocale());
+            $url = get_server_url() . GIT_BASE_URL . '/?action=repo_management&group_id='.$repository->getProjectId().'&repo_id='.$repository->getId().'&pane=gerrit';
+
+            $mail = new Codendi_Mail();
+            $mail->setFrom(ForgeConfig::get('sys_noreply'));
+            $mail->setTo($user->getEmail());
+            $mail->setSubject($language->getText('plugin_git', 'delegated_to_gerrit_error_mail_subject', array($repository->getFullName())));
+            $mail->setBodyHtml($language->getText('plugin_git', 'delegated_to_gerrit_error_mail_body', array($repository->getFullName(), $url)));
+            $mail->send();
+        }
     }
 
     /**
@@ -88,10 +111,25 @@ class SystemEvent_GIT_GERRIT_MIGRATION extends SystemEvent {
 
         $repo_id          = (int)$this->getParameter(0);
         $remote_server_id = (int)$this->getParameter(1);
+
         $txt .= 'repo: '. $this->verbalizeRepoId($repo_id, $with_link) .', remote server: '. $this->verbalizeRemoteServerId($remote_server_id, $with_link).$this->verbalizeAccessRightMigration();
+        $user = $this->getRequester();
+        if (! $user->isAnonymous()) {
+            if ($with_link) {
+                $txt .= ' <a href="/admin/usergroup.php?user_id='.$user->getId().'">'.$user->getRealName().'</a>';
+            } else {
+                $txt .= ' '.$user->getRealName();
+            }
+        }
+
         return $txt;
     }
 
+    private function getRequester() {
+        $user_id = (int)$this->getParameter(3);
+        return $this->user_manager->getUserById($user_id);
+    }
+
     private function verbalizeAccessRightMigration() {
         $migrate_access_rights = $this->getParameter(2);
         if (!$migrate_access_rights) {
@@ -130,7 +168,8 @@ class SystemEvent_GIT_GERRIT_MIGRATION extends SystemEvent {
         Git_RemoteServer_GerritServerFactory  $server_factory,
         Logger  $logger,
         Git_Driver_Gerrit_ProjectCreator $project_creator,
-        Git_GitRepositoryUrlManager $url_manager
+        Git_GitRepositoryUrlManager $url_manager,
+        UserManager $user_manager
     ) {
         $this->dao                = $dao;
         $this->repository_factory = $repository_factory;
@@ -138,7 +177,6 @@ class SystemEvent_GIT_GERRIT_MIGRATION extends SystemEvent {
         $this->logger             = $logger;
         $this->project_creator    = $project_creator;
         $this->url_manager        = $url_manager;
+        $this->user_manager       = $user_manager;
     }
 }
-
-?>
diff --git a/plugins/git/include/gitPlugin.class.php b/plugins/git/include/gitPlugin.class.php
index aa80069..8e6530c 100644
--- a/plugins/git/include/gitPlugin.class.php
+++ b/plugins/git/include/gitPlugin.class.php
@@ -271,6 +271,7 @@ class GitPlugin extends Plugin {
                     $this->getLogger(),
                     $this->getProjectCreator(),
                     $this->getGitRepositoryUrlManager(),
+                    UserManager::instance(),
                 );
                 break;
             case SystemEvent_GIT_REPO_FORK::NAME:
diff --git a/plugins/git/site-content/en_US/git.tab b/plugins/git/site-content/en_US/git.tab
index 2943736..0173e68 100644
--- a/plugins/git/site-content/en_US/git.tab
+++ b/plugins/git/site-content/en_US/git.tab
@@ -75,6 +75,7 @@ plugin_git	gerrit_migrate_to	Migrate repo to Gerrit
 plugin_git	gerrit_past_project_warn	This repository was migrated to the server in the past. You cannot migrate again without deleting the project on the Gerrit server
 plugin_git	gerrit_past_project_delete	Delete gerrit project
 plugin_git	gerrit_server_already_migrated	The repository <em>$1</em> has already been migrated to the Gerrit project: <a href="$3">$2</a>.
+plugin_git	gerrit_server_migration_error	The migration failed $1 with the following status:
 plugin_git	permissions_on_remote_server	You can only change <strong>READ</strong> permissions since this repository is managed by a remote Gerrit server. Please note that those modifications are local to $1 <strong>ARE NOT propagated to Gerrit</strong>.
 plugin_git	gerrit_migration_ongoing	The migration of this repository to Gerrit server is on going, please wait for a few minutes.
 plugin_git	gerrit_migrate_access_right	Migrate to Gerrit the access rights defined in the Git plugin.
@@ -250,7 +251,11 @@ plugin_git	logsdaily_field	Repository name
 plugin_git	logsdaily_title	Git pushes
 
 plugin_git	delegated_to_gerrit	The management of this Git repository has been delegated to the Gerrit platform:
+plugin_git	delegated_to_gerrit_error	An error occured while migrating this repository on gerrit $1. Please check <a href="$2">gerrit settings</a> and contact site administration.
+plugin_git	delegated_to_gerrit_queue	This repository is in queue for migration to gerrit. Please check back here in a few minutes.
 plugin_git	waiting_for_repo_creation	The repository is in queue for creation. Please check back here in a few minutes
+plugin_git	delegated_to_gerrit_error_mail_subject	Migration of $1 to gerrit error
+plugin_git	delegated_to_gerrit_error_mail_body	An error occured while migrating repository $1 on gerrit. Please check <a href="$2">gerrit settings</a> and contact site administration.
 
 plugin_git	push_ssh_keys_error	Error pushing SSH Keys. Please add them manually.
 plugin_git	push_ssh_keys_button_value	Manually push SSH keys
diff --git a/plugins/git/site-content/fr_FR/git.tab b/plugins/git/site-content/fr_FR/git.tab
index ad96346..acce696 100644
--- a/plugins/git/site-content/fr_FR/git.tab
+++ b/plugins/git/site-content/fr_FR/git.tab
@@ -146,6 +146,7 @@ plugin_git	gerrit_migrate_to	Migrer repo vers Gerrit
 plugin_git	gerrit_past_project_warn	Ce dépôt a déjà été migré sur Gerrit et existe encore. Il n'est pas possible de migrer ce dépôt sur ce même serveur avant de l'avoir supprimé.
 plugin_git	gerrit_past_project_delete	Supprimer ce projet sur Gerrit
 plugin_git	gerrit_server_already_migrated	Le dépôt <em>$1</em> a déjà été migré sur le projet Gerrit : <a href="$3">$2</a>.
+plugin_git	gerrit_server_migration_error	La migration a échoué $1 avec la trace suivante:
 plugin_git	permissions_on_remote_server	Vous ne pouvez modifier QUE les permissions en <strong>LECTURE</strong>, car elles sont gérés par un serveur Gerrit distant. Ces modifications affectent uniquement $1 et <strong>NE SONT PAS propagées vers Gerrit</strong>.
 plugin_git	gerrit_migration_ongoing	La migration de ce dépôt vers le serveur Gerrit est en cours, merci de patienter quelques minutes.
 plugin_git	gerrit_migrate_access_right	Migrer sur Gerrit les permissions définies dans le plugin Git.
@@ -247,7 +248,11 @@ plugin_git	logsdaily_field	Nom du répertoire
 plugin_git	logsdaily_title	Les Git push
 
 plugin_git	delegated_to_gerrit	La gestion de ce dépôt Git a été déléguée à la plateforme Gerrit:
+plugin_git	delegated_to_gerrit_error	Une erreur s'est produite lors de la migration vers gerrit $1. Veuillez consulter <a href="$2">le rapport d'erreur</a> et contacter l'administration site.
+plugin_git	delegated_to_gerrit_queue	Le dépôt est en attente de transfert vers gerrit. Veuillez revenir dans quelques minutes.
 plugin_git	waiting_for_repo_creation	Le dépôt est en attente de création. Veuillez revenir dans quelques minutes.
+plugin_git	delegated_to_gerrit_error_mail_subject	Erreur lors de la migration de $1 vers gerrit
+plugin_git	delegated_to_gerrit_error_mail_body	Une erreur s'est produite lors de la migration de $1 vers gerrit. Veuillez consulter le statut dans la <a href="$2">section gerrit</a> et contacter l'administration site.
 
 plugin_git	push_ssh_keys_error	Impossible de copier les clés SSH. Ajoutez-les de façon manuelle.
 plugin_git	push_ssh_keys_button_value	Pousser les clés SSH
diff --git a/plugins/git/tests/Git/Driver/Gerrit/ProjectCreatorStatusTest.php b/plugins/git/tests/Git/Driver/Gerrit/ProjectCreatorStatusTest.php
new file mode 100644
index 0000000..1cce1b0
--- /dev/null
+++ b/plugins/git/tests/Git/Driver/Gerrit/ProjectCreatorStatusTest.php
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * Copyright (c) Enalean, 2016. All Rights Reserved.
+ *
+ * This file is a part of Tuleap.
+ *
+ * Tuleap is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Tuleap is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+require_once dirname(__FILE__).'/../../../bootstrap.php';
+
+class ProjectCreatorStatusTest extends TuleapTestCase {
+
+    private $dao;
+    private $repository;
+    private $gerrit_status;
+
+    public function setUp() {
+        parent::setUp();
+
+        $this->dao        = mock('Git_Driver_Gerrit_ProjectCreatorStatusDao');
+        $this->repository = mock('GitRepository');
+
+        $this->gerrit_status = new Git_Driver_Gerrit_ProjectCreatorStatus($this->dao);
+    }
+
+    public function itIsStatusErrorWhenGitRepositoryIsError() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getMigrationStatus()->returns(Git_Driver_Gerrit_ProjectCreatorStatus::ERROR);
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::ERROR, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    // We don't know what project did with their repo until this change
+    // So we assume everything is OK.
+    public function itHasStatusDoneWhenOnlySystemEventIsErrorForLegacy() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getMigrationStatus()->returns(null);
+
+        stub($this->dao)->getSystemEventForRepository()->returns(
+            array(
+                'status'      => SystemEvent::STATUS_ERROR,
+                'create_date' => '1453886645',
+                'log'         => 'stuff',
+            )
+        );
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::DONE, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    // We don't know what project did with their repo until this change
+    // So we assume everything is OK.
+    public function itHasStatusDoneWhenOnlySystemEventIsWarningForLegacy() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getMigrationStatus()->returns(null);
+
+        stub($this->dao)->getSystemEventForRepository()->returns(
+            array(
+                'status'      => SystemEvent::STATUS_WARNING,
+                'create_date' => '1453886645',
+                'log'         => 'stuff',
+            )
+        );
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::DONE, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    public function itHasStatusDoneWhenSystemEventIsDone() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getMigrationStatus()->returns(null);
+
+        stub($this->dao)->getSystemEventForRepository()->returns(
+            array(
+                'status'      => SystemEvent::STATUS_DONE,
+                'create_date' => '1453886645',
+                'log'         => '',
+            )
+        );
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::DONE, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    public function itHasStatusDoneWhenRepositoryIsExplicitlyMarkedAsDone() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getMigrationStatus()->returns(Git_Driver_Gerrit_ProjectCreatorStatus::DONE);
+
+        stub($this->dao)->getSystemEventForRepository()->returns(null);
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::DONE, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    public function itHasStatusQueueWhenSystemEventIsNew() {
+        stub($this->repository)->isMigratedToGerrit()->returns(false);
+        stub($this->repository)->getMigrationStatus()->returns(null);
+
+        stub($this->dao)->getSystemEventForRepository()->returns(
+            array(
+                'status'      => SystemEvent::STATUS_NEW,
+                'create_date' => '1453886645',
+                'log'         => '',
+            )
+        );
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::QUEUE, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    public function itHasStatusQueueWhenSystemEventIsRunning() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getMigrationStatus()->returns(null);
+
+        stub($this->dao)->getSystemEventForRepository()->returns(
+            array(
+                'status'      => SystemEvent::STATUS_RUNNING,
+                'create_date' => '1453886645',
+                'log'         => '',
+            )
+        );
+
+        $this->assertEqual(Git_Driver_Gerrit_ProjectCreatorStatus::QUEUE, $this->gerrit_status->getStatus($this->repository));
+    }
+
+    public function itHasStatusNullWhenRepositoryIsNotMigrated() {
+        stub($this->repository)->isMigratedToGerrit()->returns(false);
+        stub($this->repository)->getMigrationStatus()->returns(Git_Driver_Gerrit_ProjectCreatorStatus::DONE);
+
+        $this->assertEqual(null, $this->gerrit_status->getStatus($this->repository));
+    }
+}
diff --git a/plugins/git/tests/Git/Gitolite/ConfigPermissionsSerializerTest.php b/plugins/git/tests/Git/Gitolite/ConfigPermissionsSerializerTest.php
index 335ad64..4b68aab 100644
--- a/plugins/git/tests/Git/Gitolite/ConfigPermissionsSerializerTest.php
+++ b/plugins/git/tests/Git/Gitolite/ConfigPermissionsSerializerTest.php
@@ -52,6 +52,7 @@ class Git_Gitolite_ConfigPermissionsSerializerTest extends TuleapTestCase {
 
         $this->serializer = new Git_Gitolite_ConfigPermissionsSerializer(
             stub('Git_Mirror_MirrorDataMapper')->fetchAllRepositoryMirrors()->returns(array()),
+            mock('Git_Driver_Gerrit_ProjectCreatorStatus'),
             'whatever'
         );
     }
@@ -144,7 +145,7 @@ class Git_Gitolite_ConfigPermissionsSerializer_MirrorsTest extends TuleapTestCas
     public function setUp() {
         parent::setUp();
         $this->mirror_mapper = mock('Git_Mirror_MirrorDataMapper');
-        $this->serializer    = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, 'whatever');
+        $this->serializer    = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, mock('Git_Driver_Gerrit_ProjectCreatorStatus'), 'whatever');
         $this->project       = stub('Project')->getUnixName()->returns('foo');
         $this->repository    = aGitRepository()->withId(115)->withProject($this->project)->build();
 
@@ -216,7 +217,7 @@ class Git_Gitolite_ConfigPermissionsSerializer_GitoliteConfTest extends TuleapTe
 
     public function itDumpsTheConf() {
         stub($this->mirror_mapper)->fetchAll()->returns(array());
-        $serializer = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, 'whatever');
+        $serializer = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, mock('Git_Driver_Gerrit_ProjectCreatorStatus'), 'whatever');
         $this->assertEqual(
             file_get_contents(dirname(__FILE__).'/_fixtures/default_gitolite.conf'),
             $serializer->getGitoliteDotConf(array('projecta', 'projectb'))
@@ -225,7 +226,7 @@ class Git_Gitolite_ConfigPermissionsSerializer_GitoliteConfTest extends TuleapTe
 
     public function itAllowsOverrideBySiteAdmin() {
         stub($this->mirror_mapper)->fetchAll()->returns(array());
-        $serializer = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, dirname(__FILE__).'/_fixtures/etc_templates');
+        $serializer = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, mock('Git_Driver_Gerrit_ProjectCreatorStatus'), dirname(__FILE__).'/_fixtures/etc_templates');
         $this->assertEqual(
             file_get_contents(dirname(__FILE__).'/_fixtures/override_gitolite.conf'),
             $serializer->getGitoliteDotConf(array('projecta', 'projectb'))
@@ -234,10 +235,144 @@ class Git_Gitolite_ConfigPermissionsSerializer_GitoliteConfTest extends TuleapTe
 
     public function __only__itGrantsReadAccessToGitoliteAdminForMirrorUsers() {
         stub($this->mirror_mapper)->fetchAll()->returns(array($this->mirror_1, $this->mirror_2));
-        $serializer = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, 'whatever');
+        $serializer = new Git_Gitolite_ConfigPermissionsSerializer($this->mirror_mapper, mock('Git_Driver_Gerrit_ProjectCreatorStatus'), 'whatever');
         $this->assertEqual(
             file_get_contents(dirname(__FILE__).'/_fixtures/mirrors_gitolite.conf'),
             $serializer->getGitoliteDotConf(array('projecta', 'projectb'))
         );
     }
 }
+
+class Git_Gitolite_ConfigPermissionsSerializer_GerritTest extends TuleapTestCase {
+
+    private $serializer;
+    private $repository;
+    private $gerrit_status;
+
+    public function setUp() {
+        parent::setUp();
+
+        $project = mock('Project');
+        stub($project)->getId()->returns(102);
+        stub($project)->getUnixName()->returns('gpig');
+
+        $this->repository = mock('GitRepository');
+        stub($this->repository)->getId()->returns(1001);
+        stub($this->repository)->getProject()->returns($project);
+
+        PermissionsManager::setInstance(mock('PermissionsManager'));
+        $this->permissions_manager = PermissionsManager::instance();
+
+        stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject('*', '*', Git::PERM_READ)->returns(array(ProjectUGroup::REGISTERED));
+        stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject('*', '*', Git::PERM_WRITE)->returns(array(ProjectUGroup::PROJECT_MEMBERS));
+        stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject('*', '*', Git::PERM_WPLUS)->returns(array());
+
+        $this->gerrit_status = mock('Git_Driver_Gerrit_ProjectCreatorStatus');
+
+        $this->serializer = new Git_Gitolite_ConfigPermissionsSerializer(
+            stub('Git_Mirror_MirrorDataMapper')->fetchAllRepositoryMirrors()->returns(array()),
+            $this->gerrit_status,
+            'whatever'
+        );
+    }
+
+    public function tearDown() {
+        PermissionsManager::clearInstance();
+        parent::tearDown();
+    }
+
+    public function itGeneratesTheDefaultConfiguration() {
+        $this->assertEqual(
+            " R   = @site_active @gpig_project_members\n".
+            " RW  = @gpig_project_members\n",
+            $this->serializer->getForRepository($this->repository)
+        );
+    }
+
+    public function itGrantsEverythingToGerritUserAfterMigrationIsDoneWithSuccess() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getRemoteServerId()->returns(2);
+
+        stub($this->gerrit_status)->getStatus($this->repository)->returns(
+            Git_Driver_Gerrit_ProjectCreatorStatus::DONE
+        );
+
+        $this->assertEqual(
+            " R   = @site_active @gpig_project_members\n".
+            " RW+ = forge__gerrit_2\n",
+            $this->serializer->getForRepository($this->repository)
+        );
+    }
+
+    public function itDoesntGrantAllPermissionsToGerritIfMigrationIsWaitingForExecution() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getRemoteServerId()->returns(2);
+
+        stub($this->gerrit_status)->getStatus($this->repository)->returns(
+            Git_Driver_Gerrit_ProjectCreatorStatus::QUEUE
+        );
+
+        $this->assertEqual(
+            " R   = @site_active @gpig_project_members\n".
+            " RW  = @gpig_project_members\n",
+            $this->serializer->getForRepository($this->repository)
+        );
+    }
+
+    public function itDoesntGrantAllPermissionsToGerritIfMigrationIsError() {
+        stub($this->repository)->isMigratedToGerrit()->returns(true);
+        stub($this->repository)->getRemoteServerId()->returns(2);
+
+        stub($this->gerrit_status)->getStatus($this->repository)->returns(
+            Git_Driver_Gerrit_ProjectCreatorStatus::ERROR
+        );
+
+        $this->assertEqual(
+            " R   = @site_active @gpig_project_members\n".
+            " RW  = @gpig_project_members\n",
+            $this->serializer->getForRepository($this->repository)
+        );
+    }
+}
+
+class Git_Gitolite_ConfigPermissionsSerializer_GerritAndMirrorsTest extends TuleapTestCase {
+
+    private $serializer;
+    private $repository;
+    private $gerrit_status;
+
+    public function setUp() {
+        parent::setUp();
+
+        $project = mock('Project');
+        stub($project)->getId()->returns(102);
+        stub($project)->getUnixName()->returns('gpig');
+
+        $this->repository = mock('GitRepository');
+        stub($this->repository)->getId()->returns(1001);
+        stub($this->repository)->getProject()->returns($project);
+
+        PermissionsManager::setInstance(mock('PermissionsManager'));
+        $this->permissions_manager = PermissionsManager::instance();
+
+        stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject('*', '*', Git::PERM_READ)->returns(array(ProjectUGroup::REGISTERED));
+        stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject('*', '*', Git::PERM_WRITE)->returns(array(ProjectUGroup::PROJECT_MEMBERS));
+        stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject('*', '*', Git::PERM_WPLUS)->returns(array());
+
+        $this->gerrit_status = mock('Git_Driver_Gerrit_ProjectCreatorStatus');
+
+        $user_mirror1        = aUser()->withUserName('git_mirror_1')->build();
+        $this->mirror_1      = new Git_Mirror_Mirror($user_mirror1, 1, 'url', 'hostname', 'EUR');
+
+        $this->serializer = new Git_Gitolite_ConfigPermissionsSerializer(
+            stub('Git_Mirror_MirrorDataMapper')->fetchAllRepositoryMirrors()->returns(array()),
+            $this->gerrit_status,
+            'whatever'
+        );
+    }
+
+    public function tearDown() {
+        PermissionsManager::clearInstance();
+        parent::tearDown();
+    }
+}
\ No newline at end of file
diff --git a/plugins/git/tests/Git/Gitolite/ProjectSerializerTest.php b/plugins/git/tests/Git/Gitolite/ProjectSerializerTest.php
index 7f1f1da..9c15732 100644
--- a/plugins/git/tests/Git/Gitolite/ProjectSerializerTest.php
+++ b/plugins/git/tests/Git/Gitolite/ProjectSerializerTest.php
@@ -29,6 +29,7 @@ class ProjectSerializerTest extends TuleapTestCase {
     private $logger;
     private $_fixDir;
     private $permissions_manager;
+    private $gerrit_project_status;
 
     public function setUp() {
         parent::setUp();
@@ -49,8 +50,11 @@ class ProjectSerializerTest extends TuleapTestCase {
         stub($mirror_data_mapper)->fetchAllRepositoryMirrors()->returns(array());
         stub($mirror_data_mapper)->fetchAll()->returns(array());
 
+        $this->gerrit_project_status = mock('Git_Driver_Gerrit_ProjectCreatorStatus');
+
         $this->gitolite_permissions_serializer = new Git_Gitolite_ConfigPermissionsSerializer(
             $mirror_data_mapper,
+            $this->gerrit_project_status,
             'whatever'
         );
 
@@ -260,6 +264,7 @@ class ProjectSerializerTest extends TuleapTestCase {
         stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject($prj, 5, 'PLUGIN_GIT_WRITE')->returns(array('3'));
         stub($this->permissions_manager)->getAuthorizedUGroupIdsForProject($prj, 5, 'PLUGIN_GIT_WPLUS')->returns(array('125'));
 
+        stub($this->gerrit_project_status)->getStatus()->returns(Git_Driver_Gerrit_ProjectCreatorStatus::DONE);
 
         // Ensure file is correct
         $result     = $this->project_serializer->dumpProjectRepoConf($prj);
diff --git a/plugins/git/tests/Git/SystemEventManagerTest.php b/plugins/git/tests/Git/SystemEventManagerTest.php
index ebd3e28..9b6b614 100644
--- a/plugins/git/tests/Git/SystemEventManagerTest.php
+++ b/plugins/git/tests/Git/SystemEventManagerTest.php
@@ -128,15 +128,16 @@ class Git_SystemEventManagerTest extends TuleapTestCase {
         $repository           = stub('GitRepository')->getId()->returns(54);
         $remote_server_id     = 3;
         $migrate_access_right = true;
+        $requester            = stub('PFUser')->getId()->returns(1001);
 
         expect($this->system_event_manager)->createEvent(
             SystemEvent_GIT_GERRIT_MIGRATION::NAME,
-            54 . SystemEvent::PARAMETER_SEPARATOR . $remote_server_id . SystemEvent::PARAMETER_SEPARATOR . true,
+            54 . SystemEvent::PARAMETER_SEPARATOR . $remote_server_id . SystemEvent::PARAMETER_SEPARATOR . true . SystemEvent::PARAMETER_SEPARATOR . 1001,
             SystemEvent::PRIORITY_HIGH,
             SystemEvent::OWNER_APP
         )->once();
 
-        $this->git_system_event_manager->queueMigrateToGerrit($repository, $remote_server_id, $migrate_access_right);
+        $this->git_system_event_manager->queueMigrateToGerrit($repository, $remote_server_id, $migrate_access_right, $requester);
     }
 
     public function itCreatesGerritReplicationKeyUpdateEvent() {
@@ -152,5 +153,3 @@ class Git_SystemEventManagerTest extends TuleapTestCase {
         $this->git_system_event_manager->queueGerritReplicationKeyUpdate($server);
     }
 }
-
-?>
diff --git a/plugins/git/tests/GitActionsTest.php b/plugins/git/tests/GitActionsTest.php
index 39cc7da..e0f6280 100644
--- a/plugins/git/tests/GitActionsTest.php
+++ b/plugins/git/tests/GitActionsTest.php
@@ -680,22 +680,23 @@ class GitActions_migrateToGerritTest extends TuleapTestCase {
     public function itDoesNothingWhenGivenServerDoesNotExist() {
         $repo = stub('GitRepository')->canMigrateToGerrit()->returns(true);
         expect($this->git_system_event_manager)->queueMigrateToGerrit()->never();
-        $this->actions->migrateToGerrit($repo, $this->unexsting_server_id, true);
+        $this->actions->migrateToGerrit($repo, $this->unexsting_server_id, true, mock('PFUser'));
     }
 
     public function itDoesNothingWhenItIsntMigratable() {
         $repo = stub('GitRepository')->canMigrateToGerrit()->returns(false);
         expect($this->git_system_event_manager)->queueMigrateToGerrit()->never();
-        $this->actions->migrateToGerrit($repo, 0, true);
+        $this->actions->migrateToGerrit($repo, 0, true, mock('PFUser'));
     }
 
     public function itCreatesASystemEvent() {
         $repo = stub('GitRepository')->canMigrateToGerrit()->returns(true);
         $server_id = $this->server_id;
         $repo_id   = 456;
+        $user      = mock('PFUser');
         stub($repo)->getId()->returns($repo_id);
-        expect($this->git_system_event_manager)->queueMigrateToGerrit($repo, $server_id, true)->once();
-        $this->actions->migrateToGerrit($repo, $server_id, true);
+        expect($this->git_system_event_manager)->queueMigrateToGerrit($repo, $server_id, true, $user)->once();
+        $this->actions->migrateToGerrit($repo, $server_id, true, $user);
     }
 }
 
diff --git a/plugins/git/tests/GitTest.php b/plugins/git/tests/GitTest.php
index d3c9763..ab7c0f4 100644
--- a/plugins/git/tests/GitTest.php
+++ b/plugins/git/tests/GitTest.php
@@ -258,7 +258,7 @@ class Gittest_MigrateToGerritRouteTest extends Git_RouteBaseTestCase {
         $factory = stub('GitRepositoryFactory')->getRepositoryById()->once()->returns($repo);
         $git     = $this->getGit($request, $factory);
 
-        expect($git)->addAction('migrateToGerrit', array($repo, $server_id, $gerrit_template_id))->at(0);
+        expect($git)->addAction('migrateToGerrit', array($repo, $server_id, $gerrit_template_id, $this->admin))->at(0);
         expect($git)->addAction('redirectToRepoManagementWithMigrationAccessRightInformation', '*')->at(1);
 
         $git->request();
diff --git a/plugins/git/tests/Git_GitoliteDriverTest.php b/plugins/git/tests/Git_GitoliteDriverTest.php
index fc92ce0..7dd3bf6 100644
--- a/plugins/git/tests/Git_GitoliteDriverTest.php
+++ b/plugins/git/tests/Git_GitoliteDriverTest.php
@@ -54,6 +54,7 @@ class Git_GitoliteDriverTest extends Git_GitoliteTestCase {
 
         $this->another_gitolite_permissions_serializer = new Git_Gitolite_ConfigPermissionsSerializer(
             $this->mirror_data_mapper,
+            mock('Git_Driver_Gerrit_ProjectCreatorStatus'),
             'whatever'
         );
 
diff --git a/plugins/git/tests/Git_GitoliteTestCase.class.php b/plugins/git/tests/Git_GitoliteTestCase.class.php
index 9dd8910..ac70d42 100644
--- a/plugins/git/tests/Git_GitoliteTestCase.class.php
+++ b/plugins/git/tests/Git_GitoliteTestCase.class.php
@@ -95,6 +95,7 @@ abstract class Git_GitoliteTestCase extends TuleapTestCase {
 
         $this->gitolite_permissions_serializer = new Git_Gitolite_ConfigPermissionsSerializer(
             $this->mirror_data_mapper,
+            mock('Git_Driver_Gerrit_ProjectCreatorStatus'),
             'whatever'
         );
 
diff --git a/plugins/git/tests/events/SystemEvent_GIT_GERRIT_MIGRATIONTest.php b/plugins/git/tests/events/SystemEvent_GIT_GERRIT_MIGRATIONTest.php
index b0d953b..eace7ea 100644
--- a/plugins/git/tests/events/SystemEvent_GIT_GERRIT_MIGRATIONTest.php
+++ b/plugins/git/tests/events/SystemEvent_GIT_GERRIT_MIGRATIONTest.php
@@ -35,6 +35,7 @@ abstract class SystemEvent_GIT_GERRIT_MIGRATION_BaseTest extends TuleapTestCase
     protected $gerrit_server;
     protected $server_factory;
     protected $gitolite_backend;
+    protected $user_manager;
 
     public function setUp() {
         parent::setUp();
@@ -45,6 +46,7 @@ abstract class SystemEvent_GIT_GERRIT_MIGRATION_BaseTest extends TuleapTestCase
         $this->project_creator  = mock('Git_Driver_Gerrit_ProjectCreator');
         $this->gitolite_backend = mock('Git_Backend_Gitolite');
         $this->repository       = mock('GitRepository');
+        $this->user_manager     = mock('UserManager');
         stub($this->repository)->getBackend()->returns($this->gitolite_backend);
 
         $factory = mock('GitRepositoryFactory');
@@ -55,7 +57,7 @@ abstract class SystemEvent_GIT_GERRIT_MIGRATION_BaseTest extends TuleapTestCase
                                                   array($id, $type, $parameters, $priority, $status, $create_date, $process_date, $end_date, $log));
         $this->event->setParameters("$this->repository_id::$this->remote_server_id::true");
         $this->logger = mock('Logger');
-        $this->event->injectDependencies($this->dao, $factory, $this->server_factory, $this->logger, $this->project_creator, mock('Git_GitRepositoryUrlManager'));
+        $this->event->injectDependencies($this->dao, $factory, $this->server_factory, $this->logger, $this->project_creator, mock('Git_GitRepositoryUrlManager'), $this->user_manager);
     }
 }
 
@@ -90,6 +92,7 @@ class SystemEvent_GIT_GERRIT_MIGRATION_BackendTest extends SystemEvent_GIT_GERRI
     }
 
     public function itInformsAboutAnyGenericFailure() {
+        stub($this->user_manager)->getUserById()->returns(aUser()->withId(0)->build());
         $e = new Exception("failure detail");
         stub($this->project_creator)->createGerritProject()->throws($e);
         expect($this->event)->error("failure detail")->once();
@@ -98,6 +101,7 @@ class SystemEvent_GIT_GERRIT_MIGRATION_BackendTest extends SystemEvent_GIT_GERRI
     }
 
     public function itInformsAboutAnyGerritRelatedFailureByAddingAPrefix() {
+        stub($this->user_manager)->getUserById()->returns(aUser()->withId(0)->build());
         $e = new Git_Driver_Gerrit_Exception("failure detail");
         stub($this->project_creator)->createGerritProject()->throws($e);
         expect($this->event)->error("gerrit: failure detail")->once();
@@ -106,6 +110,7 @@ class SystemEvent_GIT_GERRIT_MIGRATION_BackendTest extends SystemEvent_GIT_GERRI
     }
 
     public function itInformsAboutAnyServerFactoryFailure() {
+        stub($this->user_manager)->getUserById()->returns(aUser()->withId(0)->build());
         $e = new Exception("failure detail");
         stub($this->server_factory)->getServer()->throws($e);
         expect($this->event)->error("failure detail")->once();
@@ -115,7 +120,7 @@ class SystemEvent_GIT_GERRIT_MIGRATION_BackendTest extends SystemEvent_GIT_GERRI
 
     public function itMarksTheEventAsWarningWhenTheRepoDoesNotExist() {
         $this->event->setParameters("$this->deleted_repository_id::$this->remote_server_id");
-        expect($this->event)->warning('Unable to find repository, perhaps it was deleted in the mean time?')->once();
+        expect($this->event)->error('Unable to find repository, perhaps it was deleted in the mean time?')->once();
         $this->event->process();
     }
 }
-- 
1.9.1

