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 _moveto(repo, bookmark, ctx, clean=False): """Moves the given bookmark and the working copy to the given revision. By default it does not overwrite the working copy contents unless clean is True. Assumes the wlock is already taken. """ # Move working copy over if clean: merge.update( repo, ctx.node(), False, # not a branchmerge True, # force overwriting files None, ) # not a partial update else: # Mark any files that are different between the two as normal-lookup # so they show up correctly in hg status afterwards. wctx = repo[None] m1 = wctx.manifest() m2 = ctx.manifest() diff = m1.diff(m2) changedfiles = [] changedfiles.extend(pycompat.iterkeys(diff)) dirstate = repo.dirstate dirchanges = [f for f in dirstate if dirstate[f] != "n"] changedfiles.extend(dirchanges) if changedfiles or ctx.node() != repo["."].node(): with dirstate.parentchange(): dirstate.rebuild(ctx.node(), m2, changedfiles) # Move bookmark over if bookmark: lock = tr = None try: lock = repo.lock() tr = repo.transaction("reset") changes = [(bookmark, ctx.node())] repo._bookmarks.applychanges(repo, tr, changes) tr.close() finally: lockmod.release(lock, tr)
def merge_(rev): merge.update(repo, rev, True, False)
def update(rev): merge.update(repo, rev, False, True)