Patchwork D3887: rebase: support "history-editing-backup" config option

login
register
mail settings
Submitter phabricator
Date Aug. 2, 2018, 1:51 p.m.
Message ID <ac60fe9fc3637dcb3ce27843d22389fc@localhost.localdomain>
Download mbox | patch
Permalink /patch/33106/
State Not Applicable
Headers show

Comments

phabricator - Aug. 2, 2018, 1:51 p.m.
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG7de767e15f52: rebase: support &quot;history-editing-backup&quot; config option (authored by khanchi97, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3887?vs=9639&id=9786

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

AFFECTED FILES
  hgext/rebase.py
  mercurial/repair.py
  mercurial/scmutil.py
  tests/test-rebase-backup.t

CHANGE DETAILS




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

Patch

diff --git a/tests/test-rebase-backup.t b/tests/test-rebase-backup.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-backup.t
@@ -0,0 +1,150 @@ 
+  $ cat << EOF >> $HGRCPATH
+  > [extensions]
+  > rebase=
+  > EOF
+
+==========================================
+Test history-editing-backup config option |
+==========================================
+Test with Pre-obsmarker rebase:
+1) When config option is not set:
+  $ hg init repo1
+  $ cd repo1
+  $ echo a>a
+  $ hg ci -qAma
+  $ echo b>b
+  $ hg ci -qAmb
+  $ echo c>c
+  $ hg ci -qAmc
+  $ hg up 0 -q
+  $ echo d>d
+  $ hg ci -qAmd
+  $ echo e>e
+  $ hg ci -qAme
+  $ hg log -GT "{rev}: {firstline(desc)}\n"
+  @  4: e
+  |
+  o  3: d
+  |
+  | o  2: c
+  | |
+  | o  1: b
+  |/
+  o  0: a
+  
+  $ hg rebase -s 1 -d .
+  rebasing 1:d2ae7f538514 "b"
+  rebasing 2:177f92b77385 "c"
+  saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/d2ae7f538514-c7ed7a78-rebase.hg
+  $ hg log -GT "{rev}: {firstline(desc)}\n"
+  o  4: c
+  |
+  o  3: b
+  |
+  @  2: e
+  |
+  o  1: d
+  |
+  o  0: a
+  
+
+2) When config option is set:
+  $ cat << EOF >> $HGRCPATH
+  > [ui]
+  > history-editing-backup = False
+  > EOF
+
+  $ echo f>f
+  $ hg ci -Aqmf
+  $ echo g>g
+  $ hg ci -Aqmg
+  $ hg log -GT "{rev}: {firstline(desc)}\n"
+  @  6: g
+  |
+  o  5: f
+  |
+  | o  4: c
+  | |
+  | o  3: b
+  |/
+  o  2: e
+  |
+  o  1: d
+  |
+  o  0: a
+  
+  $ hg rebase -s 3 -d .
+  rebasing 3:05bff2a95b12 "b"
+  rebasing 4:1762bde4404d "c"
+
+  $ hg log -GT "{rev}: {firstline(desc)}\n"
+  o  6: c
+  |
+  o  5: b
+  |
+  @  4: g
+  |
+  o  3: f
+  |
+  o  2: e
+  |
+  o  1: d
+  |
+  o  0: a
+  
+Test when rebased revisions are stripped during abort:
+======================================================
+
+  $ echo conflict > c
+  $ hg ci -Am "conflict with c"
+  adding c
+  created new head
+  $ hg log -GT "{rev}: {firstline(desc)}\n"
+  @  7: conflict with c
+  |
+  | o  6: c
+  | |
+  | o  5: b
+  |/
+  o  4: g
+  |
+  o  3: f
+  |
+  o  2: e
+  |
+  o  1: d
+  |
+  o  0: a
+  
+When history-editing-backup = True:
+  $ cat << EOF >> $HGRCPATH
+  > [ui]
+  > history-editing-backup = True
+  > EOF
+  $ hg rebase -s 5 -d .
+  rebasing 5:1f8148a544ee "b"
+  rebasing 6:f8bc7d28e573 "c"
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [1]
+  $ hg rebase --abort
+  saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/818c1a43c916-2b644d96-backup.hg
+  rebase aborted
+
+When history-editing-backup = False:
+  $ cat << EOF >> $HGRCPATH
+  > [ui]
+  > history-editing-backup = False
+  > EOF
+  $ hg rebase -s 5 -d .
+  rebasing 5:1f8148a544ee "b"
+  rebasing 6:f8bc7d28e573 "c"
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [1]
+  $ hg rebase --abort
+  rebase aborted
+  $ cd ..
+
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -780,7 +780,7 @@ 
         return self._revcontains(self._torev(node))
 
 def cleanupnodes(repo, replacements, operation, moves=None, metadata=None,
-                 fixphase=False, targetphase=None):
+                 fixphase=False, targetphase=None, backup=True):
     """do common cleanups when old nodes are replaced by new nodes
 
     That includes writing obsmarkers or stripping nodes, and moving bookmarks.
@@ -905,7 +905,8 @@ 
             from . import repair # avoid import cycle
             tostrip = list(replacements)
             if tostrip:
-                repair.delayedstrip(repo.ui, repo, tostrip, operation)
+                repair.delayedstrip(repo.ui, repo, tostrip, operation,
+                                    backup=backup)
 
 def addremove(repo, matcher, prefix, opts=None):
     if opts is None:
diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -298,24 +298,24 @@ 
         if roots:
             strip(self.ui, self.repo, roots, self.backup, self.topic)
 
-def delayedstrip(ui, repo, nodelist, topic=None):
+def delayedstrip(ui, repo, nodelist, topic=None, backup=True):
     """like strip, but works inside transaction and won't strip irreverent revs
 
     nodelist must explicitly contain all descendants. Otherwise a warning will
     be printed that some nodes are not stripped.
 
