Skip to content

Commit

Permalink
Fix various conflict resolution bugs
Browse files Browse the repository at this point in the history
Among other things, when choosing the local side for a conflict, the
remote version could still end up being saved.
  • Loading branch information
dstillman committed Oct 27, 2017
1 parent 7f8699b commit f0770fa
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 132 deletions.
1 change: 0 additions & 1 deletion chrome/content/zotero/merge.js
Expand Up @@ -168,7 +168,6 @@ var Zotero_Merge_Window = new function () {
if (x.data) {
x.data.version = _conflicts[i][x.selected].version;
}
a[i] = x.data;
})

_io.dataOut = _merged;
Expand Down
7 changes: 3 additions & 4 deletions chrome/content/zotero/xpcom/sync/syncEngine.js
Expand Up @@ -880,10 +880,9 @@ Zotero.Sync.Data.Engine.prototype._downloadDeletions = Zotero.Promise.coroutine(
function (chunk) {
return Zotero.DB.executeTransaction(function* () {
for (let json of chunk) {
if (!json.deleted) continue;
let obj = objectsClass.getByLibraryAndKey(
this.libraryID, json.key
);
let data = json.data;
if (!data.deleted) continue;
let obj = objectsClass.getByLibraryAndKey(this.libraryID, data.key);
if (!obj) {
Zotero.logError("Remotely deleted " + objectType
+ " didn't exist after conflict resolution");
Expand Down
58 changes: 31 additions & 27 deletions chrome/content/zotero/xpcom/sync/syncLocal.js
Expand Up @@ -835,7 +835,6 @@ Zotero.Sync.Data.Local = {
let cachedJSON = yield this.getCacheObject(
objectType, obj.libraryID, obj.key, obj.version
);

let result = this._reconcileChanges(
objectType,
cachedJSON.data,
Expand All @@ -844,20 +843,21 @@ Zotero.Sync.Data.Local = {
['mtime', 'md5', 'dateAdded', 'dateModified']
);

// If no changes, update local version number and mark as synced
// If no changes, just update local version number and mark as synced
if (!result.changes.length && !result.conflicts.length) {
Zotero.debug("No remote changes to apply to local "
+ objectType + " " + obj.libraryKey);

saveOptions.skipData = true;
// If local object is different but we ignored the changes
// (e.g., ISBN hyphenation), save as unsynced. Since we're skipping
// data, the local version won't be overwritten.
if (result.localChanged) {
saveOptions.saveAsUnsynced = true;
}
let saveResults = yield this._saveObjectFromJSON(
obj,
jsonObject,
{
skipData: true,
notifierQueue,
// Save as unsynced
saveAsChanged: !!result.localChanged
}
saveOptions
);
results.push(saveResults);
if (!saveResults.processed) {
Expand Down Expand Up @@ -902,11 +902,6 @@ Zotero.Sync.Data.Local = {
jsonDataLocal[x] = jsonData[x];
})
jsonObject.data = jsonDataLocal;

// Save as unsynced
if (results.localChanged) {
saveOptions.saveAsChanged = true;
}
}
}
// Object doesn't exist locally
Expand Down Expand Up @@ -1190,19 +1185,26 @@ Zotero.Sync.Data.Local = {
let notifierQueues = [];
try {
for (let i = 0; i < mergeData.length; i++) {
// Batch notifier updates
// Batch notifier updates, despite multiple transactions
if (notifierQueues.length == batchSize) {
yield Zotero.Notifier.commit(notifierQueues);
notifierQueues = [];
}
let notifierQueue = new Zotero.Notifier.Queue;

let json = mergeData[i];
let json = mergeData[i].data;

let saveOptions = {};
Object.assign(saveOptions, options);
// Tell _saveObjectFromJSON() to save as unsynced
saveOptions.saveAsChanged = true;
// If choosing local object, save as unsynced with remote version (or 0 if remote is
// deleted) and remote object in cache, to simulate a save and edit
if (mergeData[i].selected == 'left') {
json.version = conflicts[i].right.version || 0;
saveOptions.saveAsUnsynced = true;
if (conflicts[i].right.version) {
saveOptions.cacheObject = conflicts[i].right;
}
}
saveOptions.notifierQueue = notifierQueue;

// Errors have to be thrown in order to roll back the transaction, so catch
Expand Down Expand Up @@ -1259,9 +1261,7 @@ Zotero.Sync.Data.Local = {
saveOptions.skipCache = true;
}

let saveResults = yield this._saveObjectFromJSON(
obj, json, saveOptions
);
let saveResults = yield this._saveObjectFromJSON(obj, json, saveOptions);
results.push(saveResults);
if (!saveResults.processed) {
throw saveResults.error;
Expand Down Expand Up @@ -1360,7 +1360,7 @@ Zotero.Sync.Data.Local = {
yield this._checkAttachmentForDownload(obj, json.data.mtime, options.isNewObject);
}
obj.version = json.data.version;
if (!options.saveAsChanged) {
if (!options.saveAsUnsynced) {
obj.synced = true;
}
yield obj.save({
Expand All @@ -1374,13 +1374,17 @@ Zotero.Sync.Data.Local = {
return;
}
});
yield this.saveCacheObject(obj.objectType, obj.libraryID, json.data);
results.processed = true;

let cacheJSON = options.cacheObject ? options.cacheObject : json.data;
yield this.saveCacheObject(obj.objectType, obj.libraryID, cacheJSON);
// Delete older versions of the object in the cache
yield this.deleteCacheObjectVersions(
obj.objectType, obj.libraryID, json.key, null, json.version - 1
obj.objectType,
obj.libraryID,
json.key,
null,
cacheJSON.version - 1
);
results.processed = true;

// Delete from sync queue
yield this._removeObjectFromSyncQueue(obj.objectType, obj.libraryID, json.key);
Expand Down Expand Up @@ -1519,7 +1523,7 @@ Zotero.Sync.Data.Local = {

return {
changes: changeset2,
conflicts: conflicts
conflicts
};
},

Expand Down

0 comments on commit f0770fa

Please sign in to comment.