def updatedir(ui, repo, patches, similarity=0): '''Update dirstate after patch application according to metadata''' if not patches: return [] copies = [] removes = set() cfiles = patches.keys() cwd = repo.getcwd() if cwd: cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()] for f in patches: gp = patches[f] if not gp: continue if gp.op == 'RENAME': copies.append((gp.oldpath, gp.path)) removes.add(gp.oldpath) elif gp.op == 'COPY': copies.append((gp.oldpath, gp.path)) elif gp.op == 'DELETE': removes.add(gp.path) wctx = repo[None] for src, dst in copies: dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd) if (not similarity) and removes: wctx.remove(sorted(removes), True) for f in patches: gp = patches[f] if gp and gp.mode: islink, isexec = gp.mode dst = repo.wjoin(gp.path) # patch won't create empty files if gp.op == 'ADD' and not os.path.lexists(dst): flags = (isexec and 'x' or '') + (islink and 'l' or '') repo.wwrite(gp.path, '', flags) util.setflags(dst, islink, isexec) addremove(repo, cfiles, similarity=similarity) files = patches.keys() files.extend([r for r in removes if r not in files]) return sorted(files)
def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None): """apply the merge action list to the working directory wctx is the working copy context mctx is the context to be merged into the working copy Return a tuple of counts (updated, merged, removed, unresolved) that describes how many files were affected by the update. """ updated, merged, removed, unresolved = 0, 0, 0, 0 ms = mergestate(repo) ms.reset(wctx.p1().node(), mctx.node()) moves = [] for m, l in actions.items(): l.sort() # prescan for merges for f, args, msg in actions['m']: f1, f2, fa, move, anc = args if f == '.hgsubstate': # merged internally continue repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f)) fcl = wctx[f1] fco = mctx[f2] actx = repo[anc] if fa in actx: fca = actx[fa] else: fca = repo.filectx(f1, fileid=nullrev) ms.add(fcl, fco, fca, f) if f1 != f and move: moves.append(f1) audit = repo.wopener.audit _updating = _('updating') _files = _('files') progress = repo.ui.progress # remove renamed files after safely stored for f in moves: if os.path.lexists(repo.wjoin(f)): repo.ui.debug("removing %s\n" % f) audit(f) util.unlinkpath(repo.wjoin(f)) numupdates = sum(len(l) for m, l in actions.items() if m != 'k') if [a for a in actions['r'] if a[0] == '.hgsubstate']: subrepo.submerge(repo, wctx, mctx, wctx, overwrite) # remove in parallel (must come first) z = 0 prog = worker.worker(repo.ui, 0.001, batchremove, (repo, ), actions['r']) for i, item in prog: z += i progress(_updating, z, item=item, total=numupdates, unit=_files) removed = len(actions['r']) # get in parallel prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g']) for i, item in prog: z += i progress(_updating, z, item=item, total=numupdates, unit=_files) updated = len(actions['g']) if [a for a in actions['g'] if a[0] == '.hgsubstate']: subrepo.submerge(repo, wctx, mctx, wctx, overwrite) # forget (manifest only, just log it) (must come first) for f, args, msg in actions['f']: repo.ui.debug(" %s: %s -> f\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) # re-add (manifest only, just log it) for f, args, msg in actions['a']: repo.ui.debug(" %s: %s -> a\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) # keep (noop, just log it) for f, args, msg in actions['k']: repo.ui.debug(" %s: %s -> k\n" % (f, msg)) # no progress # merge for f, args, msg in actions['m']: repo.ui.debug(" %s: %s -> m\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) f1, f2, fa, move, anc = args if f == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue audit(f) r = ms.resolve(f, wctx, labels=labels) if r is not None and r > 0: unresolved += 1 else: if r is None: updated += 1 else: merged += 1 # directory rename, move local for f, args, msg in actions['dm']: repo.ui.debug(" %s: %s -> dm\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) f0, flags = args repo.ui.note(_("moving %s to %s\n") % (f0, f)) audit(f) repo.wwrite(f, wctx.filectx(f0).data(), flags) util.unlinkpath(repo.wjoin(f0)) updated += 1 # local directory rename, get for f, args, msg in actions['dg']: repo.ui.debug(" %s: %s -> dg\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) f0, flags = args repo.ui.note(_("getting %s to %s\n") % (f0, f)) repo.wwrite(f, mctx.filectx(f0).data(), flags) updated += 1 # divergent renames for f, args, msg in actions['dr']: repo.ui.debug(" %s: %s -> dr\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) fl, = args repo.ui.warn( _("note: possible conflict - %s was renamed " "multiple times to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) # rename and delete for f, args, msg in actions['rd']: repo.ui.debug(" %s: %s -> rd\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) fl, = args repo.ui.warn( _("note: possible conflict - %s was deleted " "and renamed to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) # exec for f, args, msg in actions['e']: repo.ui.debug(" %s: %s -> e\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) flags, = args audit(f) util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) updated += 1 ms.commit() progress(_updating, None, total=numupdates, unit=_files) return updated, merged, removed, unresolved
def setflags(self, path, l, x): return util.setflags(self.join(path), l, x)
if f2: repo.ui.note(_("getting %s to %s\n") % (f2, fd)) t = mctx.filectx(f2).data() repo.wwrite(fd, t, flags) updated += 1 elif m == "dr": # divergent renames fl = a[2] repo.ui.warn( _("note: possible conflict - %s was renamed " "multiple times to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "e": # exec flags = a[2] repo.wopener.audit(f) util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) ms.commit() repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files')) return updated, merged, removed, unresolved def recordupdates(repo, action, branchmerge): "record merge actions to the dirstate" for a in action: f, m = a[:2] if m == "r": # remove if branchmerge: repo.dirstate.remove(f) else:
def applyupdates(repo, actions, wctx, mctx, actx, overwrite): """apply the merge action list to the working directory wctx is the working copy context mctx is the context to be merged into the working copy actx is the context of the common ancestor Return a tuple of counts (updated, merged, removed, unresolved) that describes how many files were affected by the update. """ updated, merged, removed, unresolved = 0, 0, 0, 0 ms = mergestate(repo) ms.reset(wctx.p1().node()) moves = [] actions.sort(key=actionkey) # prescan for merges for a in actions: f, m, args, msg = a repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) if m == "m": # merge f2, fd, move = args if fd == '.hgsubstate': # merged internally continue repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd)) fcl = wctx[f] fco = mctx[f2] if mctx == actx: # backwards, use working dir parent as ancestor if fcl.parents(): fca = fcl.p1() else: fca = repo.filectx(f, fileid=nullrev) else: fca = fcl.ancestor(fco, actx) if not fca: fca = repo.filectx(f, fileid=nullrev) ms.add(fcl, fco, fca, fd) if f != fd and move: moves.append(f) audit = repo.wopener.audit # remove renamed files after safely stored for f in moves: if os.path.lexists(repo.wjoin(f)): repo.ui.debug("removing %s\n" % f) audit(f) util.unlinkpath(repo.wjoin(f)) numupdates = len(actions) workeractions = [a for a in actions if a[1] in 'gr'] updateactions = [a for a in workeractions if a[1] == 'g'] updated = len(updateactions) removeactions = [a for a in workeractions if a[1] == 'r'] removed = len(removeactions) actions = [a for a in actions if a[1] not in 'gr'] hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate'] if hgsub and hgsub[0] == 'r': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) z = 0 prog = worker.worker(repo.ui, 0.001, getremove, (repo, mctx, overwrite), removeactions) for i, item in prog: z += i repo.ui.progress(_('updating'), z, item=item, total=numupdates, unit=_('files')) prog = worker.worker(repo.ui, 0.001, getremove, (repo, mctx, overwrite), updateactions) for i, item in prog: z += i repo.ui.progress(_('updating'), z, item=item, total=numupdates, unit=_('files')) if hgsub and hgsub[0] == 'g': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) _updating = _('updating') _files = _('files') progress = repo.ui.progress for i, a in enumerate(actions): f, m, args, msg = a progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files) if m == "m": # merge f2, fd, move = args if fd == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue audit(fd) r = ms.resolve(fd, wctx, mctx) if r is not None and r > 0: unresolved += 1 else: if r is None: updated += 1 else: merged += 1 elif m == "d": # directory rename f2, fd, flags = args if f: repo.ui.note(_("moving %s to %s\n") % (f, fd)) audit(f) repo.wwrite(fd, wctx.filectx(f).data(), flags) util.unlinkpath(repo.wjoin(f)) if f2: repo.ui.note(_("getting %s to %s\n") % (f2, fd)) repo.wwrite(fd, mctx.filectx(f2).data(), flags) updated += 1 elif m == "dr": # divergent renames fl, = args repo.ui.warn(_("note: possible conflict - %s was renamed " "multiple times to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "rd": # rename and delete fl, = args repo.ui.warn(_("note: possible conflict - %s was deleted " "and renamed to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "e": # exec flags, = args audit(f) util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) updated += 1 ms.commit() progress(_updating, None, total=numupdates, unit=_files) return updated, merged, removed, unresolved
def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None): """apply the merge action list to the working directory wctx is the working copy context mctx is the context to be merged into the working copy Return a tuple of counts (updated, merged, removed, unresolved) that describes how many files were affected by the update. """ updated, merged, removed, unresolved = 0, 0, 0, 0 ms = mergestate(repo) ms.reset(wctx.p1().node(), mctx.node()) moves = [] for m, l in actions.items(): l.sort() # prescan for merges for f, args, msg in actions['m']: f1, f2, fa, move, anc = args if f == '.hgsubstate': # merged internally continue repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f)) fcl = wctx[f1] fco = mctx[f2] actx = repo[anc] if fa in actx: fca = actx[fa] else: fca = repo.filectx(f1, fileid=nullrev) ms.add(fcl, fco, fca, f) if f1 != f and move: moves.append(f1) audit = repo.wvfs.audit _updating = _('updating') _files = _('files') progress = repo.ui.progress # remove renamed files after safely stored for f in moves: if os.path.lexists(repo.wjoin(f)): repo.ui.debug("removing %s\n" % f) audit(f) util.unlinkpath(repo.wjoin(f)) numupdates = sum(len(l) for m, l in actions.items() if m != 'k') def dirtysubstate(): # mark '.hgsubstate' as possibly dirty forcibly, because # modified '.hgsubstate' is misunderstood as clean, # when both st_size/st_mtime of '.hgsubstate' aren't changed, # even if "submerge" fails and '.hgsubstate' is inconsistent repo.dirstate.normallookup('.hgsubstate') if [a for a in actions['r'] if a[0] == '.hgsubstate']: dirtysubstate() subrepo.submerge(repo, wctx, mctx, wctx, overwrite) # remove in parallel (must come first) z = 0 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r']) for i, item in prog: z += i progress(_updating, z, item=item, total=numupdates, unit=_files) removed = len(actions['r']) # get in parallel prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g']) for i, item in prog: z += i progress(_updating, z, item=item, total=numupdates, unit=_files) updated = len(actions['g']) if [a for a in actions['g'] if a[0] == '.hgsubstate']: dirtysubstate() subrepo.submerge(repo, wctx, mctx, wctx, overwrite) # forget (manifest only, just log it) (must come first) for f, args, msg in actions['f']: repo.ui.debug(" %s: %s -> f\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) # re-add (manifest only, just log it) for f, args, msg in actions['a']: repo.ui.debug(" %s: %s -> a\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) # keep (noop, just log it) for f, args, msg in actions['k']: repo.ui.debug(" %s: %s -> k\n" % (f, msg)) # no progress # merge for f, args, msg in actions['m']: repo.ui.debug(" %s: %s -> m\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) if f == '.hgsubstate': # subrepo states need updating dirtysubstate() subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue audit(f) r = ms.resolve(f, wctx, labels=labels) if r is not None and r > 0: unresolved += 1 else: if r is None: updated += 1 else: merged += 1 # directory rename, move local for f, args, msg in actions['dm']: repo.ui.debug(" %s: %s -> dm\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) f0, flags = args repo.ui.note(_("moving %s to %s\n") % (f0, f)) audit(f) repo.wwrite(f, wctx.filectx(f0).data(), flags) util.unlinkpath(repo.wjoin(f0)) updated += 1 # local directory rename, get for f, args, msg in actions['dg']: repo.ui.debug(" %s: %s -> dg\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) f0, flags = args repo.ui.note(_("getting %s to %s\n") % (f0, f)) repo.wwrite(f, mctx.filectx(f0).data(), flags) updated += 1 # exec for f, args, msg in actions['e']: repo.ui.debug(" %s: %s -> e\n" % (f, msg)) z += 1 progress(_updating, z, item=f, total=numupdates, unit=_files) flags, = args audit(f) util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) updated += 1 ms.commit() progress(_updating, None, total=numupdates, unit=_files) return updated, merged, removed, unresolved
repo.wwrite(fd, t, flags) util.unlinkpath(repo.wjoin(f)) if f2: repo.ui.note(_("getting %s to %s\n") % (f2, fd)) t = mctx.filectx(f2).data() repo.wwrite(fd, t, flags) updated += 1 elif m == "dr": # divergent renames fl = a[2] repo.ui.warn(_("note: possible conflict - %s was renamed " "multiple times to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "e": # exec flags = a[2] repo.wopener.audit(f) util.setflags(repo.wjoin(f), "l" in flags, "x" in flags) ms.commit() repo.ui.progress(_("updating"), None, total=numupdates, unit=_("files")) return updated, merged, removed, unresolved def recordupdates(repo, action, branchmerge): "record merge actions to the dirstate" for a in action: f, m = a[:2] if m == "r": # remove if branchmerge: repo.dirstate.remove(f) else:
util.unlinkpath(repo.wjoin(f)) if f2: repo.ui.note(_("getting %s to %s\n") % (f2, fd)) t = mctx.filectx(f2).data() repo.wwrite(fd, t, flags) updated += 1 elif m == "dr": # divergent renames fl = a[2] repo.ui.warn(_("note: possible conflict - %s was renamed " "multiple times to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "e": # exec flags = a[2] repo.wopener.audit(f) util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) ms.commit() repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files')) return updated, merged, removed, unresolved def recordupdates(repo, action, branchmerge): "record merge actions to the dirstate" for a in action: f, m = a[:2] if m == "r": # remove if branchmerge: repo.dirstate.remove(f) else: repo.dirstate.drop(f)
def applyupdates(repo, actions, wctx, mctx, actx, overwrite): """apply the merge action list to the working directory wctx is the working copy context mctx is the context to be merged into the working copy actx is the context of the common ancestor Return a tuple of counts (updated, merged, removed, unresolved) that describes how many files were affected by the update. """ updated, merged, removed, unresolved = 0, 0, 0, 0 ms = mergestate(repo) ms.reset(wctx.p1().node()) moves = [] actions.sort(key=actionkey) # prescan for merges for a in actions: f, m, args, msg = a repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) if m == "m": # merge f2, fd, move = args if fd == '.hgsubstate': # merged internally continue repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd)) fcl = wctx[f] fco = mctx[f2] if mctx == actx: # backwards, use working dir parent as ancestor if fcl.parents(): fca = fcl.p1() else: fca = repo.filectx(f, fileid=nullrev) else: fca = fcl.ancestor(fco, actx) if not fca: fca = repo.filectx(f, fileid=nullrev) ms.add(fcl, fco, fca, fd) if f != fd and move: moves.append(f) audit = repo.wopener.audit # remove renamed files after safely stored for f in moves: if os.path.lexists(repo.wjoin(f)): repo.ui.debug("removing %s\n" % f) audit(f) util.unlinkpath(repo.wjoin(f)) numupdates = len(actions) workeractions = [a for a in actions if a[1] in 'gr'] updateactions = [a for a in workeractions if a[1] == 'g'] updated = len(updateactions) removeactions = [a for a in workeractions if a[1] == 'r'] removed = len(removeactions) actions = [a for a in actions if a[1] not in 'gr'] hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate'] if hgsub and hgsub[0] == 'r': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) z = 0 prog = worker.worker(repo.ui, 0.001, getremove, (repo, mctx, overwrite), removeactions) for i, item in prog: z += i repo.ui.progress(_('updating'), z, item=item, total=numupdates, unit=_('files')) prog = worker.worker(repo.ui, 0.001, getremove, (repo, mctx, overwrite), updateactions) for i, item in prog: z += i repo.ui.progress(_('updating'), z, item=item, total=numupdates, unit=_('files')) if hgsub and hgsub[0] == 'g': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) _updating = _('updating') _files = _('files') progress = repo.ui.progress for i, a in enumerate(actions): f, m, args, msg = a progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files) if m == "m": # merge f2, fd, move = args if fd == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue audit(fd) r = ms.resolve(fd, wctx, mctx) if r is not None and r > 0: unresolved += 1 else: if r is None: updated += 1 else: merged += 1 elif m == "d": # directory rename f2, fd, flags = args if f: repo.ui.note(_("moving %s to %s\n") % (f, fd)) audit(f) repo.wwrite(fd, wctx.filectx(f).data(), flags) util.unlinkpath(repo.wjoin(f)) if f2: repo.ui.note(_("getting %s to %s\n") % (f2, fd)) repo.wwrite(fd, mctx.filectx(f2).data(), flags) updated += 1 elif m == "dr": # divergent renames fl, = args repo.ui.warn( _("note: possible conflict - %s was renamed " "multiple times to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "rd": # rename and delete fl, = args repo.ui.warn( _("note: possible conflict - %s was deleted " "and renamed to:\n") % f) for nf in fl: repo.ui.warn(" %s\n" % nf) elif m == "e": # exec flags, = args audit(f) util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) updated += 1 ms.commit() progress(_updating, None, total=numupdates, unit=_files) return updated, merged, removed, unresolved
def applyupdates(repo, action, wctx, mctx, actx, overwrite): """apply the merge action list to the working directory wctx is the working copy context mctx is the context to be merged into the working copy actx is the context of the common ancestor Return a tuple of counts (updated, merged, removed, unresolved) that describes how many files were affected by the update. """ updated, merged, removed, unresolved = 0, 0, 0, 0 ms = mergestate(repo) ms.reset(wctx.p1().node()) moves = [] action.sort(key=actionkey) # prescan for merges for a in action: f, m = a[:2] if m == 'm': # merge f2, fd, flags, move = a[2:] if f == '.hgsubstate': # merged internally continue repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd)) fcl = wctx[f] fco = mctx[f2] if mctx == actx: # backwards, use working dir parent as ancestor if fcl.parents(): fca = fcl.p1() else: fca = repo.filectx(f, fileid=nullrev) else: fca = fcl.ancestor(fco, actx) if not fca: fca = repo.filectx(f, fileid=nullrev) ms.add(fcl, fco, fca, fd, flags) if f != fd and move: moves.append(f) audit = scmutil.pathauditor(repo.root) # remove renamed files after safely stored for f in moves: if os.path.lexists(repo.wjoin(f)): repo.ui.debug("removing %s\n" % f) audit(f) os.unlink(repo.wjoin(f)) numupdates = len(action) for i, a in enumerate(action): f, m = a[:2] repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates, unit=_('files')) if f and f[0] == "/": continue if m == "r": # remove repo.ui.note(_("removing %s\n") % f) audit(f) if f == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx, overwrite) try: util.unlinkpath(repo.wjoin(f)) except OSError, inst: if inst.errno != errno.ENOENT: repo.ui.warn(_("update failed to remove %s: %s!\n") % (f, inst.strerror)) removed += 1 elif m == "m": # merge if f == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue f2, fd, flags, move = a[2:] repo.wopener.audit(fd) r = ms.resolve(fd, wctx, mctx) if r is not None and r > 0: unresolved += 1 else: if r is None: updated += 1 else: merged += 1 util.setflags(repo.wjoin(fd), 'l' in flags, 'x' in flags) if (move and repo.dirstate.normalize(fd) != f and os.path.lexists(repo.wjoin(f))): repo.ui.debug("removing %s\n" % f) audit(f) os.unlink(repo.wjoin(f))