-    Always do a backup. The last non-None "topic" will be used as the backup
-    topic name. The default backup topic name is "backup".
+    Will do a backup if `backup` is True. The last non-None "topic" will be
+    used as the backup topic name. The default backup topic name is "backup".
     """
     tr = repo.currenttransaction()
     if not tr:
         nodes = safestriproots(ui, repo, nodelist)
-        return strip(ui, repo, nodes, True, topic)
+        return strip(ui, repo, nodes, backup=backup, topic=topic)
     # transaction postclose callbacks are called in alphabet order.
     # use '\xff' as prefix so we are likely to be called last.
     callback = tr.getpostclose('\xffstrip')
     if callback is None:
-        callback = stripcallback(ui, repo, True, topic)
+        callback = stripcallback(ui, repo, backup=backup, topic=topic)
         tr.addpostclose('\xffstrip', callback)
     if topic:
         callback.topic = topic
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -585,7 +585,11 @@ 
             # case and realize that the commit was in progress.
             self.storestatus()
 
-    def _finishrebase(self):
+    def _finishrebase(self, backup=True):
+        """
+        backup:   if False, no backup will be stored when stripping rebased
+                  revisions
+        """
         repo, ui, opts = self.repo, self.ui, self.opts
         fm = ui.formatter('rebase', opts)
         fm.startitem()
@@ -632,7 +636,7 @@ 
         if self.collapsef and not self.keepf:
             collapsedas = newnode
         clearrebased(ui, repo, self.destmap, self.state, self.skipped,
-                     collapsedas, self.keepf, fm=fm)
+                     collapsedas, self.keepf, fm=fm, backup=backup)
 
         clearstatus(repo)
         clearcollapsemsg(repo)
@@ -829,6 +833,8 @@ 
         userrevs = list(repo.revs(opts.get('auto_orphans')))
         opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)]
         opts['dest'] = '_destautoorphanrebase(SRC)'
+    backup = ui.configbool('ui', 'history-editing-backup')
+    opts['backup'] = backup
 
     if dryrun:
         return _dryrunrebase(ui, repo, opts)
@@ -850,6 +856,7 @@ 
 def _dryrunrebase(ui, repo, opts):
     rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts)
     confirm = opts.get('confirm')
+    backup = opts.get('backup')
     if confirm:
         ui.status(_('starting in-memory rebase\n'))
     else:
@@ -871,7 +878,7 @@ 
                 if not ui.promptchoice(_(b'apply changes (yn)?'
                                          b'$$ &Yes $$ &No')):
                     # finish unfinished rebase
-                    rbsrt._finishrebase()
+                    rbsrt._finishrebase(backup=backup)
                 else:
                     rbsrt._prepareabortorcontinue(isabort=True, backup=False,
                                                   suppwarns=True)
@@ -902,6 +909,7 @@ 
         destspace = opts.get('_destspace')
         contf = opts.get('continue')
         abortf = opts.get('abort')
+        backup = opts.get('backup')
         if opts.get('interactive'):
             try:
                 if extensions.find('histedit'):
@@ -932,7 +940,7 @@ 
                 ms = mergemod.mergestate.read(repo)
                 mergeutil.checkunresolved(ms)
 
-            retcode = rbsrt._prepareabortorcontinue(abortf)
+            retcode = rbsrt._prepareabortorcontinue(abortf, backup=backup)
             if retcode is not None:
                 return retcode
         else:
@@ -961,7 +969,7 @@ 
             with util.acceptintervention(dsguard):
                 rbsrt._performrebase(tr)
                 if not leaveunfinished:
-                    rbsrt._finishrebase()
+                    rbsrt._finishrebase(backup=backup)
 
 def _definedestmap(ui, repo, inmemory, destf=None, srcf=None, basef=None,
                    revf=None, destspace=None):
@@ -1728,14 +1736,17 @@ 
     return originalwd, destmap, state
 
 def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None,
-                 keepf=False, fm=None):
+                 keepf=False, fm=None, backup=True):
     """dispose of rebased revision at the end of the rebase
 
     If `collapsedas` is not None, the rebase was a collapse whose result if the
     `collapsedas` node.
 
     If `keepf` is not True, the rebase has --keep set and no nodes should be
     removed (but bookmarks still need to be moved).
+
+    If `backup` is False, no backup will be stored when stripping rebased
+    revisions.
     """
     tonode = repo.changelog.node
     replacements = {}
@@ -1751,7 +1762,7 @@ 
                 else:
                     succs = (newnode,)
                 replacements[oldnode] = succs
-    scmutil.cleanupnodes(repo, replacements, 'rebase', moves)
+    scmutil.cleanupnodes(repo, replacements, 'rebase', moves, backup=backup)
     if fm:
         hf = fm.hexfunc
         fl = fm.formatlist