[Checkins] SVN: zope.fssync/trunk/src/zope/fssync/ Add support for avoiding conflicts in certain types of merge opertions
Amos Latteier
amos at latteier.com
Tue Mar 10 14:21:54 EDT 2009
Log message for revision 97814:
Add support for avoiding conflicts in certain types of merge opertions
by ignoring local changes.
Changed:
U zope.fssync/trunk/src/zope/fssync/CHANGES.txt
U zope.fssync/trunk/src/zope/fssync/fsmerger.py
U zope.fssync/trunk/src/zope/fssync/tests/test_fsmerger.py
-=-
Modified: zope.fssync/trunk/src/zope/fssync/CHANGES.txt
===================================================================
--- zope.fssync/trunk/src/zope/fssync/CHANGES.txt 2009-03-10 18:00:07 UTC (rev 97813)
+++ zope.fssync/trunk/src/zope/fssync/CHANGES.txt 2009-03-10 18:21:53 UTC (rev 97814)
@@ -10,6 +10,10 @@
when adding multiple objects at the same time that depend on
each other. Callbacks can in turn return callbacks.
+ - Add support to FSMerger to allow locally modified files to be
+ overwritten by files returned from the server. The purpose of
+ this is to avoid conflicts after commit on files that are
+ formatted differently on the server from local versions.
After Zope 3.4.0b1 (trunk only)
Modified: zope.fssync/trunk/src/zope/fssync/fsmerger.py
===================================================================
--- zope.fssync/trunk/src/zope/fssync/fsmerger.py 2009-03-10 18:00:07 UTC (rev 97813)
+++ zope.fssync/trunk/src/zope/fssync/fsmerger.py 2009-03-10 18:21:53 UTC (rev 97814)
@@ -29,9 +29,13 @@
class FSMerger(object):
- """Higher-level three-way file and directory merger."""
+ """Higher-level three-way file and directory merger.
- def __init__(self, metadata, reporter):
+ If overwrite_local is True, then local should be replaced with
+ the remote, regardless of local changes.
+ """
+
+ def __init__(self, metadata, reporter, overwrite_local=False):
"""Constructor.
Arguments are a metadata database and a reporting function.
@@ -39,6 +43,7 @@
self.metadata = metadata
self.reporter = reporter
self.merger = Merger(metadata)
+ self.overwrite_local = overwrite_local
def merge(self, local, remote):
"""Merge remote file or directory into local file or directory."""
@@ -155,7 +160,6 @@
def merge_files(self, local, remote):
"""Merge remote file into local file."""
-
# Reset sticky conflict if file was removed
entry = self.metadata.getentry(local)
conflict = entry.get("conflict")
@@ -164,6 +168,9 @@
original = fsutil.getoriginal(local)
action, state = self.merger.classify_files(local, original, remote)
+ if action == 'Merge' and state == 'Modified' and self.overwrite_local:
+ action = 'Copy'
+ state = 'Uptodate'
state = self.merger.merge_files(local, original, remote,
action, state) or state
self.reportaction(action, state, local)
Modified: zope.fssync/trunk/src/zope/fssync/tests/test_fsmerger.py
===================================================================
--- zope.fssync/trunk/src/zope/fssync/tests/test_fsmerger.py 2009-03-10 18:00:07 UTC (rev 97813)
+++ zope.fssync/trunk/src/zope/fssync/tests/test_fsmerger.py 2009-03-10 18:21:53 UTC (rev 97814)
@@ -211,10 +211,11 @@
localentry, remoteentry,
expected_reports_template,
expected_localdata, expected_origdata, expected_remotedata,
- expected_localentry, expected_remoteentry):
+ expected_localentry, expected_remoteentry,
+ overwrite_local=False):
# Generic test setup to test merging files
reports = []
- m = FSMerger(self.metadata, reports.append)
+ m = FSMerger(self.metadata, reports.append, overwrite_local)
localtopdir = self.tempdir()
remotetopdir = self.tempdir()
@@ -467,6 +468,64 @@
None, None, None,
{}, {})
+
+ def test_overwrite_local(self):
+ # make sure that we normally get a conflict when the orginal,
+ # local, and remote versions are different
+ conflict = "<<<<<<< %l\nl\n=======\nr\n>>>>>>> %r\n"
+ self.mergetest("foo", "l\n", "a\n", "r\n", self.entry, self.entry,
+ ["C %l"], conflict, "r\n", "r\n",
+ self.make_conflict_entry, self.entry)
+
+ # now try to same thing but with overwrite_local set to
+ # true. This time the local and original should be replaced
+ # with the remote file.
+ self.mergetest("foo", "l\n", "a\n", "r\n", self.entry, self.entry,
+ ["U %l"], "r\n", "r\n", "r\n",
+ self.entry, self.entry, True)
+
+ # try it when the original and local are the same, but the
+ # remote is different. In this case the overwrite_local
+ # setting doesn't change things.
+ self.mergetest("foo", "a\n", "a\n", "r\n", self.entry, self.entry,
+ ["U %l"], "r\n", "r\n", "r\n",
+ self.entry, self.entry, True)
+
+ self.mergetest("foo", "a\n", "a\n", "r\n", self.entry, self.entry,
+ ["U %l"], "r\n", "r\n", "r\n",
+ self.entry, self.entry)
+
+ # testing if remote is the same as local. Again,
+ # overwrite_local shouldn't change things.
+ self.mergetest("foo", "l\n", "a\n", "l\n", self.entry, self.entry,
+ ["U %l"], "l\n", "l\n", "l\n",
+ self.entry, self.entry, True)
+
+ self.mergetest("foo", "l\n", "a\n", "l\n", self.entry, self.entry,
+ ["U %l"], "l\n", "l\n", "l\n",
+ self.entry, self.entry)
+
+ # How about when all are the same? Again overwrite_local
+ # shouldn't change anything.
+ self.mergetest("foo", "a\n", "a\n", "a\n", self.entry, self.entry,
+ [], "a\n", "a\n", "a\n",
+ self.entry, self.entry, True)
+
+ self.mergetest("foo", "a\n", "a\n", "a\n", self.entry, self.entry,
+ [], "a\n", "a\n", "a\n",
+ self.entry, self.entry)
+
+ # test when original and remote are the same. Again,
+ # overwrite_local shouldn't make any difference.
+ self.mergetest("foo", "l\n", "a\n", "a\n", self.entry, self.entry,
+ ["M %l"], "l\n", "a\n", "a\n",
+ self.entry, self.entry, True)
+
+ self.mergetest("foo", "l\n", "a\n", "a\n", self.entry, self.entry,
+ ["M %l"], "l\n", "a\n", "a\n",
+ self.entry, self.entry)
+
+
def test_suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(TestFSMerger))
More information about the Checkins
mailing list