Mercurial > hg
changeset 6518:92ccccb55ba3
resolve: new command
- add basic resolve command functionality
- point failed update and merge at resolve
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Fri, 11 Apr 2008 12:52:56 -0500 |
parents | fcfb6a0a0a84 |
children | 98dfc5751fdc |
files | mercurial/commands.py mercurial/hg.py mercurial/merge.py tests/test-add.out tests/test-conflict.out tests/test-convert-svn-sink.out tests/test-debugcomplete.out tests/test-globalopts.out tests/test-help.out tests/test-merge-local.out tests/test-merge-revert2.out tests/test-merge7.out tests/test-merge9 tests/test-merge9.out |
diffstat | 14 files changed, 128 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py Fri Apr 11 12:04:26 2008 +0200 +++ b/mercurial/commands.py Fri Apr 11 12:52:56 2008 -0500 @@ -13,6 +13,7 @@ import difflib, patch, time, help, mdiff, tempfile import version, socket import archival, changegroup, cmdutil, hgweb.server, sshserver, hbisect +import merge as merge_ # Commands start here, listed alphabetically @@ -2236,6 +2237,35 @@ finally: del wlock +def resolve(ui, repo, *pats, **opts): + """resolve file merges from a branch merge or update + + This command will attempt to resolve unresolved merges from the + last update or merge command. This will use the local file + revision preserved at the last update or merge to cleanly retry + the file merge attempt. With no file or options specified, this + command will attempt to resolve all unresolved files. + """ + + if len([x for x in opts if opts[x]]) > 1: + raise util.Abort(_("too many options specified")) + + ms = merge_.mergestate(repo) + mf = util.matcher(repo.root, "", pats, [], [])[1] + + for f in ms: + if mf(f): + if opts.get("list"): + ui.write("%s %s\n" % (ms[f].upper(), f)) + elif opts.get("mark"): + ms.mark(f, "r") + elif opts.get("unmark"): + ms.mark(f, "u") + else: + wctx = repo.workingctx() + mctx = wctx.parents()[-1] + ms.resolve(f, wctx, mctx) + def revert(ui, repo, *pats, **opts): """restore individual files or dirs to an earlier state @@ -3196,6 +3226,12 @@ _('forcibly copy over an existing managed file')), ] + walkopts + dryrunopts, _('hg rename [OPTION]... SOURCE... DEST')), + "resolve": + (resolve, + [('l', 'list', None, _('list state of files needing merge')), + ('m', 'mark', None, _('mark files as resolved')), + ('u', 'unmark', None, _('unmark files as resolved'))], + ('hg resolve [OPTION] [FILES...]')), "revert": (revert, [('a', 'all', None, _('revert all changes when no arguments given')),
--- a/mercurial/hg.py Fri Apr 11 12:04:26 2008 +0200 +++ b/mercurial/hg.py Fri Apr 11 12:52:56 2008 -0500 @@ -271,15 +271,7 @@ stats = _merge.update(repo, node, False, False, None) _showstats(repo, stats) if stats[3]: - repo.ui.status(_("There are unresolved merges with" - " locally modified files.\n")) - if stats[1]: - repo.ui.status(_("You can finish the partial merge using:\n")) - else: - repo.ui.status(_("You can redo the full merge using:\n")) - # len(pl)==1, otherwise _merge.update() would have raised util.Abort: - repo.ui.status(_(" hg update %s\n hg update %s\n") - % (pl[0].rev(), repo.changectx(node).rev())) + repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) return stats[3] > 0 def clean(repo, node, show_stats=True): @@ -294,11 +286,7 @@ _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())) + repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) elif remind: repo.ui.status(_("(branch merge, don't forget to commit)\n")) return stats[3] > 0
--- a/mercurial/merge.py Fri Apr 11 12:04:26 2008 +0200 +++ b/mercurial/merge.py Fri Apr 11 12:52:56 2008 -0500 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -from node import nullid, nullrev, hex +from node import nullid, nullrev, hex, bin from i18n import _ import errno, util, os, filemerge, copies, shutil @@ -13,27 +13,49 @@ '''track 3-way merge state of individual files''' def __init__(self, repo): self._repo = repo + self._read() + def reset(self, node): self._state = {} - self._data = {} - def reset(self, node): self._local = node shutil.rmtree(self._repo.join("merge"), True) + def _read(self): + self._state = {} + try: + f = self._repo.opener("merge/state") + self._local = bin(f.readline()[:-1]) + for l in f: + bits = l[:-1].split("\0") + self._state[bits[0]] = bits[1:] + except IOError, err: + if err.errno != errno.ENOENT: + raise + def _write(self): + f = self._repo.opener("merge/state", "w") + f.write(hex(self._local) + "\n") + for d, v in self._state.items(): + f.write("\0".join([d] + v) + "\n") def add(self, fcl, fco, fca, fd, flags): hash = util.sha1(fcl.path()).hexdigest() self._repo.opener("merge/" + hash, "w").write(fcl.data()) - self._state[fd] = 'u' - self._data[fd] = (hash, fcl.path(), fca.path(), hex(fca.filenode()), - fco.path(), flags) + self._state[fd] = ['u', hash, fcl.path(), fca.path(), + hex(fca.filenode()), fco.path(), flags] + self._write() def __contains__(self, dfile): return dfile in self._state def __getitem__(self, dfile): - return self._state[dfile] + return self._state[dfile][0] + def __iter__(self): + l = self._state.keys() + l.sort() + for f in l: + yield f def mark(self, dfile, state): - self._state[dfile] = state + self._state[dfile][0] = state + self._write() def resolve(self, dfile, wctx, octx): if self[dfile] == 'r': return 0 - hash, lfile, afile, anode, ofile, flags = self._data[dfile] + state, hash, lfile, afile, anode, ofile, flags = self._state[dfile] f = self._repo.opener("merge/" + hash) self._repo.wwrite(dfile, f.read(), flags) fcd = wctx[dfile] @@ -41,7 +63,6 @@ fca = self._repo.filectx(afile, fileid=anode) r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca) if not r: - util.set_flags(self._repo.wjoin(dfile), flags) self.mark(dfile, 'r') return r
--- a/tests/test-add.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-add.out Fri Apr 11 12:52:56 2008 -0500 @@ -18,9 +18,7 @@ warning: conflicts during merge. merging a failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 2 - hg merge 1 +use 'hg resolve' to retry unresolved file merges M a ? a.orig % should fail
--- a/tests/test-conflict.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-conflict.out Fri Apr 11 12:52:56 2008 -0500 @@ -4,9 +4,7 @@ warning: conflicts during merge. merging a failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 2 - hg merge 1 +use 'hg resolve' to retry unresolved file merges e7fe8eb3e180+0d24b7662d3e+ tip <<<<<<< local something else
--- a/tests/test-convert-svn-sink.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-convert-svn-sink.out Fri Apr 11 12:52:56 2008 -0500 @@ -265,9 +265,7 @@ warning: conflicts during merge. merging b failed! 2 files updated, 0 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 2 - hg merge 4 +use 'hg resolve' to retry unresolved file merges assuming destination b-hg initializing svn repo 'b-hg' initializing svn wc 'b-hg-wc'
--- a/tests/test-debugcomplete.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-debugcomplete.out Fri Apr 11 12:52:56 2008 -0500 @@ -33,6 +33,7 @@ recover remove rename +resolve revert rollback root @@ -79,6 +80,7 @@ recover remove rename +resolve revert rollback root
--- a/tests/test-globalopts.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-globalopts.out Fri Apr 11 12:52:56 2008 -0500 @@ -183,6 +183,7 @@ recover roll back an interrupted transaction remove remove the specified files on the next commit rename rename files; equivalent of copy + remove + resolve resolve file merges from a branch merge or update revert restore individual files or dirs to an earlier state rollback roll back the last transaction root print the root (top) of the current working dir @@ -236,6 +237,7 @@ recover roll back an interrupted transaction remove remove the specified files on the next commit rename rename files; equivalent of copy + remove + resolve resolve file merges from a branch merge or update revert restore individual files or dirs to an earlier state rollback roll back the last transaction root print the root (top) of the current working dir
--- a/tests/test-help.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-help.out Fri Apr 11 12:52:56 2008 -0500 @@ -74,6 +74,7 @@ recover roll back an interrupted transaction remove remove the specified files on the next commit rename rename files; equivalent of copy + remove + resolve resolve file merges from a branch merge or update revert restore individual files or dirs to an earlier state rollback roll back the last transaction root print the root (top) of the current working dir @@ -123,6 +124,7 @@ recover roll back an interrupted transaction remove remove the specified files on the next commit rename rename files; equivalent of copy + remove + resolve resolve file merges from a branch merge or update revert restore individual files or dirs to an earlier state rollback roll back the last transaction root print the root (top) of the current working dir
--- a/tests/test-merge-local.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-merge-local.out Fri Apr 11 12:52:56 2008 -0500 @@ -21,10 +21,7 @@ merging zzz2_merge_bad merging zzz2_merge_bad failed! 3 files updated, 1 files merged, 2 files removed, 1 files unresolved -There are unresolved merges with locally modified files. -You can finish the partial merge using: - hg update 0 - hg update 1 +use 'hg resolve' to retry unresolved file merges 2 files updated, 0 files merged, 3 files removed, 0 files unresolved --- a/zzz1_merge_ok +++ b/zzz1_merge_ok @@ -42,10 +39,7 @@ warning: conflicts during merge. merging zzz2_merge_bad failed! 3 files updated, 1 files merged, 2 files removed, 1 files unresolved -There are unresolved merges with locally modified files. -You can finish the partial merge using: - hg update 0 - hg update 1 +use 'hg resolve' to retry unresolved file merges 2 files updated, 0 files merged, 3 files removed, 0 files unresolved --- a/zzz1_merge_ok +++ b/zzz1_merge_ok
--- a/tests/test-merge-revert2.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-merge-revert2.out Fri Apr 11 12:52:56 2008 -0500 @@ -13,10 +13,7 @@ warning: conflicts during merge. merging file1 failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -There are unresolved merges with locally modified files. -You can redo the full merge using: - hg update 0 - hg update 1 +use 'hg resolve' to retry unresolved file merges diff -r f248da0d4c3e file1 --- a/file1 +++ b/file1
--- a/tests/test-merge7.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-merge7.out Fri Apr 11 12:52:56 2008 -0500 @@ -11,9 +11,7 @@ warning: conflicts during merge. merging test.txt failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 1 - hg merge 2 +use 'hg resolve' to retry unresolved file merges pulling from ../test-a searching for changes adding changesets @@ -33,9 +31,7 @@ warning: conflicts during merge. merging test.txt failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 3 - hg merge 4 +use 'hg resolve' to retry unresolved file merges one <<<<<<< local two-point-five
--- a/tests/test-merge9 Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-merge9 Fri Apr 11 12:52:56 2008 -0500 @@ -23,9 +23,31 @@ # test with the rename on the remote side HGMERGE=false hg merge +hg resolve -l # test with the rename on the local side hg up -C 1 HGMERGE=false hg merge +echo % show unresolved +hg resolve -l + +echo % unmark baz +hg resolve -u baz + +echo % show +hg resolve -l + +echo % re-resolve baz +hg resolve baz + +echo % after +hg resolve -l + +echo % resolve all +hg resolve + +echo % after +hg resolve -l + true
--- a/tests/test-merge9.out Fri Apr 11 12:04:26 2008 +0200 +++ b/tests/test-merge9.out Fri Apr 11 12:52:56 2008 -0500 @@ -7,14 +7,31 @@ merging bar failed! merging foo and baz to baz 1 files updated, 1 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 2 - hg merge 1 +use 'hg resolve' to retry unresolved file merges +U bar +R baz 3 files updated, 0 files merged, 1 files removed, 0 files unresolved merging bar merging bar failed! merging baz and foo to baz 1 files updated, 1 files merged, 0 files removed, 1 files unresolved -There are unresolved merges, you can redo the full merge using: - hg update -C 1 - hg merge 2 +use 'hg resolve' to retry unresolved file merges +% show unresolved +U bar +R baz +% unmark baz +% show +U bar +U baz +% re-resolve baz +merging baz and foo to baz +% after +U bar +R baz +% resolve all +merging bar +warning: conflicts during merge. +merging bar failed! +% after +U bar +R baz