Patchwork D8200: pull: add `--confirm` flag to confirm before writing changes

login
register
mail settings
Submitter phabricator
Date March 11, 2020, 4:51 p.m.
Message ID <9cfbe9fb42f1326e34c8120943d7ec36@localhost.localdomain>
Download mbox | patch
Permalink /patch/45745/
State Not Applicable
Headers show

Comments

phabricator - March 11, 2020, 4:51 p.m.
Closed by commit rHG476c8e427975: pull: add `--confirm` flag to confirm before writing changes (authored by pulkit).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8200?vs=20501&id=20739

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8200/new/

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

AFFECTED FILES
  mercurial/commands.py
  mercurial/configitems.py
  mercurial/exchange.py
  relnotes/next
  tests/test-completion.t
  tests/test-obsolete-distributed.t
  tests/test-obsolete.t
  tests/test-phases-exchange.t
  tests/test-pull-r.t

CHANGE DETAILS




To: pulkit, #hg-reviewers, durin42
Cc: marmoute, durin42, mercurial-devel

Patch

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -1,3 +1,9 @@ 
+  $ cat <<EOF >> $HGRCPATH
+  > [ui]
+  > interactive = true
+  > EOF
+
+
   $ hg init repo
   $ cd repo
   $ echo foo > foo
@@ -42,12 +48,47 @@ 
   $ hg heads -q --closed
   2:effea6de0384
   1:ed1b79f46b9a
-  $ hg pull
+  $ hg pull --confirm << EOF
+  > n
+  > EOF
   pulling from $TESTTMP/repo2
   searching for changes
   adding changesets
   adding manifests
   adding file changes
+  adding 2 changesets with 1 changes to 1 files
+  new changesets 8c900227dd5d:00cfe9073916
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ hg pull --config pull.confirm=true << EOF
+  > n
+  > EOF
+  pulling from $TESTTMP/repo2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 2 changesets with 1 changes to 1 files
+  new changesets 8c900227dd5d:00cfe9073916
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ hg pull --confirm << EOF
+  > y
+  > EOF
+  pulling from $TESTTMP/repo2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 2 changesets with 1 changes to 1 files
+  new changesets 8c900227dd5d:00cfe9073916
+  accept incoming changes (yn)? y
   added 2 changesets with 1 changes to 1 files
   new changesets 8c900227dd5d:00cfe9073916
   (run 'hg update' to get a working copy)
@@ -56,6 +97,12 @@ 
   2:effea6de0384
   1:ed1b79f46b9a
 
+pull--confirm config option should be ignored if HGPLAIN is set
+  $ HGPLAIN=1 hg pull --config pull.confirm=True
+  pulling from $TESTTMP/repo2
+  searching for changes
+  no changes found
+
   $ cd ..
 
   $ hg init copy
diff --git a/tests/test-phases-exchange.t b/tests/test-phases-exchange.t
--- a/tests/test-phases-exchange.t
+++ b/tests/test-phases-exchange.t
@@ -326,12 +326,18 @@ 
   o  0 public a-A - 054250a37db4
   
   $ cd ../mu
-  $ hg pull ../nu
+  $ hg pull ../nu --confirm --config ui.interactive=True<<EOF
+  > y
+  > EOF
   pulling from ../nu
   searching for changes
   adding changesets
   adding manifests
   adding file changes
+  adding 2 changesets with 2 changes to 2 files
+  new changesets d6bcb4f74035:145e75495359 (2 drafts)
+  4 local changesets will be published
+  accept incoming changes (yn)? y
   added 2 changesets with 2 changes to 2 files
   new changesets d6bcb4f74035:145e75495359 (2 drafts)
   4 local changesets published
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -377,15 +377,53 @@ 
   2:245bde4270cd (public) [ ] add original_c
   6:6f9641995072 (draft) [tip ] add n3w_3_c
 
-Try to pull markers
+Try to pull markers while testing pull --confirm
 (extinct changeset are excluded but marker are pushed)
 
-  $ hg pull ../tmpb
+  $ hg pull ../tmpb --confirm --config ui.interactive=true <<EOF
+  > n
+  > EOF
   pulling from ../tmpb
   requesting all changes
   adding changesets
   adding manifests
   adding file changes
+  adding 4 changesets with 4 changes to 4 files (+1 heads)
+  5 new obsolescence markers
+  new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ HGPLAIN=1 hg pull ../tmpb --confirm --config ui.interactive=true <<EOF
+  > n
+  > EOF
+  pulling from ../tmpb
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 4 changesets with 4 changes to 4 files (+1 heads)
+  5 new obsolescence markers
+  new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ hg pull ../tmpb --confirm --config ui.interactive=true <<EOF
+  > y
+  > EOF
+  pulling from ../tmpb
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 4 changesets with 4 changes to 4 files (+1 heads)
+  5 new obsolescence markers
+  new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
+  accept incoming changes (yn)? y
   added 4 changesets with 4 changes to 4 files (+1 heads)
   5 new obsolescence markers
   new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
