Mercurial > hg
changeset 19056:ac41bb76c737
largefiles: wlock in status before lfdirstate.write()
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Wed, 17 Apr 2013 03:41:11 +0200 |
parents | 0fc41f88f148 |
children | 3d265e0822d3 |
files | hgext/largefiles/reposetup.py |
diffstat | 1 files changed, 126 insertions(+), 107 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/largefiles/reposetup.py Tue Apr 16 19:31:59 2013 +0200 +++ b/hgext/largefiles/reposetup.py Wed Apr 17 03:41:11 2013 +0200 @@ -126,127 +126,146 @@ if match is None: match = match_.always(self.root, self.getcwd()) - # First check if there were files specified on the - # command line. If there were, and none of them were - # largefiles, we should just bail here and let super - # handle it -- thus gaining a big performance boost. - lfdirstate = lfutil.openlfdirstate(ui, self) - if match.files() and not match.anypats(): - for f in lfdirstate: - if match(f): - break - else: - return super(lfilesrepo, self).status(node1, node2, - match, listignored, listclean, - listunknown, listsubrepos) + wlock = None + try: + try: + # updating the dirstate is optional + # so we don't wait on the lock + wlock = self.wlock(False) + except error.LockError: + pass - # Create a copy of match that matches standins instead - # of largefiles. - def tostandins(files): - if not working: - return files - newfiles = [] - dirstate = self.dirstate - for f in files: - sf = lfutil.standin(f) - if sf in dirstate: - newfiles.append(sf) - elif sf in dirstate.dirs(): - # Directory entries could be regular or - # standin, check both - newfiles.extend((f, sf)) + # First check if there were files specified on the + # command line. If there were, and none of them were + # largefiles, we should just bail here and let super + # handle it -- thus gaining a big performance boost. + lfdirstate = lfutil.openlfdirstate(ui, self) + if match.files() and not match.anypats(): + for f in lfdirstate: + if match(f): + break else: - newfiles.append(f) - return newfiles - - m = copy.copy(match) - m._files = tostandins(m._files) + return super(lfilesrepo, self).status(node1, node2, + match, listignored, listclean, + listunknown, listsubrepos) - result = super(lfilesrepo, self).status(node1, node2, m, - ignored, clean, unknown, listsubrepos) - if working: + # Create a copy of match that matches standins instead + # of largefiles. + def tostandins(files): + if not working: + return files + newfiles = [] + dirstate = self.dirstate + for f in files: + sf = lfutil.standin(f) + if sf in dirstate: + newfiles.append(sf) + elif sf in dirstate.dirs(): + # Directory entries could be regular or + # standin, check both + newfiles.extend((f, sf)) + else: + newfiles.append(f) + return newfiles - def sfindirstate(f): - sf = lfutil.standin(f) - dirstate = self.dirstate - return sf in dirstate or sf in dirstate.dirs() + m = copy.copy(match) + m._files = tostandins(m._files) - match._files = [f for f in match._files - if sfindirstate(f)] - # Don't waste time getting the ignored and unknown - # files from lfdirstate - s = lfdirstate.status(match, [], False, - listclean, False) - (unsure, modified, added, removed, missing, _unknown, - _ignored, clean) = s - if parentworking: - for lfile in unsure: - standin = lfutil.standin(lfile) - if standin not in ctx1: - # from second parent - modified.append(lfile) - elif ctx1[standin].data().strip() \ - != lfutil.hashfile(self.wjoin(lfile)): - modified.append(lfile) - else: - clean.append(lfile) - lfdirstate.normal(lfile) - else: - tocheck = unsure + modified + added + clean - modified, added, clean = [], [], [] + result = super(lfilesrepo, self).status(node1, node2, m, + ignored, clean, unknown, listsubrepos) + if working: + + def sfindirstate(f): + sf = lfutil.standin(f) + dirstate = self.dirstate + return sf in dirstate or sf in dirstate.dirs() - for lfile in tocheck: - standin = lfutil.standin(lfile) - if inctx(standin, ctx1): - if ctx1[standin].data().strip() != \ - lfutil.hashfile(self.wjoin(lfile)): + match._files = [f for f in match._files + if sfindirstate(f)] + # Don't waste time getting the ignored and unknown + # files from lfdirstate + s = lfdirstate.status(match, [], False, + listclean, False) + (unsure, modified, added, removed, missing, _unknown, + _ignored, clean) = s + if parentworking: + for lfile in unsure: + standin = lfutil.standin(lfile) + if standin not in ctx1: + # from second parent + modified.append(lfile) + elif ctx1[standin].data().strip() \ + != lfutil.hashfile(self.wjoin(lfile)): modified.append(lfile) else: clean.append(lfile) - else: - added.append(lfile) + lfdirstate.normal(lfile) + else: + tocheck = unsure + modified + added + clean + modified, added, clean = [], [], [] - # Standins no longer found in lfdirstate has been removed - for standin in ctx1.manifest(): - if not lfutil.isstandin(standin): - continue - lfile = lfutil.splitstandin(standin) - if not match(lfile): - continue - if lfile not in lfdirstate: - removed.append(lfile) + for lfile in tocheck: + standin = lfutil.standin(lfile) + if inctx(standin, ctx1): + if ctx1[standin].data().strip() != \ + lfutil.hashfile(self.wjoin(lfile)): + modified.append(lfile) + else: + clean.append(lfile) + else: + added.append(lfile) - # Filter result lists - result = list(result) + # Standins no longer found in lfdirstate has been + # removed + for standin in ctx1.manifest(): + if not lfutil.isstandin(standin): + continue + lfile = lfutil.splitstandin(standin) + if not match(lfile): + continue + if lfile not in lfdirstate: + removed.append(lfile) + + # Filter result lists + result = list(result) - # Largefiles are not really removed when they're - # still in the normal dirstate. Likewise, normal - # files are not really removed if they are still in - # lfdirstate. This happens in merges where files - # change type. - removed = [f for f in removed if f not in self.dirstate] - result[2] = [f for f in result[2] if f not in lfdirstate] + # Largefiles are not really removed when they're + # still in the normal dirstate. Likewise, normal + # files are not really removed if they are still in + # lfdirstate. This happens in merges where files + # change type. + removed = [f for f in removed + if f not in self.dirstate] + result[2] = [f for f in result[2] + if f not in lfdirstate] - lfiles = set(lfdirstate._map) - # Unknown files - result[4] = set(result[4]).difference(lfiles) - # Ignored files - result[5] = set(result[5]).difference(lfiles) - # combine normal files and largefiles - normals = [[fn for fn in filelist - if not lfutil.isstandin(fn)] - for filelist in result] - lfiles = (modified, added, removed, missing, [], [], clean) - result = [sorted(list1 + list2) - for (list1, list2) in zip(normals, lfiles)] - else: - def toname(f): - if lfutil.isstandin(f): - return lfutil.splitstandin(f) - return f - result = [[toname(f) for f in items] for items in result] + lfiles = set(lfdirstate._map) + # Unknown files + result[4] = set(result[4]).difference(lfiles) + # Ignored files + result[5] = set(result[5]).difference(lfiles) + # combine normal files and largefiles + normals = [[fn for fn in filelist + if not lfutil.isstandin(fn)] + for filelist in result] + lfiles = (modified, added, removed, missing, [], [], + clean) + result = [sorted(list1 + list2) + for (list1, list2) in zip(normals, lfiles)] + else: + def toname(f): + if lfutil.isstandin(f): + return lfutil.splitstandin(f) + return f + result = [[toname(f) for f in items] + for items in result] - lfdirstate.write() + if wlock: + lfdirstate.write() + + finally: + if wlock: + wlock.release() if not listunknown: result[4] = []