changeset 46:ebcc5d7dd528

client: introduce merge handlers These can control the behaviour when Mercurial prompts what to do with regard to a specific file
author Idan Kamara <idankk86@gmail.com>
date Tue, 16 Aug 2011 23:58:24 +0300
parents 191855a9d813
children 94d2988e55b7
files hglib/client.py hglib/merge.py tests/test-merge.py
diffstat 3 files changed, 79 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/hglib/client.py	Tue Aug 16 23:57:21 2011 +0300
+++ b/hglib/client.py	Tue Aug 16 23:58:24 2011 +0300
@@ -1,5 +1,5 @@
 import subprocess, os, struct, cStringIO, collections, re
-import hglib, error, util, templates
+import hglib, error, util, templates, merge
 
 from util import cmdbuilder
 
@@ -442,11 +442,26 @@
 
         return self._parserevs(out)
 
-    def merge(self, rev=None, force=False, tool=None, cb=None):
+    def merge(self, rev=None, force=False, tool=None, cb=merge.handlers.abort):
+        """
+        merge working directory with another revision
+
+        cb can one of merge.handlers, or a function that gets a single argument
+        which are the contents of stdout. It should return one of the expected
+        choices (a single character).
+        """
         # we can't really use --preview since merge doesn't support --template
         args = cmdbuilder('merge', r=rev, f=force, t=tool)
 
-        self.rawcommand(args, prompt=cb)
+        prompt = None
+        if cb is merge.handlers.abort:
+            prompt = cb
+        elif cb is merge.handlers.noninteractive:
+            args.append('-y')
+        else:
+            prompt = lambda size, output: cb(output) + '\n'
+
+        self.rawcommand(args, prompt=prompt)
 
     def move(self, source, dest, after=False, force=False, dryrun=False,
              include=None, exclude=None):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hglib/merge.py	Tue Aug 16 23:58:24 2011 +0300
@@ -0,0 +1,19 @@
+class handlers(object):
+    """
+    These can be used as the cb argument to hgclient.merge() to control the
+    behaviour when Mercurial prompts what to do with regard to a specific file,
+    e.g. when one parent modified a file and the other removed it.
+    """
+
+    @staticmethod
+    def abort(size, output):
+        """
+        Abort the merge if a prompt appears.
+        """
+        return ''
+
+    """
+    This corresponds to Mercurial's -y/--noninteractive global option, which
+    picks the first choice on all prompts.
+    """
+    noninteractive = 'yes'
--- a/tests/test-merge.py	Tue Aug 16 23:57:21 2011 +0300
+++ b/tests/test-merge.py	Tue Aug 16 23:58:24 2011 +0300
@@ -27,3 +27,45 @@
 """ % (node2[:12], node[:12])
 
         self.assertEquals(diff, self.client.diff(change=node, nodates=True))
+
+    def test_merge_prompt_abort(self):
+        self.client.update(self.node0)
+        self.client.remove('a')
+        self.client.commit('remove')
+
+        self.assertRaises(hglib.error.CommandError, self.client.merge)
+
+    def test_merge_prompt_noninteractive(self):
+        self.client.update(self.node0)
+        self.client.remove('a')
+        rev, node = self.client.commit('remove')
+
+        self.client.merge(cb=hglib.merge.handlers.noninteractive)
+
+        diff = """diff -r %s a
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++aa
+\ No newline at end of file
+""" % node[:12]
+        self.assertEquals(diff, self.client.diff(nodates=True))
+
+    def test_merge_prompt_cb(self):
+        self.client.update(self.node0)
+        self.client.remove('a')
+        rev, node = self.client.commit('remove')
+
+        def cb(output):
+            return 'c'
+
+        self.client.merge(cb=cb)
+
+        diff = """diff -r %s a
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++aa
+\ No newline at end of file
+""" % node[:12]
+        self.assertEquals(diff, self.client.diff(nodates=True))