Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.1.1, 1.1.2, and 1.1.3

stable shellext: invent "peek" state for overlays

If a file was edited, saved and then the edit undone and saved again, the
overlay for that file was stuck at "modified" until the user manually
triggered an "Update icons" or caused a "hg status".

Fixed by inventing a new "peek" state ('P') which causes an update of
.hg/dirstate via TortoiseHgOverlayServer. A file X is considered to be in
peek state, if the size of X and its size in the dirstate are the same but
the mtimes are different. This requires a look into the file contents to
tell if the file really has changed or not.

Note that Thgstatus::update() is now called with path (instead of cur.hgroot)
so that shell notifications are done for the affected file.

Changeset 69ba8d0380eb

Parent be84c28c135b

by Adrian Buehlmann

Changes to 2 files · Browse files at 69ba8d0380eb Showing diff from parent be84c28c135b Diff from another changeset...

 
53
54
55
56
57
58
59
60
61
 
 
 
 
 
62
63
64
 
53
54
55
 
 
 
 
 
 
56
57
58
59
60
61
62
63
@@ -53,12 +53,11 @@
  switch (this->state)   {   case 'n': - if (this->mtime == (unsigned)stat.mtime - && this->size == (unsigned)stat.size - ) - return 'C'; - else - return 'M'; + if (this->size != (unsigned)stat.size) + return 'M'; // modified + if (this->mtime == (unsigned)stat.mtime) + return 'C'; // clean + return 'P'; // must peek into file contents   case 'm':   return 'M';   case 'r':
 
219
220
221
 
 
222
223
224
 
319
320
321
322
 
 
 
 
 
 
323
324
325
 
326
327
328
 
330
331
332
333
334
335
336
337
338
339
340
341
342
343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
 
 
345
346
 
 
 
 
 
 
 
347
 
 
348
349
350
 
219
220
221
222
223
224
225
226
 
321
322
323
 
324
325
326
327
328
329
330
331
 
332
333
334
335
 
337
338
339
 
 
 
 
 
 
 
 
 
 
 
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
@@ -219,6 +219,8 @@
  if (!outdated && last.path == path)   {   outStatus = last.status; + if (outStatus == 'P') + outStatus = 'M';   return 1;   }   @@ -319,10 +321,15 @@
    outStatus = e->status(stat);   - if (outStatus == 'M' && pdirsta) + if (unset) + goto exit; + + bool update = false; + + if (outStatus == 'M')   {   std::string relbase; - if (get_relpath(cur.hgroot, cur.basedir, relbase)) + if (pdirsta && get_relpath(cur.hgroot, cur.basedir, relbase))   {   TDEBUG_TRACE(dp << "relbase = '" << relbase << "'");   @@ -330,21 +337,35 @@
  TDEBUG_TRACE(dp << "basedir_status = " << basedir_status);     if (basedir_status != 'M') - { - if (unset) - { - TDEBUG_TRACE(dp << "omitting Thgstatus::update"); - } - else - { - TDEBUG_TRACE(dp << "calling Thgstatus::update"); - Thgstatus::update(cur.hgroot); - } - } + update = true; + } + } + else if (outStatus == 'P') + { + static unsigned lasttickcount; + + const unsigned tc = ::GetTickCount(); + const bool outdated = tc - lasttickcount > 6000; + + if (outdated) // protect against endless update loops + { + update = true; + lasttickcount = tc;   } + + TDEBUG_TRACE(dp << "outStatus is 'P'");   }   + if (update) + { + TDEBUG_TRACE(dp << "calling Thgstatus::update"); + Thgstatus::update(path); + } + + exit:   cur.status = outStatus; + if (outStatus == 'P') + outStatus = 'M';   cur.tickcount = ::GetTickCount();   last = cur;   return 1;