# HG changeset patch # User Thomas Arendsen Hein # Date 1160473639 -7200 # Node ID 34f08b8883cfce5e6a18e7a9a900feca773bd197 # Parent b7a46cbf3f598fd7cd89ee4667b10c868318f767# Parent 39fd6e82ea38015fe54b66bba2e86492df8e9705 merge with upstream diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -201,30 +201,55 @@ def clone(ui, source, dest=None, pull=Fa dest_lock.release() if update: - _merge.update(dest_repo, dest_repo.changelog.tip()) + _update(dest_repo, dest_repo.changelog.tip()) if dir_cleanup: dir_cleanup.close() return src_repo, dest_repo +def _showstats(repo, stats): + stats = ((stats[0], _("updated")), + (stats[1], _("merged")), + (stats[2], _("removed")), + (stats[3], _("unresolved"))) + note = ", ".join([_("%d files %s") % s for s in stats]) + repo.ui.status("%s\n" % note) + +def _update(repo, node): return update(repo, node) + def update(repo, node): """update the working directory to node, merging linear changes""" - return _merge.update(repo, node) + stats = _merge.update(repo, node, False, False, None, None) + _showstats(repo, stats) + if stats[3]: + repo.ui.status(_("There are unresolved merges with" + " locally modified files.\n")) + return stats[3] def clean(repo, node, wlock=None, show_stats=True): """forcibly switch the working directory to node, clobbering changes""" - return _merge.update(repo, node, force=True, wlock=wlock, - show_stats=show_stats) + stats = _merge.update(repo, node, False, True, None, wlock) + if show_stats: _showstats(repo, stats) + return stats[3] def merge(repo, node, force=None, remind=True, wlock=None): """branch merge with node, resolving changes""" - return _merge.update(repo, node, branchmerge=True, force=force, - remind=remind, wlock=wlock) + stats = _merge.update(repo, node, True, force, False, wlock) + _showstats(repo, stats) + if stats[3]: + pl = repo.parents() + repo.ui.status(_("There are unresolved merges," + " you can redo the full merge using:\n" + " hg update -C %s\n" + " hg merge %s\n" + % (pl[0].rev(), pl[1].rev()))) + elif remind: + repo.ui.status(_("(branch merge, don't forget to commit)\n")) + return stats[3] def revert(repo, node, choose, wlock): """revert changes to revision in node without updating dirstate""" - return _merge.update(repo, node, force=True, partial=choose, - show_stats=False, wlock=wlock) + return _merge.update(repo, node, False, True, choose, wlock)[3] def verify(repo): """verify the consistency of a repository""" diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -13,13 +13,9 @@ demandload(globals(), "errno util os tem def filemerge(repo, fw, fo, wctx, mctx): """perform a 3-way merge in the working directory - fw = filename in the working directory and first parent + fw = filename in the working directory fo = filename in other parent wctx, mctx = working and merge changecontexts - - TODO: - if fw is copied in the working directory, we get confused - implement move and fd """ def temp(prefix, ctx): @@ -64,9 +60,7 @@ def filemerge(repo, fw, fo, wctx, mctx): return r def checkunknown(wctx, mctx): - """ - check for collisions between unknown files and files in m2 - """ + "check for collisions between unknown files and files in mctx" man = mctx.manifest() for f in wctx.unknown(): if f in man: @@ -94,9 +88,7 @@ def forgetremoved(wctx, mctx): return action def nonoverlap(d1, d2): - """ - Return list of elements in d1 not in d2 - """ + "Return list of elements in d1 not in d2" l = [] for d in d1: @@ -107,9 +99,7 @@ def nonoverlap(d1, d2): return l def findold(fctx, limit): - """ - find files that path was copied from, back to linkrev limit - """ + "find files that path was copied from, back to linkrev limit" old = {} orig = fctx.path() @@ -174,7 +164,10 @@ def findcopies(repo, m1, m2, limit): def manifestmerge(repo, p1, p2, pa, overwrite, partial): """ - Merge manifest m1 with m2 using ancestor ma and generate merge action list + Merge p1 and p2 with ancestor ma and generate merge action list + + overwrite = whether we clobber working files + partial = function to filter file lists """ repo.ui.note(_("resolving manifests\n")) @@ -275,6 +268,8 @@ def manifestmerge(repo, p1, p2, pa, over return action def applyupdates(repo, action, wctx, mctx): + "apply the merge action list to the working directory" + updated, merged, removed, unresolved = 0, 0, 0, 0 action.sort() for a in action: @@ -296,15 +291,14 @@ def applyupdates(repo, action, wctx, mct if filemerge(repo, f, f2, wctx, mctx): unresolved += 1 else: + merged += 1 if f != fd: repo.ui.debug(_("copying %s to %s\n") % (f, fd)) repo.wwrite(fd, repo.wread(f)) if move: repo.ui.debug(_("removing %s\n") % f) os.unlink(repo.wjoin(f)) - util.set_exec(repo.wjoin(fd), flag) - merged += 1 elif m == "g": # get flag = a[2] repo.ui.note(_("getting %s\n") % f) @@ -319,6 +313,8 @@ def applyupdates(repo, action, wctx, mct return updated, merged, removed, unresolved def recordupdates(repo, action, branchmerge, mctx): + "record merge actions to the dirstate" + for a in action: f, m = a[:2] if m == "r": # remove @@ -355,8 +351,15 @@ def recordupdates(repo, action, branchme else: repo.dirstate.copy(f2, fd) -def update(repo, node, branchmerge=False, force=False, partial=None, - wlock=None, show_stats=True, remind=True): +def update(repo, node, branchmerge, force, partial, wlock): + """ + Perform a merge between the working directory and the given node + + branchmerge = whether to merge between branches + force = whether to force branch merging or file overwriting + partial = a function to filter file lists (dirstate not updated) + wlock = working dir lock, if already held + """ if not wlock: wlock = repo.wlock() @@ -397,32 +400,12 @@ def update(repo, node, branchmerge=False if not partial: repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) - updated, merged, removed, unresolved = applyupdates(repo, action, wc, p2) + stats = applyupdates(repo, action, wc, p2) - if show_stats: - stats = ((updated, _("updated")), - (merged - unresolved, _("merged")), - (removed, _("removed")), - (unresolved, _("unresolved"))) - note = ", ".join([_("%d files %s") % s for s in stats]) - repo.ui.status("%s\n" % note) if not partial: recordupdates(repo, action, branchmerge, p2) repo.dirstate.setparents(fp1, fp2) - repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved) + repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) - if branchmerge: - if unresolved: - repo.ui.status(_("There are unresolved merges," - " you can redo the full merge using:\n" - " hg update -C %s\n" - " hg merge %s\n" - % (p1.rev(), p2.rev()))) - elif remind: - repo.ui.status(_("(branch merge, don't forget to commit)\n")) - elif unresolved: - repo.ui.status(_("There are unresolved merges with" - " locally modified files.\n")) + return stats - return unresolved -