OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sync/engine/process_commit_response_command.h" | 5 #include "sync/engine/process_commit_response_command.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "sync/engine/syncer_proto_util.h" | 14 #include "sync/engine/syncer_proto_util.h" |
15 #include "sync/engine/syncer_util.h" | 15 #include "sync/engine/syncer_util.h" |
16 #include "sync/engine/syncproto.h" | |
17 #include "sync/sessions/sync_session.h" | 16 #include "sync/sessions/sync_session.h" |
18 #include "sync/syncable/entry.h" | 17 #include "sync/syncable/entry.h" |
19 #include "sync/syncable/mutable_entry.h" | 18 #include "sync/syncable/mutable_entry.h" |
20 #include "sync/syncable/read_transaction.h" | 19 #include "sync/syncable/read_transaction.h" |
20 #include "sync/syncable/syncable_proto_util.h" | |
21 #include "sync/syncable/syncable_util.h" | 21 #include "sync/syncable/syncable_util.h" |
22 #include "sync/syncable/write_transaction.h" | 22 #include "sync/syncable/write_transaction.h" |
23 #include "sync/util/time.h" | 23 #include "sync/util/time.h" |
24 | 24 |
25 using std::set; | 25 using std::set; |
26 using std::string; | 26 using std::string; |
27 using std::vector; | 27 using std::vector; |
28 using sync_pb::CommitResponse; | |
28 | 29 |
29 namespace syncer { | 30 namespace syncer { |
30 | 31 |
31 using sessions::OrderedCommitSet; | 32 using sessions::OrderedCommitSet; |
32 using sessions::StatusController; | 33 using sessions::StatusController; |
33 using sessions::SyncSession; | 34 using sessions::SyncSession; |
34 using sessions::ConflictProgress; | 35 using sessions::ConflictProgress; |
35 using syncable::WriteTransaction; | 36 using syncable::WriteTransaction; |
36 using syncable::MutableEntry; | 37 using syncable::MutableEntry; |
37 using syncable::Entry; | 38 using syncable::Entry; |
38 using syncable::BASE_VERSION; | 39 using syncable::BASE_VERSION; |
39 using syncable::GET_BY_ID; | 40 using syncable::GET_BY_ID; |
40 using syncable::ID; | 41 using syncable::ID; |
41 using syncable::IS_DEL; | 42 using syncable::IS_DEL; |
42 using syncable::IS_DIR; | 43 using syncable::IS_DIR; |
43 using syncable::IS_UNAPPLIED_UPDATE; | 44 using syncable::IS_UNAPPLIED_UPDATE; |
44 using syncable::IS_UNSYNCED; | 45 using syncable::IS_UNSYNCED; |
45 using syncable::PARENT_ID; | 46 using syncable::PARENT_ID; |
46 using syncable::SERVER_IS_DEL; | 47 using syncable::SERVER_IS_DEL; |
47 using syncable::SERVER_PARENT_ID; | 48 using syncable::SERVER_PARENT_ID; |
48 using syncable::SERVER_POSITION_IN_PARENT; | 49 using syncable::SERVER_POSITION_IN_PARENT; |
49 using syncable::SERVER_VERSION; | 50 using syncable::SERVER_VERSION; |
50 using syncable::SYNCER; | 51 using syncable::SYNCER; |
51 using syncable::SYNCING; | 52 using syncable::SYNCING; |
52 | 53 |
53 ProcessCommitResponseCommand::ProcessCommitResponseCommand( | 54 ProcessCommitResponseCommand::ProcessCommitResponseCommand( |
54 const sessions::OrderedCommitSet& commit_set, | 55 const sessions::OrderedCommitSet& commit_set, |
55 const ClientToServerMessage& commit_message, | 56 const sync_pb::ClientToServerMessage& commit_message, |
56 const ClientToServerResponse& commit_response) | 57 const sync_pb::ClientToServerResponse& commit_response) |
57 : commit_set_(commit_set), | 58 : commit_set_(commit_set), |
58 commit_message_(commit_message), | 59 commit_message_(commit_message), |
59 commit_response_(commit_response) { | 60 commit_response_(commit_response) { |
60 } | 61 } |
61 | 62 |
62 ProcessCommitResponseCommand::~ProcessCommitResponseCommand() {} | 63 ProcessCommitResponseCommand::~ProcessCommitResponseCommand() {} |
63 | 64 |
64 std::set<ModelSafeGroup> ProcessCommitResponseCommand::GetGroupsToChange( | 65 std::set<ModelSafeGroup> ProcessCommitResponseCommand::GetGroupsToChange( |
65 const sessions::SyncSession& session) const { | 66 const sessions::SyncSession& session) const { |
66 std::set<ModelSafeGroup> groups_with_commits; | 67 std::set<ModelSafeGroup> groups_with_commits; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 // | 183 // |
183 // TODO: Remove this option when the CONFLICT return value is fully | 184 // TODO: Remove this option when the CONFLICT return value is fully |
184 // deprecated. | 185 // deprecated. |
185 return SERVER_RETURN_TRANSIENT_ERROR; | 186 return SERVER_RETURN_TRANSIENT_ERROR; |
186 } else { | 187 } else { |
187 LOG(FATAL) << "Inconsistent counts when processing commit response"; | 188 LOG(FATAL) << "Inconsistent counts when processing commit response"; |
188 return SYNCER_OK; | 189 return SYNCER_OK; |
189 } | 190 } |
190 } | 191 } |
191 | 192 |
192 void LogServerError(const CommitResponse_EntryResponse& res) { | 193 void LogServerError(const sync_pb::CommitResponse_EntryResponse& res) { |
193 if (res.has_error_message()) | 194 if (res.has_error_message()) |
194 LOG(WARNING) << " " << res.error_message(); | 195 LOG(WARNING) << " " << res.error_message(); |
195 else | 196 else |
196 LOG(WARNING) << " No detailed error message returned from server"; | 197 LOG(WARNING) << " No detailed error message returned from server"; |
197 } | 198 } |
198 | 199 |
199 CommitResponse::ResponseType | 200 CommitResponse::ResponseType |
200 ProcessCommitResponseCommand::ProcessSingleCommitResponse( | 201 ProcessCommitResponseCommand::ProcessSingleCommitResponse( |
201 syncable::WriteTransaction* trans, | 202 syncable::WriteTransaction* trans, |
202 const sync_pb::CommitResponse_EntryResponse& pb_server_entry, | 203 const sync_pb::CommitResponse_EntryResponse& pb_server_entry, |
203 const sync_pb::SyncEntity& commit_request_entry, | 204 const sync_pb::SyncEntity& commit_request_entry, |
204 const syncable::Id& pre_commit_id, | 205 const syncable::Id& pre_commit_id, |
205 set<syncable::Id>* deleted_folders) { | 206 set<syncable::Id>* deleted_folders) { |
206 | 207 |
207 const CommitResponse_EntryResponse& server_entry = | 208 const sync_pb::CommitResponse_EntryResponse& server_entry = |
208 *static_cast<const CommitResponse_EntryResponse*>(&pb_server_entry); | 209 *static_cast<const sync_pb::CommitResponse_EntryResponse*>( |
akalin
2012/07/11 01:42:22
static cast not needed anymore?
rlarocque
2012/07/11 19:22:16
Done.
| |
210 &pb_server_entry); | |
209 MutableEntry local_entry(trans, GET_BY_ID, pre_commit_id); | 211 MutableEntry local_entry(trans, GET_BY_ID, pre_commit_id); |
210 CHECK(local_entry.good()); | 212 CHECK(local_entry.good()); |
211 bool syncing_was_set = local_entry.Get(SYNCING); | 213 bool syncing_was_set = local_entry.Get(SYNCING); |
212 local_entry.Put(SYNCING, false); | 214 local_entry.Put(SYNCING, false); |
213 | 215 |
214 CommitResponse::ResponseType response = (CommitResponse::ResponseType) | 216 CommitResponse::ResponseType response = (CommitResponse::ResponseType) |
215 server_entry.response_type(); | 217 server_entry.response_type(); |
216 if (!CommitResponse::ResponseType_IsValid(response)) { | 218 if (!CommitResponse::ResponseType_IsValid(response)) { |
217 LOG(ERROR) << "Commit response has unknown response type! Possibly out " | 219 LOG(ERROR) << "Commit response has unknown response type! Possibly out " |
218 "of date client?"; | 220 "of date client?"; |
(...skipping 23 matching lines...) Expand all Loading... | |
242 } | 244 } |
243 if (!server_entry.has_id_string()) { | 245 if (!server_entry.has_id_string()) { |
244 LOG(ERROR) << "Commit response has no id"; | 246 LOG(ERROR) << "Commit response has no id"; |
245 return CommitResponse::INVALID_MESSAGE; | 247 return CommitResponse::INVALID_MESSAGE; |
246 } | 248 } |
247 | 249 |
248 // Implied by the IsValid call above, but here for clarity. | 250 // Implied by the IsValid call above, but here for clarity. |
249 DCHECK_EQ(CommitResponse::SUCCESS, response) << response; | 251 DCHECK_EQ(CommitResponse::SUCCESS, response) << response; |
250 // Check to see if we've been given the ID of an existing entry. If so treat | 252 // Check to see if we've been given the ID of an existing entry. If so treat |
251 // it as an error response and retry later. | 253 // it as an error response and retry later. |
252 if (pre_commit_id != server_entry.id()) { | 254 syncable::Id server_entry_id = SyncableIdFromProto(server_entry.id_string()); |
253 Entry e(trans, GET_BY_ID, server_entry.id()); | 255 if (pre_commit_id != server_entry_id) { |
256 Entry e(trans, GET_BY_ID, server_entry_id); | |
254 if (e.good()) { | 257 if (e.good()) { |
255 LOG(ERROR) << "Got duplicate id when commiting id: " << pre_commit_id << | 258 LOG(ERROR) << "Got duplicate id when commiting id: " << pre_commit_id << |
256 ". Treating as an error return"; | 259 ". Treating as an error return"; |
257 return CommitResponse::INVALID_MESSAGE; | 260 return CommitResponse::INVALID_MESSAGE; |
258 } | 261 } |
259 } | 262 } |
260 | 263 |
261 if (server_entry.version() == 0) { | 264 if (server_entry.version() == 0) { |
262 LOG(WARNING) << "Server returned a zero version on a commit response."; | 265 LOG(WARNING) << "Server returned a zero version on a commit response."; |
263 } | 266 } |
264 | 267 |
265 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry, | 268 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry, |
266 pre_commit_id, &local_entry, syncing_was_set, deleted_folders); | 269 pre_commit_id, &local_entry, syncing_was_set, deleted_folders); |
267 return response; | 270 return response; |
268 } | 271 } |
269 | 272 |
270 const string& ProcessCommitResponseCommand::GetResultingPostCommitName( | 273 const string& ProcessCommitResponseCommand::GetResultingPostCommitName( |
271 const sync_pb::SyncEntity& committed_entry, | 274 const sync_pb::SyncEntity& committed_entry, |
272 const CommitResponse_EntryResponse& entry_response) { | 275 const sync_pb::CommitResponse_EntryResponse& entry_response) { |
273 const string& response_name = | 276 const string& response_name = |
274 SyncerProtoUtil::NameFromCommitEntryResponse(entry_response); | 277 SyncerProtoUtil::NameFromCommitEntryResponse(entry_response); |
275 if (!response_name.empty()) | 278 if (!response_name.empty()) |
276 return response_name; | 279 return response_name; |
277 return SyncerProtoUtil::NameFromSyncEntity(committed_entry); | 280 return SyncerProtoUtil::NameFromSyncEntity(committed_entry); |
278 } | 281 } |
279 | 282 |
280 bool ProcessCommitResponseCommand::UpdateVersionAfterCommit( | 283 bool ProcessCommitResponseCommand::UpdateVersionAfterCommit( |
281 const sync_pb::SyncEntity& committed_entry, | 284 const sync_pb::SyncEntity& committed_entry, |
282 const CommitResponse_EntryResponse& entry_response, | 285 const sync_pb::CommitResponse_EntryResponse& entry_response, |
283 const syncable::Id& pre_commit_id, | 286 const syncable::Id& pre_commit_id, |
284 syncable::MutableEntry* local_entry) { | 287 syncable::MutableEntry* local_entry) { |
285 int64 old_version = local_entry->Get(BASE_VERSION); | 288 int64 old_version = local_entry->Get(BASE_VERSION); |
286 int64 new_version = entry_response.version(); | 289 int64 new_version = entry_response.version(); |
287 bool bad_commit_version = false; | 290 bool bad_commit_version = false; |
288 if (committed_entry.deleted() && | 291 if (committed_entry.deleted() && |
289 !local_entry->Get(syncable::UNIQUE_CLIENT_TAG).empty()) { | 292 !local_entry->Get(syncable::UNIQUE_CLIENT_TAG).empty()) { |
290 // If the item was deleted, and it's undeletable (uses the client tag), | 293 // If the item was deleted, and it's undeletable (uses the client tag), |
291 // change the version back to zero. We must set the version to zero so | 294 // change the version back to zero. We must set the version to zero so |
292 // that the server knows to re-create the item if it gets committed | 295 // that the server knows to re-create the item if it gets committed |
293 // later for undeletion. | 296 // later for undeletion. |
294 new_version = 0; | 297 new_version = 0; |
295 } else if (!pre_commit_id.ServerKnows()) { | 298 } else if (!pre_commit_id.ServerKnows()) { |
296 bad_commit_version = 0 == new_version; | 299 bad_commit_version = 0 == new_version; |
297 } else { | 300 } else { |
298 bad_commit_version = old_version > new_version; | 301 bad_commit_version = old_version > new_version; |
299 } | 302 } |
300 if (bad_commit_version) { | 303 if (bad_commit_version) { |
301 LOG(ERROR) << "Bad version in commit return for " << *local_entry | 304 LOG(ERROR) << "Bad version in commit return for " << *local_entry |
302 << " new_id:" << entry_response.id() << " new_version:" | 305 << " new_id:" << SyncableIdFromProto(entry_response.id_string()) |
303 << entry_response.version(); | 306 << " new_version:" << entry_response.version(); |
304 return false; | 307 return false; |
305 } | 308 } |
306 | 309 |
307 // Update the base version and server version. The base version must change | 310 // Update the base version and server version. The base version must change |
308 // here, even if syncing_was_set is false; that's because local changes were | 311 // here, even if syncing_was_set is false; that's because local changes were |
309 // on top of the successfully committed version. | 312 // on top of the successfully committed version. |
310 local_entry->Put(BASE_VERSION, new_version); | 313 local_entry->Put(BASE_VERSION, new_version); |
311 DVLOG(1) << "Commit is changing base version of " << local_entry->Get(ID) | 314 DVLOG(1) << "Commit is changing base version of " << local_entry->Get(ID) |
312 << " to: " << new_version; | 315 << " to: " << new_version; |
313 local_entry->Put(SERVER_VERSION, new_version); | 316 local_entry->Put(SERVER_VERSION, new_version); |
314 return true; | 317 return true; |
315 } | 318 } |
316 | 319 |
317 bool ProcessCommitResponseCommand::ChangeIdAfterCommit( | 320 bool ProcessCommitResponseCommand::ChangeIdAfterCommit( |
318 const CommitResponse_EntryResponse& entry_response, | 321 const sync_pb::CommitResponse_EntryResponse& entry_response, |
319 const syncable::Id& pre_commit_id, | 322 const syncable::Id& pre_commit_id, |
320 syncable::MutableEntry* local_entry) { | 323 syncable::MutableEntry* local_entry) { |
321 syncable::WriteTransaction* trans = local_entry->write_transaction(); | 324 syncable::WriteTransaction* trans = local_entry->write_transaction(); |
322 if (entry_response.id() != pre_commit_id) { | 325 syncable::Id entry_response_id = |
326 SyncableIdFromProto(entry_response.id_string()); | |
327 if (entry_response_id != pre_commit_id) { | |
323 if (pre_commit_id.ServerKnows()) { | 328 if (pre_commit_id.ServerKnows()) { |
324 // The server can sometimes generate a new ID on commit; for example, | 329 // The server can sometimes generate a new ID on commit; for example, |
325 // when committing an undeletion. | 330 // when committing an undeletion. |
326 DVLOG(1) << " ID changed while committing an old entry. " | 331 DVLOG(1) << " ID changed while committing an old entry. " |
327 << pre_commit_id << " became " << entry_response.id() << "."; | 332 << pre_commit_id << " became " << entry_response_id << "."; |
328 } | 333 } |
329 MutableEntry same_id(trans, GET_BY_ID, entry_response.id()); | 334 MutableEntry same_id(trans, GET_BY_ID, entry_response_id); |
330 // We should trap this before this function. | 335 // We should trap this before this function. |
331 if (same_id.good()) { | 336 if (same_id.good()) { |
332 LOG(ERROR) << "ID clash with id " << entry_response.id() | 337 LOG(ERROR) << "ID clash with id " << entry_response_id |
333 << " during commit " << same_id; | 338 << " during commit " << same_id; |
334 return false; | 339 return false; |
335 } | 340 } |
336 ChangeEntryIDAndUpdateChildren(trans, local_entry, entry_response.id()); | 341 ChangeEntryIDAndUpdateChildren(trans, local_entry, entry_response_id); |
337 DVLOG(1) << "Changing ID to " << entry_response.id(); | 342 DVLOG(1) << "Changing ID to " << entry_response_id; |
338 } | 343 } |
339 return true; | 344 return true; |
340 } | 345 } |
341 | 346 |
342 void ProcessCommitResponseCommand::UpdateServerFieldsAfterCommit( | 347 void ProcessCommitResponseCommand::UpdateServerFieldsAfterCommit( |
343 const sync_pb::SyncEntity& committed_entry, | 348 const sync_pb::SyncEntity& committed_entry, |
344 const CommitResponse_EntryResponse& entry_response, | 349 const sync_pb::CommitResponse_EntryResponse& entry_response, |
345 syncable::MutableEntry* local_entry) { | 350 syncable::MutableEntry* local_entry) { |
346 | 351 |
347 // We just committed an entry successfully, and now we want to make our view | 352 // We just committed an entry successfully, and now we want to make our view |
348 // of the server state consistent with the server state. We must be careful; | 353 // of the server state consistent with the server state. We must be careful; |
349 // |entry_response| and |committed_entry| have some identically named | 354 // |entry_response| and |committed_entry| have some identically named |
350 // fields. We only want to consider fields from |committed_entry| when there | 355 // fields. We only want to consider fields from |committed_entry| when there |
351 // is not an overriding field in the |entry_response|. We do not want to | 356 // is not an overriding field in the |entry_response|. We do not want to |
352 // update the server data from the local data in the entry -- it's possible | 357 // update the server data from the local data in the entry -- it's possible |
353 // that the local data changed during the commit, and even if not, the server | 358 // that the local data changed during the commit, and even if not, the server |
354 // has the last word on the values of several properties. | 359 // has the last word on the values of several properties. |
(...skipping 30 matching lines...) Expand all Loading... | |
385 if (local_entry->Get(IS_UNAPPLIED_UPDATE)) { | 390 if (local_entry->Get(IS_UNAPPLIED_UPDATE)) { |
386 // This shouldn't happen; an unapplied update shouldn't be committed, and | 391 // This shouldn't happen; an unapplied update shouldn't be committed, and |
387 // if it were, the commit should have failed. But if it does happen: we've | 392 // if it were, the commit should have failed. But if it does happen: we've |
388 // just overwritten the update info, so clear the flag. | 393 // just overwritten the update info, so clear the flag. |
389 local_entry->Put(IS_UNAPPLIED_UPDATE, false); | 394 local_entry->Put(IS_UNAPPLIED_UPDATE, false); |
390 } | 395 } |
391 } | 396 } |
392 | 397 |
393 void ProcessCommitResponseCommand::OverrideClientFieldsAfterCommit( | 398 void ProcessCommitResponseCommand::OverrideClientFieldsAfterCommit( |
394 const sync_pb::SyncEntity& committed_entry, | 399 const sync_pb::SyncEntity& committed_entry, |
395 const CommitResponse_EntryResponse& entry_response, | 400 const sync_pb::CommitResponse_EntryResponse& entry_response, |
396 syncable::MutableEntry* local_entry) { | 401 syncable::MutableEntry* local_entry) { |
397 if (committed_entry.deleted()) { | 402 if (committed_entry.deleted()) { |
398 // If an entry's been deleted, nothing else matters. | 403 // If an entry's been deleted, nothing else matters. |
399 DCHECK(local_entry->Get(IS_DEL)); | 404 DCHECK(local_entry->Get(IS_DEL)); |
400 return; | 405 return; |
401 } | 406 } |
402 | 407 |
403 // Update the name. | 408 // Update the name. |
404 const string& server_name = | 409 const string& server_name = |
405 GetResultingPostCommitName(committed_entry, entry_response); | 410 GetResultingPostCommitName(committed_entry, entry_response); |
(...skipping 19 matching lines...) Expand all Loading... | |
425 local_entry->Get(PARENT_ID)); | 430 local_entry->Get(PARENT_ID)); |
426 if (!local_entry->PutPredecessor(new_prev)) { | 431 if (!local_entry->PutPredecessor(new_prev)) { |
427 // TODO(lipalani) : Propagate the error to caller. crbug.com/100444. | 432 // TODO(lipalani) : Propagate the error to caller. crbug.com/100444. |
428 NOTREACHED(); | 433 NOTREACHED(); |
429 } | 434 } |
430 } | 435 } |
431 } | 436 } |
432 | 437 |
433 void ProcessCommitResponseCommand::ProcessSuccessfulCommitResponse( | 438 void ProcessCommitResponseCommand::ProcessSuccessfulCommitResponse( |
434 const sync_pb::SyncEntity& committed_entry, | 439 const sync_pb::SyncEntity& committed_entry, |
435 const CommitResponse_EntryResponse& entry_response, | 440 const sync_pb::CommitResponse_EntryResponse& entry_response, |
436 const syncable::Id& pre_commit_id, syncable::MutableEntry* local_entry, | 441 const syncable::Id& pre_commit_id, syncable::MutableEntry* local_entry, |
437 bool syncing_was_set, set<syncable::Id>* deleted_folders) { | 442 bool syncing_was_set, set<syncable::Id>* deleted_folders) { |
438 DCHECK(local_entry->Get(IS_UNSYNCED)); | 443 DCHECK(local_entry->Get(IS_UNSYNCED)); |
439 | 444 |
440 // Update SERVER_VERSION and BASE_VERSION. | 445 // Update SERVER_VERSION and BASE_VERSION. |
441 if (!UpdateVersionAfterCommit(committed_entry, entry_response, pre_commit_id, | 446 if (!UpdateVersionAfterCommit(committed_entry, entry_response, pre_commit_id, |
442 local_entry)) { | 447 local_entry)) { |
443 LOG(ERROR) << "Bad version in commit return for " << *local_entry | 448 LOG(ERROR) << "Bad version in commit return for " << *local_entry |
444 << " new_id:" << entry_response.id() << " new_version:" | 449 << " new_id:" << SyncableIdFromProto(entry_response.id_string()) |
445 << entry_response.version(); | 450 << " new_version:" << entry_response.version(); |
446 return; | 451 return; |
447 } | 452 } |
448 | 453 |
449 // If the server gave us a new ID, apply it. | 454 // If the server gave us a new ID, apply it. |
450 if (!ChangeIdAfterCommit(entry_response, pre_commit_id, local_entry)) { | 455 if (!ChangeIdAfterCommit(entry_response, pre_commit_id, local_entry)) { |
451 return; | 456 return; |
452 } | 457 } |
453 | 458 |
454 // Update our stored copy of the server state. | 459 // Update our stored copy of the server state. |
455 UpdateServerFieldsAfterCommit(committed_entry, entry_response, local_entry); | 460 UpdateServerFieldsAfterCommit(committed_entry, entry_response, local_entry); |
(...skipping 13 matching lines...) Expand all Loading... | |
469 // been recursively deleted. | 474 // been recursively deleted. |
470 // TODO(nick): Here, commit_message.deleted() would be more correct than | 475 // TODO(nick): Here, commit_message.deleted() would be more correct than |
471 // local_entry->Get(IS_DEL). For example, an item could be renamed, and then | 476 // local_entry->Get(IS_DEL). For example, an item could be renamed, and then |
472 // deleted during the commit of the rename. Unit test & fix. | 477 // deleted during the commit of the rename. Unit test & fix. |
473 if (local_entry->Get(IS_DIR) && local_entry->Get(IS_DEL)) { | 478 if (local_entry->Get(IS_DIR) && local_entry->Get(IS_DEL)) { |
474 deleted_folders->insert(local_entry->Get(ID)); | 479 deleted_folders->insert(local_entry->Get(ID)); |
475 } | 480 } |
476 } | 481 } |
477 | 482 |
478 } // namespace syncer | 483 } // namespace syncer |
OLD | NEW |