--- a/mercurial/progress.py Wed Sep 27 14:30:58 2017 -0700
+++ b/mercurial/progress.py Wed Sep 27 15:14:59 2017 -0700
@@ -104,6 +104,8 @@
self.order = self.ui.configlist(
'progress', 'format',
default=['topic', 'bar', 'number', 'estimate'])
+ self.estimateinterval = self.ui.configwith(
+ float, 'progress', 'estimateinterval')
def show(self, now, topic, pos, item, unit, total):
if not shouldprint(self.ui):
@@ -238,6 +240,32 @@
else:
return False
+ def _calibrateestimate(self, topic, now, pos):
+ '''Adjust starttimes and startvals for topic so ETA works better
+
+ If progress is non-linear (ex. get much slower in the last minute),
+ it's more friendly to only use a recent time span for ETA and speed
+ calculation.
+
+ [======================================> ]
+ ^^^^^^^
+ estimateinterval, only use this for estimation
+ '''
+ interval = self.estimateinterval
+ if interval <= 0:
+ return
+ elapsed = now - self.starttimes[topic]
+ if elapsed > interval:
+ delta = pos - self.startvals[topic]
+ newdelta = delta * interval / elapsed
+ # If a stall happens temporarily, ETA could change dramatically
+ # frequently. This is to avoid such dramatical change and make ETA
+ # smoother.
+ if newdelta < 0.1:
+ return
+ self.startvals[topic] = pos - newdelta
+ self.starttimes[topic] = now - interval
+
def progress(self, topic, pos, item='', unit='', total=None):
now = time.time()
self._refreshlock.acquire()
@@ -268,6 +296,7 @@
self.topics.append(topic)
self.topicstates[topic] = pos, item, unit, total
self.curtopic = topic
+ self._calibrateestimate(topic, now, pos)
if now - self.lastprint >= self.refresh and self.topics:
if self._oktoprint(now):
self.lastprint = now