Mercurial > hg > mercurial-source
changeset 23853:9d25bb84cf6c
largefiles: make linear update set unsure largefiles normal if unchanged
'hg update' would hash all 'unsure' largefiles before performing the merge. It
would update the standins but not detect the very common case where the
largefile never had been changed by the user but just had been marked with an
invalid dirstate mtime to make sure any changes done by the user in the same
second would be detected. The largefile would remain in that state and would
have to be hashed again next time even though it still not had been changed.
Sad trombone.
Instead, for largefiles listed as 'unsure' or 'modified', after updating the
standin with the actual hash, mark the largefile as normal if it turns out to
not be modified relative to the revision in the parent revision. That will
prevent it from being hashed again next time.
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Fri, 09 Jan 2015 18:38:02 +0100 |
parents | ddc17eaf0f1b |
children | 91dbb98b3513 |
files | hgext/largefiles/overrides.py tests/test-largefiles-update.t |
diffstat | 2 files changed, 47 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -1295,8 +1295,21 @@ unsure, s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False, False, False) - for lfile in unsure + s.modified + s.added: + pctx = repo['.'] + for lfile in unsure + s.modified: + lfileabs = repo.wvfs.join(lfile) + if not os.path.exists(lfileabs): + continue + lfhash = lfutil.hashrepofile(repo, lfile) + standin = lfutil.standin(lfile) + lfutil.writestandin(repo, standin, lfhash, + lfutil.getexecutable(lfileabs)) + if (standin in pctx and + lfhash == lfutil.readstandin(repo, lfile, '.')): + lfdirstate.normal(lfile) + for lfile in s.added: lfutil.updatestandin(repo, lfutil.standin(lfile)) + lfdirstate.write() if linearmerge: # Only call updatelfiles on the standins that have changed
--- a/tests/test-largefiles-update.t +++ b/tests/test-largefiles-update.t @@ -25,6 +25,39 @@ $ hg commit -m '#2' created new head +Test that update also updates the lfdirstate of 'unsure' largefiles after +hashing them: + +The previous operations will usually have left us with largefiles with a mtime +within the same second as the dirstate was written. +The lfdirstate entries will thus have been written with an invalidated/unset +mtime to make sure further changes within the same second is detected. +We will however occasionally be "lucky" and get a tick between writing +largefiles and writing dirstate so we get valid lfdirstate timestamps. The +following verification is thus disabled but can be verified manually. + +#if false + $ hg debugdirstate --large --nodate + n 644 7 unset large1 + n 644 13 unset large2 +#endif + +Wait to make sure we get a tick so the mtime of the largefiles become valid. + + $ sleep 1 + +A linear merge will update standins before performing the actual merge. It will +do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and +update the corresponding standins. +Verify that it actually marks the clean files as clean in lfdirstate so +we don't have to hash them again next time we update. + + $ hg up + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg debugdirstate --large --nodate + n 644 7 set large1 + n 644 13 set large2 + Test that lfdirstate keeps track of last modification of largefiles and prevents unnecessary hashing of content - also after linear/noop update