Patchwork D6737: shelve: add --unresolved flag to shelve mergestate with unresolved files

login
register
mail settings
Submitter phabricator
Date Aug. 17, 2019, 8:41 p.m.
Message ID <differential-rev-PHID-DREV-nfkzedmfrvi3h4y7uc25-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/41340/
State New
Headers show

Comments

phabricator - Aug. 17, 2019, 8:41 p.m.
navaneeth.suresh created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Until now, `shelve` used to abort on trying to `shelve` a mergestate.
  This patch adds an `--unresolved` flag to `shelve` and use the changeset
  extras to store the mergestate.
  
  After shelving, and the working directory is updated to `p1()`.
  
  `hg shelve` will abort when:
  
  1. No merge is active on calling with `--unresolved`.
  2. No unresolved files found in active merge on calling with `--unresolved`.
  3. Merge is active on calling without `--unresolved`.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D6737

AFFECTED FILES
  mercurial/commands.py
  mercurial/shelve.py
  tests/test-completion.t
  tests/test-shelve-unresolved.t
  tests/test-shelve.t

CHANGE DETAILS




To: navaneeth.suresh, #hg-reviewers
Cc: mercurial-devel

Patch

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
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 <<EOF
+  > [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 <<EOF
+  > 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-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/mercurial/shelve.py b/mercurial/shelve.py
--- a/mercurial/shelve.py
+++ b/mercurial/shelve.py
@@ -459,14 +459,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]
@@ -491,6 +502,9 @@ 
         name = getshelvename(repo, parent, opts)
         activebookmark = _backupactivebookmark(repo)
         extra = {'internal': 'shelve'}
+        if unresolved:
+            extra['unresolved-merge'] = True
+            _storeunresolvedmerge(ui, repo, name, extra)
         if includeunknown:
             _includeunknownfiles(repo, pats, opts, extra)
 
@@ -602,6 +616,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/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)