changeset 12:a51909f8032d

introduce merge functions
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 14 May 2011 13:25:57 +0200
parents a4560f329a9e
children 3d578fbfeb66
files hgstorage.py test_repo.py
diffstat 2 files changed, 33 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/hgstorage.py	Sat May 14 00:57:13 2011 +0200
+++ b/hgstorage.py	Sat May 14 13:25:57 2011 +0200
@@ -27,6 +27,24 @@
     possible or wanted.
     """
 
+def default_merge_func(base, other, this):
+    if (mercurial.util.binary(this) or mercurial.util.binary(base) or
+        mercurial.util.binary(other)):
+        raise ConflictError("can't merge binary data")
+    m3 = mercurial.simplemerge.Merge3Text(base, other, this)
+    return ''.join(m3.merge_lines(start_marker='<<<<<<<',
+                                  mid_marker='=======',
+                                  end_marker='>>>>>>>',
+                                  base_marker='|||||||'))
+
+def conflict_merge_func(base, other, this):
+    raise ConflictError("merge conflict")
+
+
+def overwrite_merge_func(base, other, this):
+    return this
+
+
 class Storage(object):
     """
     A storage object holds all the configuration and path to your repository.
@@ -149,19 +167,12 @@
 
         return (parent_rev, last_rev)
 
-    def _merge(self, filename, parent, other, data):
+
+    def _merge(self, filename, parent, other, data, func):
         filetip = self.tip[filename]
         parent_data = filetip.filectx(parent).data()
         other_data = filetip.filectx(other).data()
-        if (mercurial.util.binary(data) or
-            mercurial.util.binary(parent_data) or
-            mercurial.util.binary(other_data)):
-            raise ConflictError("can't mege binary data for %r" % filename)
-        m3 = mercurial.simplemerge.Merge3Text(parent_data, other_data, data)
-        return ''.join(m3.merge_lines(start_marker='<<<<<<<',
-                                      mid_marker='=======',
-                                      end_marker='>>>>>>>',
-                                      base_marker='|||||||'))
+        return func(parent_data, other_data, data)
 
     def _filectx(self, key, rev=None):
         filename = self.storage._key_to_file(key)
@@ -177,7 +188,7 @@
             raise KeyError()
 
     def save(self, key, data, user=None, message=None, parent_rev=None,
-             encoding=None, force=False, no_merge=False):
+             encoding=None, merge_func=default_merge_func):
         """Save a new revision of the item."""
 
         if encoding:
@@ -186,11 +197,8 @@
         filename = self.storage._key_to_file(key)
         parent, other = self._get_parents(filename, parent_rev)
 
-        if no_merge and other is not None:
-            raise ConflictError('conflict while updating %r' % key)
-
-        if other is not None and not force:
-            data = self._merge(filename, parent, other, data)
+        if other is not None:
+            data = self._merge(filename, parent, other, data, merge_func)
 
         def filectxfn(repo, memctx, path):
             return mercurial.context.memfilectx(path, data, False, False, None)
--- a/test_repo.py	Sat May 14 00:57:13 2011 +0200
+++ b/test_repo.py	Sat May 14 13:25:57 2011 +0200
@@ -72,6 +72,14 @@
         data = s.load('title', 0)
         assert 'text1' == data
 
+    def test_save_overwrite (self, storage):
+        s = storage.session()
+        s.save('title', u'text1', 'user1', 'message1', -1)
+        s.save('title', u'text2', 'user2', 'message2', -1,
+                merge_func=hgstorage.overwrite_merge_func)
+        data = s.load('title')
+        assert 'text2' == data
+
     def test_save_merge(self, storage):
         s = storage.session()
         s.save('title', u'a\ntext\nb', 'user1', 'message1', -1, encoding='utf8')
@@ -97,7 +105,7 @@
         assert 'a\ntext\n<<<<<<<\nbb|||||||\nb=======\na>>>>>>>\n' == data
         with py.test.raises(hgstorage.ConflictError):
             s.save('title', u'a\ntext\nb', 'user2', 'message2', 0,
-                   encoding='utf8', no_merge=True)
+                   encoding='utf8', merge_func=hgstorage.conflict_merge_func)
 
     def test_silly_parents(self, storage):
         s = storage.session()