diff --git a/tests/test-obsolete-distributed.t b/tests/test-obsolete-distributed.t
--- a/tests/test-obsolete-distributed.t
+++ b/tests/test-obsolete-distributed.t
@@ -138,12 +138,37 @@ 
 
   $ hg up 'desc("ROOT")'
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ hg pull
+  $ hg pull --confirm --config ui.interactive=True << EOF
+  > n
+  > EOF
   pulling from $TESTTMP/distributed-chain-building/server
   searching for changes
   adding changesets
   adding manifests
   adding file changes
+  adding 1 changesets with 1 changes to 1 files (+1 heads)
+  1 new obsolescence markers
+  obsoleting 1 changesets
+  new changesets 391a2bf12b1b (1 drafts)
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+
+  $ hg pull --confirm --config ui.interactive=True << EOF
+  > y
+  > EOF
+  pulling from $TESTTMP/distributed-chain-building/server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 1 changesets with 1 changes to 1 files (+1 heads)
+  1 new obsolescence markers
+  obsoleting 1 changesets
+  new changesets 391a2bf12b1b (1 drafts)
+  accept incoming changes (yn)? y
   added 1 changesets with 1 changes to 1 files (+1 heads)
   1 new obsolescence markers
   obsoleted 1 changesets
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -345,7 +345,7 @@ 
   parents: rev, style, template
   paths: template
   phase: public, draft, secret, force, rev
-  pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
+  pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure
   push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
   recover: verify
   remove: after, force, subrepos, include, exclude, dry-run
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,6 +3,9 @@ 
  * `hg purge`/`hg clean` can now delete ignored files instead of
    untracked files, with the new -i flag.
 
+ * `hg pull` now has a `--confirm` flag to prompt before applying changes.
+   Config option `pull.confirm` is also added for that.
+
  * `hg log` now defaults to using an '%' symbol for commits involved
     in unresolved merge conflicts. That includes unresolved conflicts
     caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -8,6 +8,7 @@ 
 from __future__ import absolute_import
 
 import collections
+import weakref
 
 from .i18n import _
 from .node import (
@@ -1705,6 +1706,23 @@ 
         pullop.rheads = set(pullop.rheads) - pullop.common
 
 
+def add_confirm_callback(repo, pullop):
+    """ adds a finalize callback to transaction which can be used to show stats
+    to user and confirm the pull before committing transaction """
+
+    tr = pullop.trmanager.transaction()
+    scmutil.registersummarycallback(repo, tr, txnname=b'pull', as_validator=True)
+    reporef = weakref.ref(repo.unfiltered())
+
+    def prompt(tr):
+        repo = reporef()
+        cm = _(b'accept incoming changes (yn)?$$ &Yes $$ &No')
+        if repo.ui.promptchoice(cm):
+            raise error.Abort("user aborted")
+
+    tr.addvalidator(b'900-pull-prompt', prompt)
+
+
 def pull(
     repo,
     remote,
@@ -1716,6 +1734,7 @@ 
     includepats=None,
     excludepats=None,
     depth=None,
+    confirm=None,
 ):
     """Fetch repository data from a remote.
 
@@ -1740,6 +1759,8 @@ 
     ``depth`` is an integer indicating the DAG depth of history we're
     interested in. If defined, for each revision specified in ``heads``, we
     will fetch up to this many of its ancestors and data associated with them.
+    ``confirm`` is a boolean indicating whether the pull should be confirmed
+    before committing the transaction. This overrides HGPLAIN.
 
     Returns the ``pulloperation`` created for this pull.
     """
@@ -1786,6 +1807,9 @@ 
     if not bookmod.bookmarksinstore(repo):
         wlock = repo.wlock()
     with wlock, repo.lock(), pullop.trmanager:
+        if confirm or (repo.ui.configbool(b"pull", b"confirm") and not repo.ui.plain()):
+            add_confirm_callback(repo, pullop)
+
         # Use the modern wire protocol, if available.
         if remote.capable(b'command-changesetdata'):
             exchangev2.pull(pullop)
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -1067,6 +1067,9 @@ 
     b'progress', b'width', default=dynamicdefault,
 )
 coreconfigitem(
+    b'pull', b'confirm', default=False,
+)
+coreconfigitem(
     b'push', b'pushvars.server', default=False,
 )
 coreconfigitem(
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5344,6 +5344,7 @@ 
             None,
             _(b'run even when remote repository is unrelated'),
         ),
+        (b'', b'confirm', None, _(b'confirm pull before applying changes'),),
         (
             b'r',
             b'rev',
@@ -5460,6 +5461,7 @@ 
                 force=opts.get(b'force'),
                 bookmarks=opts.get(b'bookmark', ()),
                 opargs=pullopargs,
+                confirm=opts.get(b'confirm'),
             ).cgresult
 
             # brev is a name, which might be a bookmark to be activated at