diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -57,7 +57,9 @@ def dodiff(repo, files = None, node1 = N c, a, d = map(lambda x: filterfiles(files, x), (c, a, d)) for f in c: - to = repo.file(f).read(mmap[f]) + to = None + if f in mmap: + to = repo.file(f).read(mmap[f]) tn = read(f) sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f)) for f in a: @@ -450,7 +452,7 @@ def undo(ui, repo): """undo the last transaction""" repo.undo() -def update(ui, repo, node=None): +def update(ui, repo, node=None, merge=False, clean=False): '''update or merge working directory If there are no outstanding changes in the working directory and @@ -464,7 +466,7 @@ def update(ui, repo, node=None): are allowed. ''' node = node and repo.lookup(node) or repo.changelog.tip() - repo.update(node) + return repo.update(node, allow=merge, force=clean) def verify(ui, repo): """verify the integrity of the repository""" @@ -524,7 +526,12 @@ table = { "tags": (tags, [], 'hg tags'), "tip": (tip, [], 'hg tip'), "undo": (undo, [], 'hg undo'), - "update|up|checkout|co|resolve": (update, [], 'hg update [node]'), + "update|up|checkout|co|resolve": (update, + [('m', 'merge', None, + 'allow merging of conflicts'), + ('C', 'clean', None, + 'overwrite locally modified files')], + 'hg update [options] [node]'), "verify": (verify, [], 'hg verify'), } @@ -599,6 +606,7 @@ def dispatch(args): tb = traceback.extract_tb(sys.exc_info()[2]) if len(tb) > 2: # no raise + raise u.warn("%s: invalid arguments\n" % i[0].__name__) u.warn("syntax: %s\n" % i[2]) sys.exit(-1) diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -835,9 +835,9 @@ class localrepository: tr.close() return - def update(self, node): + def update(self, node, allow=False, force=False): pl = self.dirstate.parents() - if pl[1] != nullid: + if not force and pl[1] != nullid: self.ui.warn("aborting: outstanding uncommitted merges\n") return @@ -880,7 +880,7 @@ class localrepository: get[f] = m2[f] del m2[f] elif f in ma: - if n != ma[f]: + if not force and n != ma[f]: r = self.ui.prompt( (" local changed %s which remote deleted\n" % f) + "(k)eep or (d)elete?", "[kd]", "k") @@ -898,22 +898,34 @@ class localrepository: for f, n in m2.iteritems(): if f[0] == "/": continue - if f in ma and n != ma[f]: - r = self.ui.prompt( - ("remote changed %s which local deleted\n" % f) + - "(k)eep or (d)elete?", "[kd]", "k") - if r == "d": remove.append(f) + if not force and f in ma and n != ma[f]: + r = self.ui.prompt( + ("remote changed %s which local deleted\n" % f) + + "(k)eep or (d)elete?", "[kd]", "k") + if r == "d": remove.append(f) else: self.ui.debug("remote created %s\n" % f) get[f] = n del mw, m1, m2, ma + if force: + for f in merge: + get[f] = merge[f][1] + merge = {} + if not merge: # we don't need to do any magic, just jump to the new rev mode = 'n' p1, p2 = p2, nullid else: + if not allow: + self.ui.status("the following files conflict:\n") + for f in merge: + self.ui.status(" %s\n" % f) + self.ui.warn("aborting update due to conflicting files!\n") + self.ui.status("(use update -m to allow a merge)\n") + return 1 # we have to remember what files we needed to get/change # because any file that's different from either one of its # parents must be in the changeset @@ -976,7 +988,7 @@ class localrepository: cmd = os.environ.get("HGMERGE", "hgmerge") r = os.system("%s %s %s %s" % (cmd, a, b, c)) if r: - self.ui.warn("merging %s failed!\n" % f) + self.ui.warn("merging %s failed!\n" % fn) os.unlink(b) os.unlink(c)