Exemplo n.º 1
0
def patchcmds(ui, repo, pats, opts, subcommand):
    """subcommand that displays shelves"""
    if len(pats) == 0:
        shelved = listshelves(repo)
        if len(shelved) < 1:
            raise error.Abort(_("no shelves found"))
        pats = [util.split(shelved[0][1])[1]]

    for shelfname in pats:
        if not shelvedfile(repo, shelfname, patchextension).exists():
            raise error.Abort(_("cannot find shelf %s") % shelfname)

    listcmd(ui, repo, pats, opts)
Exemplo n.º 2
0
def listcmd(ui, repo, pats, opts):
    """subcommand that displays the list of shelves"""
    pats = set(pats)
    width = 80
    if not ui.plain():
        width = ui.termwidth()
    namelabel = "shelve.newest"
    ui.pager("shelve")
    for mtime, name in listshelves(repo):
        sname = util.split(name)[1]
        if pats and sname not in pats:
            continue
        ui.write(sname, label=namelabel)
        namelabel = "shelve.name"
        if ui.quiet:
            ui.write("\n")
            continue
        ui.write(" " * (16 - len(sname)))
        used = 16
        age = "(%s)" % templatefilters.age(util.makedate(mtime), abbrev=True)
        ui.write(age, label="shelve.age")
        ui.write(" " * (12 - len(age)))
        used += 12
        with open(name + "." + patchextension, "rb") as fp:
            while True:
                line = fp.readline()
                if not line:
                    break
                if not line.startswith(b"#"):
                    desc = pycompat.decodeutf8(line.rstrip())
                    if ui.formatted:
                        desc = util.ellipsis(desc, width - used)
                    ui.write(desc)
                    break
            ui.write("\n")
            if not (opts["patch"] or opts["stat"]):
                continue
            difflines = fp.readlines()
            if opts["patch"]:
                for chunk, label in patch.difflabel(iter, difflines):
                    ui.writebytes(chunk, label=label)
            if opts["stat"]:
                for chunk, label in patch.diffstatui(difflines, width=width):
                    ui.write(chunk, label=label)
Exemplo n.º 3
0
def applytomirrors(repo, status, sourcepath, mirrors, action):
    """Applies the changes that are in the sourcepath to all the mirrors."""
    mirroredfiles = set()

    # Detect which mirror this file comes from
    sourcemirror = None
    for mirror in mirrors:
        if sourcepath.startswith(mirror):
            sourcemirror = mirror
            break
    if not sourcemirror:
        raise error.Abort(
            _("unable to detect source mirror of '%s'") % (sourcepath, ))

    relpath = sourcepath[len(sourcemirror):]

    # Apply the change to each mirror one by one
    allchanges = set(status.modified + status.removed + status.added)
    for mirror in mirrors:
        if mirror == sourcemirror:
            continue

        mirrorpath = mirror + relpath
        mirroredfiles.add(mirrorpath)
        if mirrorpath in allchanges:
            wctx = repo[None]
            if (sourcepath not in wctx and mirrorpath not in wctx
                    and sourcepath in status.removed
                    and mirrorpath in status.removed):
                if repo.ui.verbose:
                    repo.ui.status(
                        _("not mirroring remove of '%s' to '%s';"
                          " it is already removed\n") %
                        (sourcepath, mirrorpath))
                continue

            if wctx[sourcepath].data() == wctx[mirrorpath].data():
                if repo.ui.verbose:
                    repo.ui.status(
                        _("not mirroring '%s' to '%s'; it already "
                          "matches\n") % (sourcepath, mirrorpath))
                continue
            raise error.Abort(
                _("path '%s' needs to be mirrored to '%s', but "
                  "the target already has pending changes") %
                (sourcepath, mirrorpath))

        fullsource = repo.wjoin(sourcepath)
        fulltarget = repo.wjoin(mirrorpath)

        dirstate = repo.dirstate
        if action == "m" or action == "a":
            mirrorpathdir, unused = util.split(mirrorpath)
            util.makedirs(repo.wjoin(mirrorpathdir))

            util.copyfile(fullsource, fulltarget)
            if dirstate[mirrorpath] in "?r":
                dirstate.add(mirrorpath)

            if action == "a":
                # For adds, detect copy data as well
                copysource = dirstate.copied(sourcepath)
                if copysource and copysource.startswith(sourcemirror):
                    mirrorcopysource = mirror + copysource[len(sourcemirror):]
                    dirstate.copy(mirrorcopysource, mirrorpath)
                    repo.ui.status(
                        _("mirrored copy '%s -> %s' to '%s -> %s'\n") %
                        (copysource, sourcepath, mirrorcopysource, mirrorpath))
                else:
                    repo.ui.status(
                        _("mirrored adding '%s' to '%s'\n") %
                        (sourcepath, mirrorpath))
            else:
                repo.ui.status(
                    _("mirrored changes in '%s' to '%s'\n") %
                    (sourcepath, mirrorpath))
        elif action == "r":
            try:
                util.unlink(fulltarget)
            except OSError as e:
                if e.errno == errno.ENOENT:
                    repo.ui.status(
                        _("not mirroring remove of '%s' to '%s'; it "
                          "is already removed\n") % (sourcepath, mirrorpath))
                else:
                    raise
            else:
                dirstate.remove(mirrorpath)
                repo.ui.status(
                    _("mirrored remove of '%s' to '%s'\n") %
                    (sourcepath, mirrorpath))

    return mirroredfiles
