Mercurial > public > mercurial-scm > hg
comparison hgext/fastannotate/protocol.py @ 39715:d8a7690ccc74
fastannotate: process files as they arrive
peer.commandexecutor()'s context manager waits for all responses to
arrive in its __exit__() method. We want to process the results as
they arrive, so we should do that inside the context manager
scope. Note that the futures' result() methods have been replaced to
make sure that the command executor's sendcommands() method is called
when the first future's result is requested, so we don't need to do
that.
A minor side-effect is that we can no longer easily tell when the
server has started sending us responses, so that long statement was
lost.
Differential Revision: https://phab.mercurial-scm.org/D4666
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Wed, 19 Sep 2018 17:34:36 -0700 |
parents | b220851999b5 |
children | e40b7a504b1d |
comparison
equal
deleted
inserted
replaced
39714:491fc3f4be67 | 39715:d8a7690ccc74 |
---|---|
161 for p in paths: | 161 for p in paths: |
162 results.append(batcher.callcommand( | 162 results.append(batcher.callcommand( |
163 'getannotate', | 163 'getannotate', |
164 {'path': p, 'lastnode':lastnodemap.get(p)})) | 164 {'path': p, 'lastnode':lastnodemap.get(p)})) |
165 | 165 |
166 ui.debug('fastannotate: server returned\n') | 166 for result in results: |
167 for result in results: | 167 r = result.result() |
168 r = result.result() | 168 # TODO: pconvert these paths on the server? |
169 # TODO: pconvert these paths on the server? | 169 r = {util.pconvert(p): v for p, v in r.iteritems()} |
170 r = {util.pconvert(p): v for p, v in r.iteritems()} | 170 for path in sorted(r): |
171 for path in sorted(r): | 171 # ignore malicious paths |
172 # ignore malicious paths | 172 if (not path.startswith('fastannotate/') |
173 if not path.startswith('fastannotate/') or '/../' in (path + '/'): | 173 or '/../' in (path + '/')): |
174 ui.debug('fastannotate: ignored malicious path %s\n' % path) | 174 ui.debug('fastannotate: ignored malicious path %s\n' % path) |
175 continue | 175 continue |
176 content = r[path] | 176 content = r[path] |
177 if ui.debugflag: | 177 if ui.debugflag: |
178 ui.debug('fastannotate: writing %d bytes to %s\n' | 178 ui.debug('fastannotate: writing %d bytes to %s\n' |
179 % (len(content), path)) | 179 % (len(content), path)) |
180 repo.vfs.makedirs(os.path.dirname(path)) | 180 repo.vfs.makedirs(os.path.dirname(path)) |
181 with repo.vfs(path, 'wb') as f: | 181 with repo.vfs(path, 'wb') as f: |
182 f.write(content) | 182 f.write(content) |
183 | 183 |
184 def _filterfetchpaths(repo, paths): | 184 def _filterfetchpaths(repo, paths): |
185 """return a subset of paths whose history is long and need to fetch linelog | 185 """return a subset of paths whose history is long and need to fetch linelog |
186 from the server. works with remotefilelog and non-remotefilelog repos. | 186 from the server. works with remotefilelog and non-remotefilelog repos. |
187 """ | 187 """ |