diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -5361,7 +5361,9 @@ _('interactive mode')), ('', 'stat', None, _('output diffstat-style summary of changes (provide the names of ' - 'the shelved changes as positional arguments)') + 'the shelved changes as positional arguments)')), + ('', 'unresolved', None, + _('shelve mergestate with unresolved files') )] + cmdutil.walkopts, _('hg shelve [OPTION]... [FILE]...'), helpcategory=command.CATEGORY_WORKING_DIRECTORY) diff --git a/mercurial/shelve.py b/mercurial/shelve.py --- a/mercurial/shelve.py +++ b/mercurial/shelve.py @@ -454,14 +454,25 @@ def createcmd(ui, repo, pats, opts): """subcommand that creates a new shelve""" with repo.wlock(): - cmdutil.checkunfinished(repo) + cmdutil.checkunfinished(repo, skipmerge=True) return _docreatecmd(ui, repo, pats, opts) def _docreatecmd(ui, repo, pats, opts): wctx = repo[None] parents = wctx.parents() + unresolved = opts.get('unresolved') parent = parents[0] origbranch = wctx.branch() + ms = merge.mergestate.read(repo) + if unresolved: + if not ms.active(): + raise error.Abort(_('no active mergestate found')) + elif not list(ms.unresolved()): + raise error.Abort(_('no unresolved ' + 'files found in the mergestate')) + elif ms.active(): + raise error.Abort(_('mergestate found\n' + 'try with --unresolved to shelve conflicts')) if parent.node() != nodemod.nullid: desc = "changes to: %s" % parent.description().split('\n', 1)[0] @@ -486,6 +497,10 @@ name = getshelvename(repo, parent, opts) activebookmark = _backupactivebookmark(repo) extra = {'internal': 'shelve'} + if unresolved: + extra['unresolved-merge'] = True + _storeunresolvedmerge(ui, repo, name, extra) + ms.reset() if includeunknown: _includeunknownfiles(repo, pats, opts, extra) @@ -597,6 +612,7 @@ sname = util.split(name)[1] if pats and sname not in pats: continue + #TODO: add method to distinguish unresolved shelves from others. ui.write(sname, label=namelabel) namelabel = 'shelve.name' if ui.quiet: diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -347,7 +347,7 @@ rollback: dry-run, force root: template serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos - shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude + shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, unresolved, include, exclude status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template summary: remote tag: force, local, rev, remove, edit, message, date, user diff --git a/tests/test-shelve-unresolved.t b/tests/test-shelve-unresolved.t new file mode 100644 --- /dev/null +++ b/tests/test-shelve-unresolved.t @@ -0,0 +1,173 @@ + $ addunresolvedmerge() { + > echo A >> $1 + > echo A >> $2 + > hg ci -m A + > echo B >> $1 + > echo B >> $2 + > hg ci -m B + > hg up $3 + > echo C >> $1 + > echo C >> $2 + > hg ci -m C + > hg merge -r $(($3+1)) + > } + +Test shelve with unresolved mergestate + + $ cat >> $HGRCPATH < [extensions] + > shelve = + > EOF + + $ hg init shelve-unresolved + $ cd shelve-unresolved + $ echo A >> file1 + $ echo A >> file2 + $ hg ci -Am A + adding file1 + adding file2 + $ echo foo >> bar + $ hg add bar + +-- should abort on absence of mergestate + $ hg shelve --unresolved + abort: no active mergestate found + [255] + + $ hg forget bar + $ echo B >> file1 + $ echo B >> file2 + $ hg ci -m B + $ hg up 0 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo C >> file1 + $ echo C >> file2 + $ hg ci -m C + created new head + $ hg merge + merging file1 + merging file2 + warning: conflicts while merging file1! (edit, then use 'hg resolve --mark') + warning: conflicts while merging file2! (edit, then use 'hg resolve --mark') + 0 files updated, 0 files merged, 0 files removed, 2 files unresolved + use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon + [1] + +-- let's partially solve the conflicts + $ cat > file1 < A + > B + > C + > EOF + $ hg resolve -m file1 + +-- mark file2 as resolved to check abort + $ hg resolve -m file2 + (no more unresolved files) + $ hg log -G + @ changeset: 2:69004294ad57 + | tag: tip + | parent: 0:c32ef6121744 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: C + | + | @ changeset: 1:fd9a4049234b + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: B + | + o changeset: 0:c32ef6121744 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: A + + $ cat file1 + A + B + C + $ hg diff + diff -r 69004294ad57 file1 + --- a/file1 Thu Jan 01 00:00:00 1970 +0000 + +++ b/file1 Thu Jan 01 00:00:00 1970 +0000 + @@ -1,2 +1,3 @@ + A + +B + C + diff -r 69004294ad57 file2 + --- a/file2 Thu Jan 01 00:00:00 1970 +0000 + +++ b/file2 Thu Jan 01 00:00:00 1970 +0000 + @@ -1,2 +1,6 @@ + A + +<<<<<<< working copy: 69004294ad57 - test: C + C + +======= + +B + +>>>>>>> merge rev: fd9a4049234b - test: B + +-- should abort on absence of conflicts + $ hg shelve + abort: mergestate found + try with --unresolved to shelve conflicts + [255] + $ hg shelve --unresolved + abort: no unresolved files found in the mergestate + [255] + $ hg resolve -u file2 + $ hg resolve -l + R file1 + U file2 + +-- should suggest --unresolved on shelving with mergestate + $ hg shelve + abort: mergestate found + try with --unresolved to shelve conflicts + [255] + + $ hg shelve --unresolved + shelved as default + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ cat file1 + A + C + $ hg log -G + @ changeset: 2:69004294ad57 + | tag: tip + | parent: 0:c32ef6121744 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: C + | + | o changeset: 1:fd9a4049234b + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: B + | + o changeset: 0:c32ef6121744 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: A + + $ hg shelve --list + default (1s ago) changes to: C + $ hg shelve --patch + default (1s ago) changes to: C + + diff --git a/file1 b/file1 + --- a/file1 + +++ b/file1 + @@ -1,2 +1,3 @@ + A + +B + C + diff --git a/file2 b/file2 + --- a/file2 + +++ b/file2 + @@ -1,2 +1,6 @@ + A + +<<<<<<< working copy: 69004294ad57 - test: C + C + +======= + +B + +>>>>>>> merge rev: fd9a4049234b - test: B diff --git a/tests/test-shelve.t b/tests/test-shelve.t --- a/tests/test-shelve.t +++ b/tests/test-shelve.t @@ -83,6 +83,7 @@ --stat output diffstat-style summary of changes (provide the names of the shelved changes as positional arguments) + --unresolved shelve mergestate with unresolved files -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns --mq operate on patch repository