diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2135,7 +2135,8 @@ def undo(ui, repo): """ repo.undo() -def update(ui, repo, node=None, merge=False, clean=False, branch=None): +def update(ui, repo, node=None, merge=False, clean=False, force=None, + branch=None): """update or merge working directory Update the working directory to the specified revision. @@ -2172,7 +2173,7 @@ def update(ui, repo, node=None, merge=Fa return 1 else: node = node and repo.lookup(node) or repo.changelog.tip() - return repo.update(node, allow=merge, force=clean) + return repo.update(node, allow=merge, force=clean, forcemerge=force) def verify(ui, repo): """verify the integrity of the repository @@ -2418,8 +2419,9 @@ table = { (update, [('b', 'branch', "", _('checkout the head of a specific branch')), ('m', 'merge', None, _('allow merging of branches')), - ('C', 'clean', None, _('overwrite locally modified files'))], - _('hg update [-b TAG] [-m] [-C] [REV]')), + ('C', 'clean', None, _('overwrite locally modified files')), + ('f', 'force', None, _('force a merge with outstanding changes'))], + _('hg update [-b TAG] [-m] [-C] [-f] [REV]')), "verify": (verify, [], _('hg verify')), "version": (show_version, [], _('hg version')), } diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1358,7 +1358,7 @@ class localrepository(object): return def update(self, node, allow=False, force=False, choose=None, - moddirstate=True): + moddirstate=True, forcemerge=False): pl = self.dirstate.parents() if not force and pl[1] != nullid: self.ui.warn(_("aborting: outstanding uncommitted merges\n")) @@ -1378,6 +1378,18 @@ class localrepository(object): (c, a, d, u) = self.changes() + if allow and not forcemerge: + if c or a or d: + raise util.Abort(_("outstanding uncommited changes")) + if not forcemerge and not force: + for f in u: + if f in m2: + t1 = self.wread(f) + t2 = self.file(f).read(m2[f]) + if cmp(t1, t2) != 0: + raise util.Abort(_("'%s' already exists in the working" + " dir and differs from remote") % f) + # is this a jump, or a merge? i.e. is there a linear path # from p1 to p2? linear_path = (pa == p1 or pa == p2) diff --git a/tests/test-merge1 b/tests/test-merge1 --- a/tests/test-merge1 +++ b/tests/test-merge1 @@ -40,8 +40,10 @@ echo This is file c1 > c hg add c hg commit -m "commit #2" -d "0 0" echo This is file b2 > b +echo %% merge should fail +env HGMERGE=../merge hg update -m 1 echo %% merge of b expected -env HGMERGE=../merge hg update -m 1 +env HGMERGE=../merge hg update -f -m 1 cd ..; /bin/rm -rf t echo %% @@ -65,8 +67,10 @@ echo 'Contents of b should be "this is f cat b echo This is file b22 > b +echo %% merge fails +env HGMERGE=../merge hg update -m 2 echo %% merge expected! -env HGMERGE=../merge hg update -m 2 +env HGMERGE=../merge hg update -f -m 2 cd ..; /bin/rm -rf t mkdir t @@ -85,6 +89,8 @@ echo This is file c1 > c hg add c hg commit -m "commit #3" -d "0 0" echo This is file b33 > b -echo %% merge of b expected +echo %% merge of b should fail env HGMERGE=../merge hg update -m 2 +echo %% merge of b expected +env HGMERGE=../merge hg update -f -m 2 cd ..; /bin/rm -rf t diff --git a/tests/test-merge1.out b/tests/test-merge1.out --- a/tests/test-merge1.out +++ b/tests/test-merge1.out @@ -1,13 +1,19 @@ %% no merges expected +%% merge should fail +abort: 'b' already exists in the working dir and differs from remote %% merge of b expected merging for b merging b %% Contents of b should be "this is file b1" This is file b1 +%% merge fails +abort: outstanding uncommited changes %% merge expected! merging for b merging b +%% merge of b should fail +abort: outstanding uncommited changes %% merge of b expected merging for b merging b diff --git a/tests/test-up-local-change b/tests/test-up-local-change --- a/tests/test-up-local-change +++ b/tests/test-up-local-change @@ -25,7 +25,8 @@ cd ../r2 hg -q pull ../r1 hg status hg --debug up -hg --debug up -m +hg --debug up -m || echo failed +hg --debug up -f -m hg parents hg -v history hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ diff --git a/tests/test-up-local-change.out b/tests/test-up-local-change.out --- a/tests/test-up-local-change.out +++ b/tests/test-up-local-change.out @@ -16,6 +16,8 @@ getting b merging a resolving a file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2 +abort: outstanding uncommited changes +failed resolving manifests force None allow 1 moddirstate True linear True ancestor 1165e8bd193e local 1165e8bd193e remote 1165e8bd193e