def localChanges(self, layer):
     filename, layername = namesFromLayer(layer)
     con = sqlite3.connect(filename)
     cursor = con.cursor()
     attributes = [v[1] for v in cursor.execute("PRAGMA table_info('%s');" % layername)]
     attrnames = [a for a in attributes if a != "fid"]
     cursor.execute("SELECT * FROM %s_audit;" % layername)
     changes = cursor.fetchall()
     changesdict = {}
     tracking = getTrackingInfo(layer)
     repo = Repository(tracking.repoUrl)
     commitid = cursor.execute("SELECT commit_id FROM geogig_audited_tables WHERE table_name='%s';" % layername).fetchone()[0]
     geomField = cursor.execute("SELECT column_name FROM gpkg_geometry_columns WHERE table_name='%s';" % layername).fetchone()[0]
     for c in changes:
         featurechanges = {}
         path = str(c[attributes.index("fid")])
         for attr in attrnames:
             if c[-1] == LOCAL_FEATURE_REMOVED:
                 value = None
             else:
                 if attr != geomField:
                     value = c[attributes.index(attr)]
                 else:
                     request = QgsFeatureRequest().setFilterExpression("fid=%s" % path)
                     features = list(layer.getFeatures(request))
                     if len(features) == 0:
                         continue
                     value = features[0].geometry().exportToWkt().upper()
             featurechanges[attr] = value
         path = geogigFidFromGpkgFid(tracking, path)
         changesdict[path] = LocalDiff(layername, path, repo, featurechanges, commitid, c[-1])
     return changesdict
def revertChange(layer):
    if hasLocalChanges(layer):
        QMessageBox.warning(config.iface.mainWindow(), 'Cannot revert commit',
                "The layer has local changes.\n"
                "Revert local changes before reverting a previous commit.",
                QMessageBox.Ok)
        return
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    filename, layername = namesFromLayer(layer)
    from geogig.gui.dialogs.historyviewer import HistoryViewerDialog
    dlg = HistoryViewerDialog(repo, layername)
    dlg.exec_()
    if dlg.ref is not None:
        #TODO check that selected commit is in history line

        commit = Commit.fromref(repo, dlg.ref)
        # check if we are reverting commit which adds layer to the repo
        if commit.addsLayer():
            QMessageBox.warning(config.iface.mainWindow(), 'Cannot revert commit',
                    "Commits which add layer to the repository can not "
                    "be reverted. Use GeoGig Navigator to remove layer "
                    "from branch.")
            return

        applyLayerChanges(repo, layer, commit.commitid, commit.parent.commitid, False)
        layer.reload()
        layer.triggerRepaint()
        config.iface.messageBar().pushMessage("GeoGig", "Commit changes have been reverted in local layer",
                                                      level=QgsMessageBar.INFO,
                                                      duration=5)
        commitdialog.suggestedMessage = "Reverted changes from commit %s [%s] " % (commit.commitid, commit.message)
