Example #1
0
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, [], [], [], [])
Example #2
0
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, [], [], [], [])
Example #3
0
 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)
Example #4
0
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)
Example #5
0
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)))
Example #6
0
 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)
Example #7
0
    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)))