Patchwork D3557: commit: add new close-branch command

login
register
mail settings
Submitter phabricator
Date May 13, 2018, 11:42 p.m.
Message ID <differential-rev-PHID-DREV-xc4qpx5at2fp5vs4hfcg-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/31580/
State New
Headers show

Comments

phabricator - May 13, 2018, 11:42 p.m.
joerg.sonnenberger created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  ``hg close-branch`` allows closing arbitrary heads. It is equivalent to
  checking out the given revisions and commit an empty change with
  ``hg commit --close-branch``.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/commands.py
  tests/test-close-branch.t
  tests/test-completion.t
  tests/test-globalopts.t
  tests/test-help.t
  tests/test-hgweb-json.t

CHANGE DETAILS




To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-devel
phabricator - May 20, 2018, 7:52 p.m.
pulkit added a comment.


  > `hg close-branch` allows closing arbitrary heads. It is equivalent to
  >  checking out the given revisions and commit an empty change with
  >  `hg commit --close-branch`.
  
  I am -1 on having a new command for this. How about adding this as a `--close` flag to `hg branch` command?

REPOSITORY
  rHG Mercurial

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

To: joerg.sonnenberger, #hg-reviewers
Cc: pulkit, mercurial-devel

Patch

diff --git a/tests/test-hgweb-json.t b/tests/test-hgweb-json.t
--- a/tests/test-hgweb-json.t
+++ b/tests/test-hgweb-json.t
@@ -1800,6 +1800,10 @@ 
         "topic": "cat"
       },
       {
+        "summary": "close the given head revisions",
+        "topic": "close-branch"
+      },
+      {
         "summary": "show combined config settings from all hgrc files",
         "topic": "config"
       },
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -65,6 +65,7 @@ 
    bundle        create a bundle file
    cat           output the current or given revision of files
    clone         make a copy of an existing repository
+   close-branch  close the given head revisions
    commit        commit the specified files or all outstanding changes
    config        show combined config settings from all hgrc files
    copy          mark files as copied for the next commit
@@ -144,6 +145,7 @@ 
    bundle        create a bundle file
    cat           output the current or given revision of files
    clone         make a copy of an existing repository
+   close-branch  close the given head revisions
    commit        commit the specified files or all outstanding changes
    config        show combined config settings from all hgrc files
    copy          mark files as copied for the next commit
@@ -840,6 +842,7 @@ 
    bundle        create a bundle file
    cat           output the current or given revision of files
    clone         make a copy of an existing repository
+   close-branch  close the given head revisions
    commit        commit the specified files or all outstanding changes
    config        show combined config settings from all hgrc files
    copy          mark files as copied for the next commit
@@ -2356,6 +2359,13 @@ 
   output the current or given revision of files
   </td></tr>
   <tr><td>
+  <a href="/help/close-branch">
+  close-branch
+  </a>
+  </td><td>
+  close the given head revisions
+  </td></tr>
+  <tr><td>
   <a href="/help/config">
   config
   </a>
diff --git a/tests/test-globalopts.t b/tests/test-globalopts.t
--- a/tests/test-globalopts.t
+++ b/tests/test-globalopts.t
@@ -308,6 +308,7 @@ 
    bundle        create a bundle file
    cat           output the current or given revision of files
    clone         make a copy of an existing repository
+   close-branch  close the given head revisions
    commit        commit the specified files or all outstanding changes
    config        show combined config settings from all hgrc files
    copy          mark files as copied for the next commit
@@ -391,6 +392,7 @@ 
    bundle        create a bundle file
    cat           output the current or given revision of files
    clone         make a copy of an existing repository
+   close-branch  close the given head revisions
    commit        commit the specified files or all outstanding changes
    config        show combined config settings from all hgrc files
    copy          mark files as copied for the next commit
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -12,6 +12,7 @@ 
   bundle
   cat
   clone
+  close-branch
   commit
   config
   copy