Exemplo n.º 4
0
def listshelvesfiles(repo):
    """return all shelves in the repo as list of filenames from the repo root"""
    return [util.split(filetuple[1])[1] for filetuple in listshelves(repo)]
Exemplo n.º 5
0
def _dounshelve(ui, repo, *shelved, **opts):
    abortf = opts.get("abort")
    continuef = opts.get("continue")
    if not abortf and not continuef:
        cmdutil.checkunfinished(repo)
    shelved = list(shelved)
    if opts.get("name"):
        shelved.append(opts["name"])

    if abortf or continuef:
        if abortf and continuef:
            raise error.Abort(_("cannot use both abort and continue"))
        if shelved:
            raise error.Abort(
                _("cannot combine abort/continue with "
                  "naming a shelved change"))
        if abortf and opts.get("tool", False):
            ui.warn(_("tool option will be ignored\n"))

        try:
            state = shelvedstate.load(repo)
            if opts.get("keep") is None:
                opts["keep"] = state.keep
        except IOError as err:
            if err.errno != errno.ENOENT:
                raise
            cmdutil.wrongtooltocontinue(repo, _("unshelve"))
        except error.CorruptedState as err:
            ui.debug(str(err) + "\n")
            if continuef:
                msg = _("corrupted shelved state file")
                hint = _("please run hg unshelve --abort to abort unshelve "
                         "operation")
                raise error.Abort(msg, hint=hint)
            elif abortf:
                msg = _("could not read shelved state file, your working copy "
                        "may be in an unexpected state\nplease update to some "
                        "commit\n")
                ui.warn(msg)
                shelvedstate.clear(repo)
            return

        if abortf:
            return unshelveabort(ui, repo, state, opts)
        elif continuef:
            return unshelvecontinue(ui, repo, state, opts)
    elif len(shelved) > 1:
        raise error.Abort(_("can only unshelve one change at a time"))
    elif not shelved:
        shelved = listshelves(repo)
        if not shelved:
            raise error.Abort(_("no shelved changes to apply!"))
        basename = util.split(shelved[0][1])[1]
        ui.status(_("unshelving change '%s'\n") % basename)
    else:
        basename = shelved[0]

    if not shelvedfile(repo, basename, patchextension).exists():
        raise error.Abort(_("shelved change '%s' not found") % basename)

    lock = tr = None
    obsshelve = True
    obsshelvedfile = shelvedfile(repo, basename, "oshelve")
    if not obsshelvedfile.exists():
        # although we can unshelve a obs-based shelve technically,
        # this particular shelve was created using a traditional way
        obsshelve = False
        ui.note(
            _("falling back to traditional unshelve since "
              "shelve was traditional"))
    try:
        lock = repo.lock()
        tr = repo.transaction("unshelve", report=lambda x: None)
        oldtiprev = len(repo)

        pctx = repo["."]
        tmpwctx = pctx
        # The goal is to have a commit structure like so:
        # ...-> pctx -> tmpwctx -> shelvectx
        # where tmpwctx is an optional commit with the user's pending changes
        # and shelvectx is the unshelved changes. Then we merge it all down
        # to the original pctx.

        activebookmark = _backupactivebookmark(repo)
        tmpwctx, addedbefore = _commitworkingcopychanges(
            ui, repo, opts, tmpwctx)
        repo, shelvectx = _unshelverestorecommit(ui, repo, basename, obsshelve)
        _checkunshelveuntrackedproblems(ui, repo, shelvectx)
        branchtorestore = ""
        if shelvectx.branch() != shelvectx.p1().branch():
            branchtorestore = shelvectx.branch()

        rebaseconfigoverrides = {
            ("ui", "forcemerge"): opts.get("tool", ""),
            ("experimental", "rebaseskipobsolete"): "off",
        }
        with ui.configoverride(rebaseconfigoverrides, "unshelve"):
            shelvectx = _rebaserestoredcommit(
                ui,
                repo,
                opts,
                tr,
                oldtiprev,
                basename,
                pctx,
                tmpwctx,
                shelvectx,
                branchtorestore,
                activebookmark,
                obsshelve,
            )
            mergefiles(ui, repo, pctx, shelvectx)
            restorebranch(ui, repo, branchtorestore)
            _forgetunknownfiles(repo, shelvectx, addedbefore)

        if obsshelve:
            _obsoleteredundantnodes(repo, tr, pctx, shelvectx, tmpwctx)

        shelvedstate.clear(repo)
        _finishunshelve(repo, oldtiprev, tr, activebookmark, obsshelve)
        unshelvecleanup(ui, repo, basename, opts)
    finally:
        if tr:
            tr.release()
        lockmod.release(lock)