def _adjuststatus(status, ctx1, ctx2): """Adjusts the status result to remove item that don't differ between ctx1 and ctx2 `status` is the memctx status for a reparented mirror of ctx2. `ctx1` is the predecessor to `ctx2`. So this function adjusts status to remove items that didn't change between the predecessor and the successor, and adds items that existed in the predecessor but not the successor. """ newmodified = [] newadded = [] newremoved = list(status.removed) for oldpaths, newpaths in [ (status.modified, newmodified), (status.added, newadded), ]: for path in oldpaths: # No real changes? if path in ctx1 and path in ctx2: f1 = ctx1[path] f2 = ctx2[path] if f1.flags() == f2.flags() and not f1.cmp(f2): continue newpaths.append(path) for oldpath in ctx1.files(): if oldpath not in status.removed and oldpath not in ctx2: newremoved.append(oldpath) return scmutil.status(newmodified, newadded, newremoved, [], [], [], [])
def _status(ctx1, ctx2): """Similar to ctx1.status(ctx2) but remove false positive modifies. The false positive might happen if a file in a "commitablectx" changes back to match its p1 content. Context like `memctx` currently does not read file content in its `status` calculation. This might belong to ctx.status(). However, the performance penalty might be undesirable. """ status = ctx1.status(ctx2) newmodified = [] newadded = [] for oldpaths, newpaths in [ (status.modified, newmodified), (status.added, newadded), ]: for path in oldpaths: # No real changes? if path in ctx1 and path in ctx2: f1 = ctx1[path] f2 = ctx2[path] if f1.flags() == f2.flags() and not f1.cmp(f2): continue newpaths.append(path) return scmutil.status(newmodified, newadded, status.removed, [], [], [], [])
def deserialize(cls, string): ll = super(buildstatusserializer, cls).deserialize(string) ls = [] for l in ll: ls.append([ pycompat.decodeutf8(base64.b64decode(pycompat.encodeutf8(f))) for f in l ]) return status(*ls)
def overridestatus( orig, self, node1=".", node2=None, match=None, ignored=False, clean=False, unknown=False, ): listignored = ignored listclean = clean listunknown = unknown def _cmpsets(l1, l2): try: if "FSMONITOR_LOG_FILE" in encoding.environ: fn = encoding.environ["FSMONITOR_LOG_FILE"] f = open(fn, "wb") else: fn = "fsmonitorfail.log" f = self.opener(fn, "wb") except (IOError, OSError): self.ui.warn(_("warning: unable to write to %s\n") % fn) return try: for i, (s1, s2) in enumerate(zip(l1, l2)): if set(s1) != set(s2): f.write("sets at position %d are unequal\n" % i) f.write("watchman returned: %s\n" % s1) f.write("stat returned: %s\n" % s2) finally: f.close() if isinstance(node1, context.changectx): ctx1 = node1 else: ctx1 = self[node1] if isinstance(node2, context.changectx): ctx2 = node2 else: ctx2 = self[node2] working = ctx2.rev() is None parentworking = working and ctx1 == self["."] match = match or matchmod.always(self.root, self.getcwd()) # Maybe we can use this opportunity to update Watchman's state. # Mercurial uses workingcommitctx and/or memctx to represent the part of # the workingctx that is to be committed. So don't update the state in # that case. # HG_PENDING is set in the environment when the dirstate is being updated # in the middle of a transaction; we must not update our state in that # case, or we risk forgetting about changes in the working copy. updatestate = (parentworking and match.always() and not isinstance( ctx2, (context.workingcommitctx, context.overlayworkingctx, context.memctx)) and "HG_PENDING" not in encoding.environ) try: if self._fsmonitorstate.walk_on_invalidate: # Use a short timeout to query the current clock. If that # takes too long then we assume that the service will be slow # to answer our query. # walk_on_invalidate indicates that we prefer to walk the # tree ourselves because we can ignore portions that Watchman # cannot and we tend to be faster in the warmer buffer cache # cases. self._watchmanclient.settimeout(0.1) else: # Give Watchman more time to potentially complete its walk # and return the initial clock. In this mode we assume that # the filesystem will be slower than parsing a potentially # very large Watchman result set. self._watchmanclient.settimeout(self._fsmonitorstate.timeout + 0.1) startclock = self._watchmanclient.getcurrentclock() except Exception as ex: self._watchmanclient.clearconnection() _handleunavailable(self.ui, self._fsmonitorstate, ex) # boo, Watchman failed. if self.ui.configbool("fsmonitor", "fallback-on-watchman-exception"): return orig(node1, node2, match, listignored, listclean, listunknown) else: raise ex if updatestate: # We need info about unknown files. This may make things slower the # first time, but whatever. stateunknown = True else: stateunknown = listunknown if updatestate: if "treestate" in self.requirements: # No need to invalidate fsmonitor state. # state.set needs to run before dirstate write, since it changes # dirstate (treestate). self.addpostdsstatus(poststatustreestate, afterdirstatewrite=False) else: # Invalidate fsmonitor.state if dirstate changes. This avoids the # following issue: # 1. pid 11 writes dirstate # 2. pid 22 reads dirstate and inconsistent fsmonitor.state # 3. pid 22 calculates a wrong state # 4. pid 11 writes fsmonitor.state # Because before 1, # 0. pid 11 invalidates fsmonitor.state # will happen. # # To avoid race conditions when reading without a lock, do things # in this order: # 1. Invalidate fsmonitor state # 2. Write dirstate # 3. Write fsmonitor state psbefore = lambda *args, **kwds: self._fsmonitorstate.invalidate( reason="dirstate_change") self.addpostdsstatus(psbefore, afterdirstatewrite=False) psafter = poststatus(startclock) self.addpostdsstatus(psafter, afterdirstatewrite=True) r = orig(node1, node2, match, listignored, listclean, stateunknown) modified, added, removed, deleted, unknown, ignored, clean = r if not listunknown: unknown = [] # don't do paranoid checks if we're not going to query Watchman anyway full = listclean or match.traversedir is not None if self._fsmonitorstate.mode == "paranoid" and not full: # run status again and fall back to the old walk this time self.dirstate._fsmonitordisable = True # shut the UI up quiet = self.ui.quiet self.ui.quiet = True fout, ferr = self.ui.fout, self.ui.ferr self.ui.fout = self.ui.ferr = open(os.devnull, "wb") try: rv2 = orig(node1, node2, match, listignored, listclean, listunknown) finally: self.dirstate._fsmonitordisable = False self.ui.quiet = quiet self.ui.fout, self.ui.ferr = fout, ferr # clean isn't tested since it's set to True above _cmpsets([modified, added, removed, deleted, unknown, ignored, clean], rv2) modified, added, removed, deleted, unknown, ignored, clean = rv2 return scmutil.status(modified, added, removed, deleted, unknown, ignored, clean)
print('=== with "pattern match":') print(actx1.status(other=wctx, match=scmutil.matchfiles(repo, ["bar-m", "foo"]))) print("wctx._status=%s" % (str(wctx._status))) print(actx2.status(other=wctx, match=scmutil.matchfiles(repo, ["bar-m", "foo"]))) print("wctx._status=%s" % (str(wctx._status))) print('=== with "always match" and "listclean=True":') print(actx1.status(other=wctx, listclean=True)) print("wctx._status=%s" % (str(wctx._status))) print(actx2.status(other=wctx, listclean=True)) print("wctx._status=%s" % (str(wctx._status))) print("== checking workingcommitctx.status:") wcctx = context.workingcommitctx( repo, scmutil.status(["bar-m"], ["bar-a"], [], [], [], [], []), text="", date="0 0" ) print("wcctx._status=%s" % (str(wcctx._status))) print('=== with "always match":') print(actx1.status(other=wcctx)) print("wcctx._status=%s" % (str(wcctx._status))) print(actx2.status(other=wcctx)) print("wcctx._status=%s" % (str(wcctx._status))) print('=== with "always match" and "listclean=True":') print(actx1.status(other=wcctx, listclean=True)) print("wcctx._status=%s" % (str(wcctx._status))) print(actx2.status(other=wcctx, listclean=True)) print("wcctx._status=%s" % (str(wcctx._status)))
def deserialize(cls, string): ll = super(buildstatusserializer, cls).deserialize(string) ls = [] for l in ll: ls.append([f.decode("base64") for f in l]) return status(*ls)
actx1.status(other=wctx, match=scmutil.matchfiles(repo, ["bar-m", "foo"]))) print("wctx._status=%s" % (str(wctx._status))) print( actx2.status(other=wctx, match=scmutil.matchfiles(repo, ["bar-m", "foo"]))) print("wctx._status=%s" % (str(wctx._status))) print('=== with "always match" and "listclean=True":') print(actx1.status(other=wctx, listclean=True)) print("wctx._status=%s" % (str(wctx._status))) print(actx2.status(other=wctx, listclean=True)) print("wctx._status=%s" % (str(wctx._status))) print("== checking workingcommitctx.status:") wcctx = context.workingcommitctx(repo, scmutil.status(["bar-m"], ["bar-a"], [], [], [], [], []), text="", date="0 0") print("wcctx._status=%s" % (str(wcctx._status))) print('=== with "always match":') print(actx1.status(other=wcctx)) print("wcctx._status=%s" % (str(wcctx._status))) print(actx2.status(other=wcctx)) print("wcctx._status=%s" % (str(wcctx._status))) print('=== with "always match" and "listclean=True":') print(actx1.status(other=wcctx, listclean=True)) print("wcctx._status=%s" % (str(wcctx._status))) print(actx2.status(other=wcctx, listclean=True)) print("wcctx._status=%s" % (str(wcctx._status)))