D3757: rebase: add dry-run functionality

khanchi97 (Sushil khanchi) phabricator at mercurial-scm.org
Sat Jun 16 13:47:20 UTC 2018


khanchi97 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  For now, it just notify that if we will hit a conflict or not, but
  we can improve this like making it a --confirm flag or by showing the
  graph that would result when we will run the command without --dry-run

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-inmemory.t

CHANGE DETAILS

diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t
--- a/tests/test-rebase-inmemory.t
+++ b/tests/test-rebase-inmemory.t
@@ -155,4 +155,169 @@
   |/
   o  0: b173517d0057 'a'
   
+Test dry-run rebasing
+  $ hg init skrepo
+  $ cd skrepo
+  $ echo a>a
+  $ hg ci -Aqma
+  $ echo b>b
+  $ hg ci -Aqmb
+  $ echo c>c
+  $ hg ci -Aqmc
+  $ echo d>d
+  $ hg ci -Aqmd
+  $ echo e>e
+  $ hg ci -Aqme
 
+  $ hg up 1 -q
+  $ echo f>f
+  $ hg ci -Amf
+  adding f
+  created new head
+  $ echo g>g
+  $ hg ci -Aqmg
+  $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
+  @  6:baf10c5166d4 test
+  |  g
+  |
+  o  5:6343ca3eff20 test
+  |  f
+  |
+  | o  4:e860deea161a test
+  | |  e
+  | |
+  | o  3:055a42cdd887 test
+  | |  d
+  | |
+  | o  2:177f92b77385 test
+  |/   c
+  |
+  o  1:d2ae7f538514 test
+  |  b
+  |
+  o  0:cb9a9f314b8b test
+     a
+  
+Make sure it throws error while passing --continue or --abort with --dry-run
+  $ hg rebase -s 2 -d 6 -n --continue
+  abort: cannot specify both --dry-run and --continue
+  [255]
+  $ hg rebase -s 2 -d 6 -n --abort
+  abort: cannot specify both --dry-run and --abort
+  [255]
+
+Check dryrun gives correct results when there is no conflict in rebasing
+  $ hg rebase -s 2 -d 6 -n
+  rebasing 2:177f92b77385 "c"
+  rebasing 3:055a42cdd887 "d"
+  rebasing 4:e860deea161a "e"
+  There will be no conflict, you can rebase
+  rebase aborted
+
+  $ hg diff
+  $ hg status
+
+  $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
+  @  6:baf10c5166d4 test
+  |  g
+  |
+  o  5:6343ca3eff20 test
+  |  f
+  |
+  | o  4:e860deea161a test
+  | |  e
+  | |
+  | o  3:055a42cdd887 test
+  | |  d
+  | |
+  | o  2:177f92b77385 test
+  |/   c
+  |
+  o  1:d2ae7f538514 test
+  |  b
+  |
+  o  0:cb9a9f314b8b test
+     a
+  
+Check dryrun working with --collapse when there is no conflict
+  $ hg rebase -s 2 -d 6 -n --collapse
+  rebasing 2:177f92b77385 "c"
+  rebasing 3:055a42cdd887 "d"
+  rebasing 4:e860deea161a "e"
+  There will be no conflict, you can rebase
+  rebase aborted
+
+Check dryrun gives correct results when there is conflict in rebasing
+Make a conflict:
+  $ hg up 6 -q
+  $ echo conflict>e
+  $ hg ci -Aqm "conflict with e"
+  $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
+  @  7:d2c195b28050 test
+  |  conflict with e
+  |
+  o  6:baf10c5166d4 test
+  |  g
+  |
+  o  5:6343ca3eff20 test
+  |  f
+  |
+  | o  4:e860deea161a test
+  | |  e
+  | |
+  | o  3:055a42cdd887 test
+  | |  d
+  | |
+  | o  2:177f92b77385 test
+  |/   c
+  |
+  o  1:d2ae7f538514 test
+  |  b
+  |
+  o  0:cb9a9f314b8b test
+     a
+  
+  $ hg rebase -s 2 -d 7 -n
+  rebasing 2:177f92b77385 "c"
+  rebasing 3:055a42cdd887 "d"
+  rebasing 4:e860deea161a "e"
+  merging e
+  transaction abort!
+  rollback completed
+  Hit a merge conflict
+  rebase aborted
+  $ hg diff
+  $ hg status
+  $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
+  @  7:d2c195b28050 test
+  |  conflict with e
+  |
+  o  6:baf10c5166d4 test
+  |  g
+  |
+  o  5:6343ca3eff20 test
+  |  f
+  |
+  | o  4:e860deea161a test
+  | |  e
+  | |
+  | o  3:055a42cdd887 test
+  | |  d
+  | |
+  | o  2:177f92b77385 test
+  |/   c
+  |
+  o  1:d2ae7f538514 test
+  |  b
+  |
+  o  0:cb9a9f314b8b test
+     a
+  
+Check dryrun working with --collapse when there is conflicts
+  $ hg rebase -s 2 -d 7 -n --collapse
+  rebasing 2:177f92b77385 "c"
+  rebasing 3:055a42cdd887 "d"
+  rebasing 4:e860deea161a "e"
+  merging e
+  Hit a merge conflict
+  rebase aborted
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -673,8 +673,7 @@
     ('a', 'abort', False, _('abort an interrupted rebase')),
     ('', 'auto-orphans', '', _('automatically rebase orphan revisions '
                                'in the specified revset (EXPERIMENTAL)')),
