Mercurial > hg-stable
diff hgext/largefiles/overrides.py @ 30190:56b930238036 stable
largefiles: more safe handling of interruptions while updating modifications
Largefiles are fragile with the design where dirstate and lfdirstate must be
kept in sync.
To be less fragile, mark all clean largefiles as unsure ("normallookup") before
updating standins. After standins have been updated and we know exactly which
largefile standins actually was changed, mark the unchanged largefiles back to
clean ("normal").
This will make the failure mode more safe. If interrupted, the next command
will continue to perform extra hashing of all largefiles. That will do that all
largefiles that are out of sync with their standin will be marked dirty and
they will show up in status and can be cleaned with update --clean.
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Sun, 16 Oct 2016 02:29:45 +0200 |
parents | e5c91dc909f7 |
children | 438173c41587 |
line wrap: on
line diff
--- a/hgext/largefiles/overrides.py Sun Oct 16 02:26:38 2016 +0200 +++ b/hgext/largefiles/overrides.py Sun Oct 16 02:29:45 2016 +0200 @@ -1390,7 +1390,8 @@ lfdirstate = lfutil.openlfdirstate(repo.ui, repo) unsure, s = lfdirstate.status(matchmod.always(repo.root, repo.getcwd()), - [], False, False, False) + [], False, True, False) + oldclean = set(s.clean) pctx = repo['.'] for lfile in unsure + s.modified: lfileabs = repo.wvfs.join(lfile) @@ -1402,9 +1403,13 @@ lfutil.getexecutable(lfileabs)) if (standin in pctx and lfhash == lfutil.readstandin(repo, lfile, '.')): - lfdirstate.normal(lfile) + oldclean.add(lfile) for lfile in s.added: lfutil.updatestandin(repo, lfutil.standin(lfile)) + # mark all clean largefiles as dirty, just in case the update gets + # interrupted before largefiles and lfdirstate are synchronized + for lfile in oldclean: + lfdirstate.normallookup(lfile) lfdirstate.write() oldstandins = lfutil.getstandinsstate(repo) @@ -1413,6 +1418,13 @@ newstandins = lfutil.getstandinsstate(repo) filelist = lfutil.getlfilestoupdate(oldstandins, newstandins) + + # to avoid leaving all largefiles as dirty and thus rehash them, mark + # all the ones that didn't change as clean + for lfile in oldclean.difference(filelist): + lfdirstate.normal(lfile) + lfdirstate.write() + if branchmerge or force or partial: filelist.extend(s.deleted + s.removed)