def addInfoActions(layer):
    commitId = getCommitId(layer)
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    _infoActions[layer.id()] = []
    try:
        commit = Commit.fromref(repo, commitId)
        messageAction = QAction(
            "Message: '%s'" % commit.message.splitlines()[0],
            config.iface.legendInterface())
        f = messageAction.font()
        f.setBold(True)
        messageAction.setFont(f)
        config.iface.legendInterface().addLegendLayerAction(
            messageAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
        config.iface.legendInterface().addLegendLayerActionForLayer(
            messageAction, layer)
        _infoActions[layer.id()].append(messageAction)
    except Exception, e:
        QgsMessageLog.logMessage(
            "Cannot connect to server when creating GeoGig layer context:\n %s"
            % str(e),
            level=QgsMessageLog.WARNING)
        messageAction = QAction("Error: Cannot connect with repository",
                                config.iface.legendInterface())
        f = messageAction.font()
        f.setBold(True)
        messageAction.setFont(f)
        config.iface.legendInterface().addLegendLayerAction(
            messageAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
        config.iface.legendInterface().addLegendLayerActionForLayer(
            messageAction, layer)
        _infoActions[layer.id()].append(messageAction)
        return False
def changeVersion(layer):
    if hasLocalChanges(layer):
        QMessageBox.warning(config.iface.mainWindow(), 'Cannot change commit',
                "The layer has local changes that would be overwritten. "
                "Either sync layer with branch or revert local changes "
                "before changing commit.",
                QMessageBox.Ok)
    else:
        tracking = getTrackingInfo(layer)
        repo = Repository(tracking.repoUrl)
        dlg = HistoryViewerDialog(repo, tracking.layername)
        dlg.exec_()
        if dlg.ref is not None:
            layers = repo.trees(dlg.ref)
            if tracking.layername not in layers:
                QMessageBox.warning(config.iface.mainWindow(), 'Cannot change commit',
                "The selected commit does not contain the specified layer.",
                QMessageBox.Ok)
            else:
                repo.checkoutlayer(tracking.geopkg, tracking.layername, None, dlg.ref)
                config.iface.messageBar().pushMessage("GeoGig", "Layer has been updated to commit %s" % dlg.ref,
                                                       level=QgsMessageBar.INFO,
                                                       duration=5)
                layer.reload()
                layer.triggerRepaint()
                repoWatcher.layerUpdated.emit(layer)
                repoWatcher.repoChanged.emit(repo)
 def localChanges(self, layer):
     filename, layername = namesFromLayer(layer)
     con = sqlite3.connect(filename)
     cursor = con.cursor()
     attributes = [v[1] for v in cursor.execute("PRAGMA table_info('%s');" % layername)]
     attrnames = [a for a in attributes if a != "fid"]
     cursor.execute("SELECT * FROM %s_audit;" % layername)
     changes = cursor.fetchall()
     changesdict = {}
     tracking = getTrackingInfo(layer)
     repo = Repository(tracking.repoUrl)
     commitid = cursor.execute("SELECT commit_id FROM geogig_audited_tables WHERE table_name='%s';" % layername).fetchone()[0]
     geomField = cursor.execute("SELECT column_name FROM gpkg_geometry_columns WHERE table_name='%s';" % layername).fetchone()[0]
     for c in changes:
         featurechanges = {}
         path = str(c[attributes.index("fid")])
         for attr in attrnames:
             if c[-1] == LOCAL_FEATURE_REMOVED:
                 value = None
             else:
                 if attr != geomField:
                     value = c[attributes.index(attr)]
                 else:
                     request = QgsFeatureRequest().setFilterExpression("fid=%s" % path)
                     features = list(layer.getFeatures(request))
                     if len(features) == 0:
                         continue
                     value = features[0].geometry().exportToWkt().upper()
             featurechanges[attr] = value
         path = geogigFidFromGpkgFid(tracking, path)
         changesdict[path] = LocalDiff(layername, path, repo, featurechanges, commitid, c[-1])
     return changesdict
    def canvasPressEvent(self, e):
        layer = config.iface.activeLayer()
        if layer is None or not isinstance(layer, QgsVectorLayer):
            config.iface.messageBar().pushMessage("No layer selected or the current active layer is not a valid vector layer",
                                                  level = QgsMessageBar.WARNING, duration = 4)
            return
        if not layertracking.isTracked(layer):
            config.iface.messageBar().pushMessage("The current active layer is not being tracked as part of a GeoGig repo",
                                                  level = QgsMessageBar.WARNING, duration = 4)
            return

        trackedlayer = layertracking.getTrackingInfo(layer)
        point = self.toMapCoordinates(e.pos())
        searchRadius = self.canvas().extent().width() * .01;
        r = QgsRectangle()
        r.setXMinimum(point.x() - searchRadius);
        r.setXMaximum(point.x() + searchRadius);
        r.setYMinimum(point.y() - searchRadius);
        r.setYMaximum(point.y() + searchRadius);

        r = self.toLayerCoordinates(layer, r);

        fit = layer.getFeatures(QgsFeatureRequest().setFilterRect(r).setFlags(QgsFeatureRequest.ExactIntersect));
        fid = None
        try:
            feature = fit.next()
            try:
                fid = unicode(feature["geogigid"])
            except:
                pass
        except StopIteration, e:
            return
def changeVersion(layer):
    if hasLocalChanges(layer):
        QMessageBox.warning(
            config.iface.mainWindow(), 'Cannot change version',
            "There are local changes that would be overwritten.\n"
            "Revert them before changing version.", QMessageBox.Ok)
    else:
        tracking = getTrackingInfo(layer)
        repo = Repository(tracking.repoUrl)
        dlg = HistoryViewerDialog(repo, tracking.layername)
        dlg.exec_()
        if dlg.ref is not None:
            layers = repo.trees(dlg.ref)
            if tracking.layername not in layers:
                QMessageBox.warning(
                    config.iface.mainWindow(), 'Cannot change version',
                    "The selected version does not contain the specified layer.",
                    QMessageBox.Ok)
            else:
                repo.checkoutlayer(tracking.geopkg, tracking.layername, None,
                                   dlg.ref)
                config.iface.messageBar().pushMessage(
                    "GeoGig",
                    "Layer has been updated to version %s" % dlg.ref,
                    level=QgsMessageBar.INFO,
                    duration=5)
                layer.reload()
                layer.triggerRepaint()
                repoWatcher.layerUpdated.emit(layer)
                repoWatcher.repoChanged.emit(repo)
def _checkLayerNotInRepo():
    layer = layerFromName("points")
    tracking = getTrackingInfo(layer)
    assert tracking is None
    connector = PyQtConnectorDecorator()
    connector.checkIsAlive()
    repo =  Repository(os.path.join(_tempReposPath, "repos", "pointsrepo"), connector)
    layers = [tree.path for tree in repo.trees]
    assert "points" not in layers
def _checkLayerInRepo():
    layer = layerFromName("points")
    tracking = getTrackingInfo(layer)
    assert tracking is not None
    connector = PyQtConnectorDecorator()
    connector.checkIsAlive()
    repo =  Repository(tracking.repoFolder, connector)
    layers = [tree.path for tree in repo.trees]
    assert "points" in layers
    removeTrackedLayer(layer)
 def changeVersion(self, repo, layer, commit):
     if hasLocalChanges(layer):
         QMessageBox.warning(config.iface.mainWindow(), 'Cannot switch to this commit',
             "There are local changes that would be overwritten.\n"
             "Revert them before retrying this operation.",
             QMessageBox.Ok)
     else:
         tracking = getTrackingInfo(layer)
         repo.checkoutlayer(tracking.geopkg, tracking.layername, None, commit)
         config.iface.messageBar().pushMessage("GeoGig", "Layer has been updated to commit %s" % commit,
                                                level=QgsMessageBar.INFO,
                                                duration=5)
         layer.reload()
         layer.triggerRepaint()
         repoWatcher.layerUpdated.emit(layer)
def revertLocalChanges(layer):
    if hasLocalChanges(layer):
        tracking = getTrackingInfo(layer)
        repo = Repository(tracking.repoUrl)
        commitid = getCommitId(layer)
        repo.checkoutlayer(tracking.geopkg, tracking.layername, None, commitid)
        config.iface.messageBar().pushMessage("GeoGig", "Local changes have been discarded",
                                                      level=QgsMessageBar.INFO,
                                                      duration=5)
        layer.reload()
        layer.triggerRepaint()
    else:
        config.iface.messageBar().pushMessage("GeoGig", "No local changes were found",
                                                      level=QgsMessageBar.INFO,
                                                      duration=5)
def revertLocalChanges(layer):
    if hasLocalChanges(layer):
        tracking = getTrackingInfo(layer)
        repo = Repository(tracking.repoUrl)
        commitid = getCommitId(layer)
        repo.checkoutlayer(tracking.geopkg, tracking.layername, None, commitid)
        config.iface.messageBar().pushMessage(
            "GeoGig",
            "Local changes have been discarded",
            level=QgsMessageBar.INFO,
            duration=5)
        layer.reload()
        layer.triggerRepaint()
    else:
        config.iface.messageBar().pushMessage("GeoGig",
                                              "No local changes were found",
                                              level=QgsMessageBar.INFO,
                                              duration=5)
Beispiel #13
0
 def changeVersion(self, repo, layer, commit):
     if hasLocalChanges(layer):
         QMessageBox.warning(
             config.iface.mainWindow(), 'Cannot switch to this commit',
             "There are local changes that would be overwritten.\n"
             "Revert them before retrying this operation.", QMessageBox.Ok)
     else:
         tracking = getTrackingInfo(layer)
         repo.checkoutlayer(tracking.geopkg, tracking.layername, None,
                            commit)
         config.iface.messageBar().pushMessage(
             "GeoGig",
             "Layer has been updated to commit %s" % commit,
             level=QgsMessageBar.INFO,
             duration=5)
         layer.reload()
         layer.triggerRepaint()
         repoWatcher.layerUpdated.emit(layer)
Beispiel #14
0
    def canvasPressEvent(self, e):
        layer = config.iface.activeLayer()
        if layer is None or not isinstance(layer, QgsVectorLayer):
            config.iface.messageBar().pushMessage("No layer selected or the current active layer is not a valid vector layer",
                                                  level = QgsMessageBar.WARNING, duration = 5)
            return
        if not layertracking.isRepoLayer(layer):
            config.iface.messageBar().pushMessage("The current active layer is not being tracked as part of a GeoGig repo",
                                                  level = QgsMessageBar.WARNING, duration = 5)
            return

        trackedlayer = layertracking.getTrackingInfo(layer)
        point = self.toMapCoordinates(e.pos())
        searchRadius = self.canvas().extent().width() * .01;
        r = QgsRectangle()
        r.setXMinimum(point.x() - searchRadius);
        r.setXMaximum(point.x() + searchRadius);
        r.setYMinimum(point.y() - searchRadius);
        r.setYMaximum(point.y() + searchRadius);

        r = self.toLayerCoordinates(layer, r);

        fit = layer.getFeatures(QgsFeatureRequest().setFilterRect(r).setFlags(QgsFeatureRequest.ExactIntersect));
        fid = None
        try:
            feature = next(fit)
            fid = feature.id()
            fid = geogigFidFromGpkgFid(trackedlayer, fid)
            if fid is None:
                return
        except StopIteration as e:
            return
        repo = Repository(trackedlayer.repoUrl)

        menu = QMenu()
        versionsAction = QAction("Show all versions of this feature...", None)
        versionsAction.triggered.connect(lambda: self.versions(repo, trackedlayer.layername, fid))
        menu.addAction(versionsAction)
        blameAction = QAction("Show authorship...", None)
        blameAction.triggered.connect(lambda: self.blame(repo, trackedlayer.layername, fid))
        menu.addAction(blameAction)
        point = config.iface.mapCanvas().mapToGlobal(e.pos())
        menu.exec_(point)
def revertChange(layer):
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    currentCommitId = getCommitId(layer)
    filename, layername = namesFromLayer(layer)
    dlg = CommitSelectDialog(repo, currentCommitId, layername)
    dlg.exec_()
    if dlg.ref is not None:
        #TODO check that selected commit is in history line
        applyLayerChanges(repo, layer, dlg.ref.commitid,
                          dlg.ref.parent.commitid, False)
        layer.reload()
        layer.triggerRepaint()
        config.iface.messageBar().pushMessage(
            "GeoGig",
            "Version changes have been reverted in local layer",
            level=QgsMessageBar.INFO,
            duration=5)
        commitdialog.suggestedMessage = "Reverted changes from version %s [%s] " % (
            dlg.ref.commitid, dlg.ref.message)
def addInfoActions(layer):
    commitId = getCommitId(layer)
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    layer.infoActions = []
    try:
        commit = Commit.fromref(repo, commitId)
        messageAction = QAction(
            "Message: '%s'" % commit.message.splitlines()[0],
            config.iface.legendInterface())
        f = messageAction.font()
        f.setBold(True)
        messageAction.setFont(f)
        config.iface.legendInterface().addLegendLayerAction(
            messageAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
        config.iface.legendInterface().addLegendLayerActionForLayer(
            messageAction, layer)
        layer.infoActions.append(messageAction)
    except:
        messageAction = QAction("Error: Cannot connect with repository",
                                config.iface.legendInterface())
        f = messageAction.font()
        f.setBold(True)
        messageAction.setFont(f)
        config.iface.legendInterface().addLegendLayerAction(
            messageAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
        config.iface.legendInterface().addLegendLayerActionForLayer(
            messageAction, layer)
        layer.infoActions.append(messageAction)
        return False
    shaAction = QAction("Version ID: %s" % commitId,
                        config.iface.legendInterface())
    f = shaAction.font()
    f.setBold(True)
    shaAction.setFont(f)
    config.iface.legendInterface().addLegendLayerAction(
        shaAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
    config.iface.legendInterface().addLegendLayerActionForLayer(
        shaAction, layer)
    layer.infoActions.append(shaAction)
    return True
def revertChange(layer):
    if hasLocalChanges(layer):
        QMessageBox.warning(
            config.iface.mainWindow(), 'Cannot revert commit',
            "The layer has local changes.\n"
            "Revert local changes before reverting a previous commit.",
            QMessageBox.Ok)
        return
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    filename, layername = namesFromLayer(layer)
    from geogig.gui.dialogs.historyviewer import HistoryViewerDialog
    dlg = HistoryViewerDialog(repo, layername)
    dlg.exec_()
    if dlg.ref is not None:
        #TODO check that selected commit is in history line

        commit = Commit.fromref(repo, dlg.ref)
        # check if we are reverting commit which adds layer to the repo
        if commit.addsLayer():
            QMessageBox.warning(
                config.iface.mainWindow(), 'Cannot revert commit',
                "Commits which add layer to the repository can not "
                "be reverted. Use GeoGig Navigator to remove layer "
                "from branch.")
            return

        applyLayerChanges(repo, layer, commit.commitid, commit.parent.commitid,
                          False)
        layer.reload()
        layer.triggerRepaint()
        config.iface.messageBar().pushMessage(
            "GeoGig",
            "Commit changes have been reverted in local layer",
            level=QgsMessageBar.INFO,
            duration=5)
        commitdialog.suggestedMessage = "Reverted changes from commit %s [%s] " % (
            commit.commitid, commit.message)
Beispiel #18
0
    def canvasPressEvent(self, e):
        layer = config.iface.activeLayer()
        if layer is None or not isinstance(layer, QgsVectorLayer):
            config.iface.messageBar().pushMessage(
                "No layer selected or the current active layer is not a valid vector layer",
                level=QgsMessageBar.WARNING,
                duration=4)
            return
        if not layertracking.isTracked(layer):
            config.iface.messageBar().pushMessage(
                "The current active layer is not being tracked as part of a GeoGig repo",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        trackedlayer = layertracking.getTrackingInfo(layer)
        point = self.toMapCoordinates(e.pos())
        searchRadius = self.canvas().extent().width() * .01
        r = QgsRectangle()
        r.setXMinimum(point.x() - searchRadius)
        r.setXMaximum(point.x() + searchRadius)
        r.setYMinimum(point.y() - searchRadius)
        r.setYMaximum(point.y() + searchRadius)

        r = self.toLayerCoordinates(layer, r)

        fit = layer.getFeatures(QgsFeatureRequest().setFilterRect(r).setFlags(
            QgsFeatureRequest.ExactIntersect))
        fid = None
        try:
            feature = fit.next()
            try:
                fid = unicode(feature["geogigid"])
            except:
                pass
        except StopIteration, e:
            return
def addInfoActions(layer):
    commitId = getCommitId(layer)
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    _infoActions[layer.id()] = []
    try:
        commit = Commit.fromref(repo, commitId)
        messageAction = QAction("Message: '%s'" % commit.message.splitlines()[0], config.iface.legendInterface())
        f = messageAction.font();
        f.setBold(True);
        messageAction.setFont(f);
        config.iface.legendInterface().addLegendLayerAction(messageAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
        config.iface.legendInterface().addLegendLayerActionForLayer(messageAction, layer)
        _infoActions[layer.id()].append(messageAction)
    except Exception, e:
        QgsMessageLog.logMessage("Cannot connect to server when creating GeoGig layer context:\n %s" % str(e), level=QgsMessageLog.WARNING)
        messageAction = QAction("Error: Cannot connect with repository", config.iface.legendInterface())
        f = messageAction.font();
        f.setBold(True);
        messageAction.setFont(f);
        config.iface.legendInterface().addLegendLayerAction(messageAction, u"GeoGig", u"id1", QgsMapLayer.VectorLayer, False)
        config.iface.legendInterface().addLegendLayerActionForLayer(messageAction, layer)
        _infoActions[layer.id()].append(messageAction)
        return False
Beispiel #20
0
def syncLayer(layer):
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    filename, layername = namesFromLayer(layer)
    con = sqlite3.connect(filename)
    cursor = con.cursor()
    cursor.execute("SELECT * FROM %s_audit;" % layername)
    changes = bool(cursor.fetchall())
    cursor.close()
    con.close()
    if changes:
        con = sqlite3.connect(filename)
        cursor = con.cursor()
        beforeAttrs = set(v[1]
                          for v in cursor.execute("PRAGMA table_info('%s');" %
                                                  layername))
        afterAttrs = set(
            v[1] for v in cursor.execute("PRAGMA table_info('%s_audit');" %
                                         layername)
            if v[1] not in ["audit_timestamp", "audit_op"])
        cursor.close()
        con.close()
        if beforeAttrs != afterAttrs:
            ret = QMessageBox.warning(
                iface.mainWindow(), "Cannot commit changes to repository",
                "The structure of attributes table has been modified.\n"
                "This type of change is not supported by GeoGig.",
                QMessageBox.Yes)
            return

        user, email = config.getUserInfo()
        if user is None:
            return

        dlg = CommitDialog(repo, layername)
        dlg.exec_()
        if dlg.branch is None:
            return

        if dlg.branch not in repo.branches():
            commitId = getCommitId(layer)
            repo.createbranch(commitId, dlg.branch)
        mergeCommitId, importCommitId, conflicts, featureIds = repo.importgeopkg(
            layer, dlg.branch, dlg.message, user, email, True)

        if conflicts:
            ret = QMessageBox.warning(
                iface.mainWindow(), "Error while syncing",
                "There are conflicts between local and remote changes.\n"
                "Do you want to continue and fix them?",
                QMessageBox.Yes | QMessageBox.No)
            if ret == QMessageBox.No:
                repo.closeTransaction(conflicts[0].transactionId)
                return
            solved, resolvedConflicts = solveConflicts(conflicts)
            if not solved:
                repo.closeTransaction(conflicts[0].transactionId)
                return
            for conflict, resolution in zip(conflicts,
                                            list(resolvedConflicts.values())):
                if resolution == ConflictDialog.LOCAL:
                    conflict.resolveWithLocalVersion()
                elif resolution == ConflictDialog.REMOTE:
                    conflict.resolveWithRemoteVersion()
                elif resolution == ConflictDialog.DELETE:
                    conflict.resolveDeletingFeature()
                else:
                    conflict.resolveWithNewFeature(resolution)
            repo.commitAndCloseMergeAndTransaction(user, email,
                                                   "Resolved merge conflicts",
                                                   conflicts[0].transactionId)

        updateFeatureIds(repo, layer, featureIds)
        try:
            applyLayerChanges(repo, layer, importCommitId, mergeCommitId)
        except:
            QgsMessageLog.logMessage(
                "Database locked while syncing. Using full layer checkout instead",
                level=QgsMessageLog.CRITICAL)
            repo.checkoutlayer(tracking.geopkg, layername, None, mergeCommitId)

        commitdialog.suggestedMessage = ""
    else:
        branches = []
        for branch in repo.branches():
            trees = repo.trees(branch)
            if layername in trees:
                branches.append(branch)

        branch, ok = QInputDialog.getItem(iface.mainWindow(), "Sync",
                                          "Select branch to update from",
                                          branches, 0, False)
        if not ok:
            return
        commitId = getCommitId(layer)
        headCommitId = repo.revparse(branch)
        applyLayerChanges(repo, layer, commitId, headCommitId)

    layer.reload()
    layer.triggerRepaint()
    repoWatcher.repoChanged.emit(repo)

    iface.messageBar().pushMessage("GeoGig",
                                   "Layer has been correctly synchronized",
                                   level=QgsMessageBar.INFO,
                                   duration=5)
    repoWatcher.layerUpdated.emit(layer)