changeset 42542:2e1d9414ff71

commit: add --force-close-branch flag to close a non-head changeset While closing branch from a changeset which is not a branch head current implementation abort this action in every case but, there can be the situations where the changeset is not a local head but could be a remote head. This patch adds the functionality to bypass the "abort: can only close branch heads" by introducing --force-close-branch flag. Test case changes demonstrate the new functionality added. Differential Revision: https://phab.mercurial-scm.org/D6490
author Sushil khanchi <sushilkhanchi97@gmail.com>
date Sat, 18 May 2019 15:44:23 +0530
parents 3de4f17f4824
children abd902a85040
files mercurial/commands.py tests/test-branches.t tests/test-completion.t
diffstat 3 files changed, 25 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Fri Jun 28 21:31:34 2019 +0530
+++ b/mercurial/commands.py	Sat May 18 15:44:23 2019 +0530
@@ -1584,6 +1584,8 @@
     ('', 'amend', None, _('amend the parent of the working directory')),
     ('s', 'secret', None, _('use the secret phase for committing')),
     ('e', 'edit', None, _('invoke editor on commit messages')),
+    ('', 'force-close-branch', None,
+     _('forcibly close branch from a non-head changeset (ADVANCED)')),
     ('i', 'interactive', None, _('use interactive mode')),
     ] + walkopts + commitopts + commitopts2 + subrepoopts,
     _('[OPTION]... [FILE]...'),
@@ -1671,7 +1673,7 @@
     bheads = repo.branchheads(branch)
 
     extra = {}
-    if opts.get('close_branch'):
+    if opts.get('close_branch') or opts.get('force_close_branch'):
         extra['close'] = '1'
 
         if repo['.'].closesbranch():
@@ -1679,8 +1681,11 @@
                                 ' head'))
         elif not bheads:
             raise error.Abort(_('branch "%s" has no heads to close') % branch)
-        elif branch == repo['.'].branch() and repo['.'].node() not in bheads:
-            raise error.Abort(_('can only close branch heads'))
+        elif (branch == repo['.'].branch() and repo['.'].node() not in bheads
+              and not opts.get('force_close_branch')):
+            hint = _('use --force-close-branch to close branch from a non-head'
+                     ' changeset')
+            raise error.Abort(_('can only close branch heads'), hint=hint)
         elif opts.get('amend'):
             if (repo['.'].p1().branch() != branch and
                 repo['.'].p2().branch() != branch):
--- a/tests/test-branches.t	Fri Jun 28 21:31:34 2019 +0530
+++ b/tests/test-branches.t	Sat May 18 15:44:23 2019 +0530
@@ -958,6 +958,7 @@
 it should abort:
   $ hg ci -m "closing branch" --close-branch
   abort: can only close branch heads
+  (use --force-close-branch to close branch from a non-head changeset)
   [255]
 
   $ hg up 0
@@ -972,3 +973,18 @@
   @  0: 9092f1db7931 added a
      	default
   
+Test --force-close-branch to close a branch from a non-head changeset:
+---------------------------------------------------------------------
+
+  $ hg show stack --config extensions.show=
+    o  1553 added c
+    o  5f6d added b
+    @  9092 added a
+
+  $ hg ci -m "branch closed" --close-branch
+  abort: can only close branch heads
+  (use --force-close-branch to close branch from a non-head changeset)
+  [255]
+
+  $ hg ci -m "branch closed" --force-close-branch
+  created new head
--- a/tests/test-completion.t	Fri Jun 28 21:31:34 2019 +0530
+++ b/tests/test-completion.t	Sat May 18 15:44:23 2019 +0530
@@ -247,7 +247,7 @@
   bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
   cat: output, rev, decode, include, exclude, template
   clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
-  commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
+  commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   copy: after, force, include, exclude, dry-run
   debugancestor: