     hasRemoteData = yes
     unlockMutableOperations = _.noop
     pushedData = null
-    p = @pull().fail (e) =>
+    p = @_getAllData()
+    .then (data) =>
+      throw Errors.NoChanges unless @_areChangesMeaningful(data, @_changes)
+    .then () =>
+      @pull()
+    .fail (e) =>
+      throw Errors.NoChanges if e is Errors.NoChanges
       throw Errors.NetworkError if e is Errors.NetworkError
       hasRemoteData = no
     .then =>

      @_getAllData()
    .then (data) =>
      # Check if the changes are useful or not by hashing the changes without the last commit
      if data['__hashes']?.length > 0
        checkData = _.clone(data)
        checkData['__hashes'] = _(checkData['__hashes']).without(checkData['__hashes'][0])
        checkData = _(checkData).omit('__hashes') if checkData['__hashes'].length is 0
        [lastCommitHash, __] = @_computeCommit(checkData, @_changes)
        if lastCommitHash is data['__hashes'][0]
          @_clearChanges()
          throw Errors.NoChanges
      # Create commit hash
      [commitHash, pushedData] = @_computeCommit(data, @_changes)
      # Jsonify data
      @_encryptToJson(pushedData)
    .then (data) => if hasRemoteData then @client.put_settings(data) else @client.post_settings(data)
    .then (md5) =>
      @_setLastMd5(md5)
      # Merge changes into store
      @_clearChanges()
      @_setAllData(pushedData)
    .then () => @emit 'pushed', this
    .then () => do unlockMutableOperations
    .fail (e) =>
      do unlockMutableOperations
      return if e is Errors.NoChanges
      l "Failed push ", e
      @push() # Retry later
      throw e

  NoRemoteData: 0
  NetworkError: 1
  NoChanges: 2

$logger = -> ledger.utils.Logger.getLoggerByTag('SyncedStore')
$info = (args...) -> $logger().info(args...)

# A store able to synchronize with a remote crypted store. This store has an extra method in order to order a push or pull
# operations