-     ] +
-    cmdutil.formatteropts,
+     ] + cmdutil.dryrunopts + cmdutil.formatteropts,
     _('[-s REV | -b REV] [-d REV] [OPTION]'))
 def rebase(ui, repo, **opts):
     """move changeset (and descendants) to a different branch
@@ -798,6 +797,15 @@
 
     """
     inmemory = ui.configbool('rebase', 'experimental.inmemory')
+    dryrun = opts.get(r'dry_run')
+    if dryrun:
+        if (opts.get(r'abort')):
+                raise error.Abort(_('cannot specify both --dry-run '
+                                    'and --abort'))
+        if (opts.get(r'continue')):
+                raise error.Abort(_('cannot specify both --dry-run '
+                                    'and --continue'))
+
     if (opts.get(r'continue') or opts.get(r'abort') or
         repo.currenttransaction() is not None):
         # in-memory rebase is not compatible with resuming rebases.
@@ -814,22 +822,35 @@
         opts[r'rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)]
         opts[r'dest'] = '_destautoorphanrebase(SRC)'
 
-    if inmemory:
+    if dryrun:
         try:
-            # in-memory merge doesn't support conflicts, so if we hit any, abort
-            # and re-run as an on-disk merge.
             overrides = {('rebase', 'singletransaction'): True}
             with ui.configoverride(overrides, 'rebase'):
-                return _origrebase(ui, repo, inmemory=inmemory, **opts)
+                _origrebase(ui, repo, inmemory=True, dryrun=dryrun, **opts)
         except error.InMemoryMergeConflictsError:
-            ui.warn(_('hit merge conflicts; re-running rebase without in-memory'
-                      ' merge\n'))
+            ui.status(_('Hit a merge conflict\n'))
+        else:
+            ui.status(_('There will be no conflict, you can rebase\n'))
+        finally:
             _origrebase(ui, repo, **{r'abort': True})
-            return _origrebase(ui, repo, inmemory=False, **opts)
+
     else:
-        return _origrebase(ui, repo, **opts)
+        if inmemory:
+            try:
+                # in-memory merge doesn't support conflicts, so if we hit any, abort
+                # and re-run as an on-disk merge.
+                overrides = {('rebase', 'singletransaction'): True}
+                with ui.configoverride(overrides, 'rebase'):
+                    return _origrebase(ui, repo, inmemory=inmemory, **opts)
+            except error.InMemoryMergeConflictsError:
+                ui.warn(_('hit merge conflicts; re-running rebase without in-memory'
+                          ' merge\n'))
+                _origrebase(ui, repo, **{r'abort': True})
+                return _origrebase(ui, repo, inmemory=False, **opts)
+        else:
+            return _origrebase(ui, repo, **opts)
 
-def _origrebase(ui, repo, inmemory=False, **opts):
+def _origrebase(ui, repo, inmemory=False, dryrun=None, **opts):
     opts = pycompat.byteskwargs(opts)
     rbsrt = rebaseruntime(repo, ui, inmemory, opts)
 
@@ -902,7 +923,8 @@
                 dsguard = dirstateguard.dirstateguard(repo, 'rebase')
             with util.acceptintervention(dsguard):
                 rbsrt._performrebase(tr)
-                rbsrt._finishrebase()
+                if not dryrun:
+                    rbsrt._finishrebase()
 
 def _definedestmap(ui, repo, inmemory, destf=None, srcf=None, basef=None,
                    revf=None, destspace=None):



To: khanchi97, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list