821 dst.setconfig('web', 'cacerts', v, 'copied') |
821 dst.setconfig('web', 'cacerts', v, 'copied') |
822 elif v: |
822 elif v: |
823 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied') |
823 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied') |
824 |
824 |
825 return dst |
825 return dst |
|
826 |
|
827 # Files of interest |
|
828 # Used to check if the repository has changed looking at mtime and size of |
|
829 # theses files. |
|
830 foi = [('spath', '00changelog.i'), |
|
831 ('spath', 'phaseroots'), # ! phase can change content at the same size |
|
832 ('spath', 'obsstore'), |
|
833 ('path', 'bookmarks'), # ! bookmark can change content at the same size |
|
834 ] |
|
835 |
|
836 class cachedlocalrepo(object): |
|
837 """Holds a localrepository that can be cached and reused.""" |
|
838 |
|
839 def __init__(self, repo): |
|
840 """Create a new cached repo from an existing repo. |
|
841 |
|
842 We assume the passed in repo was recently created. If the |
|
843 repo has changed between when it was created and when it was |
|
844 turned into a cache, it may not refresh properly. |
|
845 """ |
|
846 assert isinstance(repo, localrepo.localrepository) |
|
847 self._repo = repo |
|
848 self._state, self.mtime = self._repostate() |
|
849 |
|
850 def fetch(self): |
|
851 """Refresh (if necessary) and return a repository. |
|
852 |
|
853 If the cached instance is out of date, it will be recreated |
|
854 automatically and returned. |
|
855 |
|
856 Returns a tuple of the repo and a boolean indicating whether a new |
|
857 repo instance was created. |
|
858 """ |
|
859 # We compare the mtimes and sizes of some well-known files to |
|
860 # determine if the repo changed. This is not precise, as mtimes |
|
861 # are susceptible to clock skew and imprecise filesystems and |
|
862 # file content can change while maintaining the same size. |
|
863 |
|
864 state, mtime = self._repostate() |
|
865 if state == self._state: |
|
866 return self._repo, False |
|
867 |
|
868 self._repo = repository(self._repo.baseui, self._repo.url()) |
|
869 self._state = state |
|
870 self.mtime = mtime |
|
871 |
|
872 return self._repo, True |
|
873 |
|
874 def _repostate(self): |
|
875 state = [] |
|
876 maxmtime = -1 |
|
877 for attr, fname in foi: |
|
878 prefix = getattr(self._repo, attr) |
|
879 p = os.path.join(prefix, fname) |
|
880 try: |
|
881 st = os.stat(p) |
|
882 except OSError: |
|
883 st = os.stat(prefix) |
|
884 state.append((st.st_mtime, st.st_size)) |
|
885 maxmtime = max(maxmtime, st.st_mtime) |
|
886 |
|
887 return tuple(state), maxmtime |
|
888 |
|
889 def copy(self): |
|
890 """Obtain a copy of this class instance.""" |
|
891 c = cachedlocalrepo(self._repo) |
|
892 c._state = self._state |
|
893 c.mtime = self.mtime |
|
894 return c |