# HG changeset patch # User Idan Kamara # Date 1313528304 -10800 # Node ID ebcc5d7dd528d570645b7f384fdc05b439d685ea # Parent 191855a9d813dbefa7144832d08a6e4965f6f660 client: introduce merge handlers These can control the behaviour when Mercurial prompts what to do with regard to a specific file diff -r 191855a9d813 -r ebcc5d7dd528 hglib/client.py --- 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): diff -r 191855a9d813 -r ebcc5d7dd528 hglib/merge.py --- /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' diff -r 191855a9d813 -r ebcc5d7dd528 tests/test-merge.py --- 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))