comparison hgext/largefiles/lfcommands.py @ 35168:b175e54c1103 stable

largefiles: pay attention to dropped standin files when updating largefiles Previously, the largefile for a dropped standin would be deleted here, and then restored from the cache. This had the effect of clobbering uncommitted changes if a revert caused the file to be forgotten, which is not what happens with a normal file. Now the removal and update is skipped for dropped largefiles, and the corresponding standin is deleted from disk. This was noticed when working on issue5738 because the forgotten standin files were left behind, and that changes the behavior of the next rename to that directory. My first attempt was to cleanup the standins before calling this. That failed, because this function deletes the largefile if the corresponding standin is missing. This function is called by the revert command, merge (and therefore update), and patch, via the scmutil.marktouched() override. So it should be pretty narrow in scope. I didn't mark issue5738 as fixed because the move related issues can still happen if the main tree and the .hglf subtree get out of sync somehow. I don't see an easy fix for that, but that should be an edge case. If whoever queues this thinks it is good enough to close out the bug and can cram it into the summary, go for it.
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 12 Nov 2017 23:45:14 -0500
parents 3f3c6d12095d
children aef2b98d9352
comparison
equal deleted inserted replaced
35167:9fb2b0b41bec 35168:b175e54c1103
453 if filelist is not None: 453 if filelist is not None:
454 filelist = set(filelist) 454 filelist = set(filelist)
455 lfiles = [f for f in lfiles if f in filelist] 455 lfiles = [f for f in lfiles if f in filelist]
456 456
457 update = {} 457 update = {}
458 dropped = set()
458 updated, removed = 0, 0 459 updated, removed = 0, 0
459 wvfs = repo.wvfs 460 wvfs = repo.wvfs
460 wctx = repo[None] 461 wctx = repo[None]
461 for lfile in lfiles: 462 for lfile in lfiles:
462 rellfile = lfile 463 rellfile = lfile
474 wvfs.join(rellfileorig)) 475 wvfs.join(rellfileorig))
475 wvfs.unlinkpath(relstandinorig) 476 wvfs.unlinkpath(relstandinorig)
476 expecthash = lfutil.readasstandin(wctx[relstandin]) 477 expecthash = lfutil.readasstandin(wctx[relstandin])
477 if expecthash != '': 478 if expecthash != '':
478 if lfile not in wctx: # not switched to normal file 479 if lfile not in wctx: # not switched to normal file
479 wvfs.unlinkpath(rellfile, ignoremissing=True) 480 if repo.dirstate[relstandin] != '?':
481 wvfs.unlinkpath(rellfile, ignoremissing=True)
482 else:
483 dropped.add(rellfile)
484
480 # use normallookup() to allocate an entry in largefiles 485 # use normallookup() to allocate an entry in largefiles
481 # dirstate to prevent lfilesrepo.status() from reporting 486 # dirstate to prevent lfilesrepo.status() from reporting
482 # missing files as removed. 487 # missing files as removed.
483 lfdirstate.normallookup(lfile) 488 lfdirstate.normallookup(lfile)
484 update[lfile] = expecthash 489 update[lfile] = expecthash
494 499
495 # largefile processing might be slow and be interrupted - be prepared 500 # largefile processing might be slow and be interrupted - be prepared
496 lfdirstate.write() 501 lfdirstate.write()
497 502
498 if lfiles: 503 if lfiles:
504 lfiles = [f for f in lfiles if f not in dropped]
505
506 for f in dropped:
507 repo.wvfs.unlinkpath(lfutil.standin(f))
508
509 # This needs to happen for dropped files, otherwise they stay in
510 # the M state.
511 lfutil.synclfdirstate(repo, lfdirstate, f, normallookup)
512
499 statuswriter(_('getting changed largefiles\n')) 513 statuswriter(_('getting changed largefiles\n'))
500 cachelfiles(ui, repo, None, lfiles) 514 cachelfiles(ui, repo, None, lfiles)
501 515
502 for lfile in lfiles: 516 for lfile in lfiles:
503 update1 = 0 517 update1 = 0