@@ -252,6 +253,7 @@ 
   branches: active, closed, template
   bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
   cat: output, rev, decode, include, exclude, template
+  close-branch: message, logfile, date, user
   config: untrusted, edit, local, global, template
   copy: after, force, include, exclude, dry-run
   debugancestor: 
diff --git a/tests/test-close-branch.t b/tests/test-close-branch.t
new file mode 100644
--- /dev/null
+++ b/tests/test-close-branch.t
@@ -0,0 +1,41 @@ 
+  $ hg init
+  $ hg debugbuilddag '+2*2*3*4'
+  $ hg log -G --template '{rev}:{node|short}'
+  o  4:e7bd5218ca15
+  |
+  | o  3:6100d3090acf
+  |/
+  | o  2:fa942426a6fd
+  |/
+  | o  1:66f7d451a68b
+  |/
+  o  0:1ea73414a91b
+  
+  $ hg close-branch -m 'Close old heads' 1 2
+  $ hg heads
+  changeset:   4:e7bd5218ca15
+  parent:      0:1ea73414a91b
+  user:        debugbuilddag
+  date:        Thu Jan 01 00:00:04 1970 +0000
+  summary:     r4
+  
+  changeset:   3:6100d3090acf
+  parent:      0:1ea73414a91b
+  user:        debugbuilddag
+  date:        Thu Jan 01 00:00:03 1970 +0000
+  summary:     r3
+  
+  $ hg close-branch -m 'Close more old heads' 4
+  $ hg heads
+  changeset:   3:6100d3090acf
+  parent:      0:1ea73414a91b
+  user:        debugbuilddag
+  date:        Thu Jan 01 00:00:03 1970 +0000
+  summary:     r3
+  
+  $ hg close-branch -m 'Not a head' 0
+  abort: revision is not an open head: 0
+  [255]
+  $ hg close-branch -m 'Already closed head' 1
+  abort: revision is not an open head: 1
+  [255]
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -26,6 +26,7 @@ 
     bundle2,
     changegroup,
     cmdutil,
+    context,
     copies,
     debugcommands as debugcommandsmod,
     destutil,
@@ -1468,6 +1469,55 @@ 
 
     return r is None
 
+@command('close-branch', commitopts + commitopts2,
+    _('[OPTION]... [REV]...'), inferrepo=True)
+def close_branch(ui, repo, *revs, **opts):
+    """close the given head revisions
+
+    This is equivalent to checking out each revision in a clean tree and running
+    ``hg commit --close-branch``, except that it doesn't change the working
+    directory.
+
+    The commit message must be specified with -l or -m.
+    """
+    def docommit(rev):
+        cctx = context.memctx(repo, parents=[rev, None], text=message,
+                              files=[], filectxfn=None, user=opts.get('user'),
+                              date=opts.get('date'), extra=extra)
+        tr = repo.transaction('commit')
+        ret = repo.commitctx(cctx, True)
+        bookmarks.update(repo, [rev, None], ret)
+        cctx.markcommitted(ret)
+        tr.close()
+
+    if not revs:
+        raise error.Abort(_('no revisions specified'))
+
+    revs = scmutil.revrange(repo, revs)
+
+    heads = []
+    for branch in repo.branchmap():
+        heads.extend(repo.branchheads(branch))
+    heads = set(repo[h].rev() for h in heads)
+    for rev in revs:
+        if rev not in heads:
+            raise error.Abort(_('revision is not an open head: %s') % rev)
+
+    message = cmdutil.logmessage(ui, opts)
+    if not message:
+        raise error.Abort(_("No commit message specified with -l or -m"))
+    extra = { 'close': '1' }
+
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        for rev in revs:
+            docommit(rev)
+    finally:
+        release(lock, wlock)
+    return 0
+
 @command('^commit|ci',
     [('A', 'addremove', None,
      _('mark new/missing files as added/removed before committing')),