fix: add --all flag to fix non-public non-obsolete revisions
authorDanny Hooper <hooper@google.com>
Fri, 30 Mar 2018 16:40:25 -0700
changeset 37595 e2506748b47f
parent 37594 b1f62cd39b5c
child 37596 8c121a9837ca
fix: add --all flag to fix non-public non-obsolete revisions Differential Revision: https://phab.mercurial-scm.org/D3213
hgext/fix.py
tests/test-fix-topology.t
tests/test-fix.t
--- a/hgext/fix.py	Sat Mar 24 14:28:24 2018 -0400
+++ b/hgext/fix.py	Fri Mar 30 16:40:25 2018 -0700
@@ -95,7 +95,8 @@
 configitem('fix', 'maxfilesize', default='2MB')
 
 @command('fix',
-    [('', 'base', [], _('revisions to diff against (overrides automatic '
+    [('', 'all', False, _('fix all non-public non-obsolete revisions')),
+     ('', 'base', [], _('revisions to diff against (overrides automatic '
                         'selection, and applies to every revision being '
                         'fixed)'), _('REV')),
      ('r', 'rev', [], _('revisions to fix'), _('REV')),
@@ -125,6 +126,11 @@
     revisions are not forgotten in later ones. The --base flag can be used to
     override this default behavior, though it is not usually desirable to do so.
     """
+    if opts['all']:
+        if opts['rev']:
+            raise error.Abort(_('cannot specify both "--rev" and "--all"'))
+        opts['rev'] = ['not public() and not obsolete()']
+        opts['working_dir'] = True
     with repo.wlock(), repo.lock():
         revstofix = getrevstofix(ui, repo, opts)
         basectxs = getbasectxs(repo, opts, revstofix)
--- a/tests/test-fix-topology.t	Sat Mar 24 14:28:24 2018 -0400
+++ b/tests/test-fix-topology.t	Fri Mar 30 16:40:25 2018 -0700
@@ -266,3 +266,152 @@
 
   $ cd ..
 
+The --all flag should fix anything that wouldn't cause a problem if you fixed
+it, including the working copy. Obsolete revisions are not fixed because that
+could cause divergence. Public revisions would cause an abort because they are
+immutable. We can fix orphans because their successors are still just orphans
+of the original obsolete parent. When obsolesence is off, we're just fixing and
+replacing anything that isn't public.
+
+  $ hg init fixall
+  $ cd fixall
+
+#if obsstore-on
+  $ printf "one\n" > foo.whole
+  $ hg commit -Aqm "first"
+  $ hg phase --public
+  $ hg tag --local root
+  $ printf "two\n" > foo.whole
+  $ hg commit -m "second"
+  $ printf "three\n" > foo.whole
+  $ hg commit -m "third" --secret
+  $ hg tag --local secret
+  $ hg checkout root
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "four\n" > foo.whole
+  $ hg commit -m "fourth"
+  created new head
+  $ printf "five\n" > foo.whole
+  $ hg commit -m "fifth"
+  $ hg tag --local replaced
+  $ printf "six\n" > foo.whole
+  $ hg commit -m "sixth"
+  $ hg checkout replaced
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "seven\n" > foo.whole
+  $ hg commit --amend
+  1 new orphan changesets
+  $ hg checkout secret
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "uncommitted\n" > foo.whole
+
+  $ hg log --graph --template '{rev} {desc} {phase}\n'
+  o  6 fifth draft
+  |
+  | *  5 sixth draft
+  | |
+  | x  4 fifth draft
+  |/
+  o  3 fourth draft
+  |
+  | @  2 third secret
+  | |
+  | o  1 second draft
+  |/
+  o  0 first public
+  
+
+  $ hg fix --all
+  1 new orphan changesets
+
+  $ hg log --graph --template '{rev} {desc}\n' -r 'sort(all(), topo)' --hidden
+  o  11 fifth
+  |
+  o  9 fourth
+  |
+  | @  8 third
+  | |
+  | o  7 second
+  |/
+  | *  10 sixth
+  | |
+  | | x  5 sixth
+  | |/
+  | x  4 fifth
+  | |
+  | | x  6 fifth
+  | |/
+  | x  3 fourth
+  |/
+  | x  2 third
+  | |
+  | x  1 second
+  |/
+  o  0 first
+  
+
+  $ hg cat -r 7 foo.whole
+  TWO
+  $ hg cat -r 8 foo.whole
+  THREE
+  $ hg cat -r 9 foo.whole
+  FOUR
+  $ hg cat -r 10 foo.whole
+  SIX
+  $ hg cat -r 11 foo.whole
+  SEVEN
+  $ cat foo.whole
+  UNCOMMITTED
+#else
+  $ printf "one\n" > foo.whole
+  $ hg commit -Aqm "first"
+  $ hg phase --public
+  $ hg tag --local root
+  $ printf "two\n" > foo.whole
+  $ hg commit -m "second"
+  $ printf "three\n" > foo.whole
+  $ hg commit -m "third" --secret
+  $ hg tag --local secret
+  $ hg checkout root
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "four\n" > foo.whole
+  $ hg commit -m "fourth"
+  created new head
+  $ printf "uncommitted\n" > foo.whole
+
+  $ hg log --graph --template '{rev} {desc} {phase}\n'
+  @  3 fourth draft
+  |
+  | o  2 third secret
+  | |
+  | o  1 second draft
+  |/
+  o  0 first public
+  
+
+  $ hg fix --all
+  saved backup bundle to * (glob)
+
+  $ hg log --graph --template '{rev} {desc} {phase}\n'
+  @  3 fourth draft
+  |
+  | o  2 third secret
+  | |
+  | o  1 second draft
+  |/
+  o  0 first public
+  
+  $ hg cat -r 0 foo.whole
+  one
+  $ hg cat -r 1 foo.whole
+  TWO
+  $ hg cat -r 2 foo.whole
+  THREE
+  $ hg cat -r 3 foo.whole
+  FOUR
+  $ cat foo.whole
+  UNCOMMITTED
+#endif
+
+  $ cd ..
+
--- a/tests/test-fix.t	Sat Mar 24 14:28:24 2018 -0400
+++ b/tests/test-fix.t	Fri Mar 30 16:40:25 2018 -0700
@@ -104,6 +104,7 @@
   
   options ([+] can be repeated):
   
+      --all          fix all non-public non-obsolete revisions
       --base REV [+] revisions to diff against (overrides automatic selection,
                      and applies to every revision being fixed)
    -r --rev REV [+]  revisions to fix