def snapshotcheckout(ui, repo, *args, **opts): """checks out the working copy to the snapshot state, given its revision id """ cctx = getsnapshotctx(ui, repo, args) clean = opts.get("clean") # This is a temporary safety check that WC is clean. if sum(map(len, repo.status(unknown=True))) != 0 and not clean: raise error.Abort( _("You must have a clean working copy to checkout on a snapshot. " "Use --clean to bypass that.\n")) ui.status(_("will checkout on %s\n") % cctx.hex()) with repo.wlock(): parents = [p.node() for p in cctx.parents()] # First we check out on the 1st parent of the snapshot state hg.update(repo.unfiltered(), parents[0], quietempty=True) # Then we update snapshot files in the working copy # Here the dirstate is not updated because of the matcher matcher = scmutil.matchfiles(repo, cctx.files(), opts) mergemod.update(repo.unfiltered(), cctx.hex(), False, False, matcher=matcher) # Finally, we mark the modified files in the dirstate scmutil.addremove(repo, matcher, "", opts) # Tie the state to the 2nd parent if needed if len(parents) == 2: with repo.dirstate.parentchange(): repo.setparents(*parents) snapshotmetadataid = cctx.extra().get("snapshotmetadataid") if snapshotmetadataid: snapmetadata = snapshotmetadata.getfromlocalstorage( repo, snapshotmetadataid) checkouttosnapshotmetadata(ui, repo, snapmetadata, clean) ui.status(_("checkout complete\n"))
def changedlines(ui, repo, ctx1, ctx2, fns): added, removed = 0, 0 fmatch = scmutil.matchfiles(repo, fns) diff = "".join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch)) for l in diff.split("\n"): if l.startswith("+") and not l.startswith("+++ "): added += 1 elif l.startswith("-") and not l.startswith("--- "): removed += 1 return (added, removed)
def snapshot(ui, repo, files, node, tmproot): """snapshot files as of some revision if not using snapshot, -I/-X does not work and recursive diff in tools like kdiff3 and meld displays too many files.""" dirname = os.path.basename(repo.root) if dirname == "": dirname = "root" if node is not None: dirname = "%s.%s" % (dirname, short(node)) base = os.path.join(tmproot, dirname) os.mkdir(base) fnsandstat = [] if node is not None: ui.note( _("making snapshot of %d files from rev %s\n") % (len(files), short(node))) else: ui.note( _("making snapshot of %d files from working directory\n") % (len(files))) if files: repo.ui.setconfig("ui", "archivemeta", False) archival.archive(repo, base, node, "files", matchfn=scmutil.matchfiles(repo, files)) for fn in sorted(files): wfn = util.pconvert(fn) ui.note(" %s\n" % wfn) if node is None: dest = os.path.join(base, wfn) fnsandstat.append((dest, repo.wjoin(fn), util.lstat(dest))) return dirname, fnsandstat
def restore(ui, repo, csid, clean=False): ui.status(_(f"Will restore snapshot {csid}\n"), component="snapshot") snapshot = repo.edenapi.fetchsnapshot( getreponame(repo), { "cs_id": bytes.fromhex(csid), }, ) # Once merges/conflicted states are supported, we'll need to support more # than one parent assert isinstance(snapshot["hg_parents"], bytes) with repo.wlock(): if _hasanychanges(repo): if clean: _fullclean(ui, repo) else: raise error.Abort( _( "Can't restore snapshot with unclean working copy, unless --clean is specified" ) ) ui.status( _(f"Updating to parent {snapshot['hg_parents'].hex()}\n"), component="snapshot", ) hg.updatetotally( ui, repo, repo[snapshot["hg_parents"]], None, updatecheck="abort" ) files2download = [] for (path, fc) in snapshot["file_changes"]: matcher = scmutil.matchfiles(repo, [path]) fctx = repo[None][path] # fc is either a string or a dict, can't use "Deletion" in fc because # that applies to "UntrackedDeletion" as well if fc == "Deletion": cmdutil.remove(ui, repo, matcher, "", False, False) elif fc == "UntrackedDeletion": if not fctx.exists(): # File was hg added and is now missing. Let's add an empty file first repo.wwrite(path, b"", "") cmdutil.add(ui, repo, matcher, prefix="", explicitonly=True) fctx.remove() elif "Change" in fc: if fctx.exists(): # File exists, was modified fctx.remove() files2download.append((path, fc["Change"]["upload_token"])) elif "UntrackedChange" in fc: if fctx.exists(): # File was hg rm'ed and then overwritten cmdutil.remove( ui, repo, matcher, prefix="", after=False, force=False ) files2download.append((path, fc["UntrackedChange"]["upload_token"])) repo.edenapi.downloadfiles(getreponame(repo), repo.root, files2download) for (path, fc) in snapshot["file_changes"]: if "Change" in fc: # Doesn't hurt to add again if it was already tracked cmdutil.add(ui, repo, scmutil.matchfiles(repo, [path]), "", True)
repo[None].add(["bar-a"]) repo[None].forget(["bar-r"]) # status at this point: # M bar-m # A bar-a # R bar-r # C foo print("== checking workingctx.status:") wctx = repo[None] print("wctx._status=%s" % (str(wctx._status))) 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" )
repo[None].forget(["bar-r"]) # status at this point: # M bar-m # A bar-a # R bar-r # C foo print("== checking workingctx.status:") wctx = repo[None] print("wctx._status=%s" % (str(wctx._status))) 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"], [], [],