[Zope3-checkins] CVS: Zope3/src/zope/fssync - merger.py:1.4

Guido van Rossum guido@python.org
Wed, 14 May 2003 11:20:14 -0400


Update of /cvs-repository/Zope3/src/zope/fssync
In directory cvs.zope.org:/tmp/cvs-serv13290

Modified Files:
	merger.py 
Log Message:
Updated some comments to be closer to reality; this only deals with
files.  Also rename 'orig' to 'original'.


=== Zope3/src/zope/fssync/merger.py 1.3 => 1.4 ===
--- Zope3/src/zope/fssync/merger.py:1.3	Tue May 13 17:47:15 2003
+++ Zope3/src/zope/fssync/merger.py	Wed May 14 11:20:14 2003
@@ -23,39 +23,40 @@
 import filecmp
 import commands
 
-from os.path import exists, isdir, isfile
+from os.path import exists, isfile
 
 class Merger(object):
-    """Augmented three-way file and directory merges.
+    """Augmented three-way file merges.
 
-    An augmented merge takes into account three files (or directories)
-    and two metadata entries.  The files are labeled local, original,
-    and remote.  The metadata entries are for local and remote.  A
-    remote metadata entry is either empty or non-empty.  Empty means
-    the file does not exist remotely, non-empty means it does exist
-    remotely.  We also have to take into account the possibility that
-    the existence of the file belies what the entry declares.  A local
-    metadata entry can have those states, and in addition, if
-    non-empty, it can be flagged as added or removed.  Again, the
-    existence of the file may bely what the entry claims.  The
-    original file serves the obvious purpose.  Its existence, too, can
-    be inconsistent with the state indicated by the metadata entries.
-
-    To find the metadata entry for a file, we look for a key
-    corresponding to its basename @@Zope/Entries.xml in the directory
-    that contains it.  For this purpose, we assume the filename given
-    uses the correct case even on a case-insensitive filesystem (i.e.,
-    the filesystem must be at least case-preserving).
+    An augmented merge takes into account three files and two metadata
+    entries.  The files are labeled local, original, and remote.  The
+    metadata entries are for local and remote.  A remote metadata
+    entry is either empty or non-empty.  Empty means the file does not
+    exist remotely, non-empty means it does exist remotely.  We also
+    have to take into account the possibility that the existence of
+    the file belies what the entry declares.  A local metadata entry
+    can have those states, and in addition, if non-empty, it can be
+    flagged as added or removed.  Again, the existence of the file may
+    bely what the entry claims.  The original file serves the obvious
+    purpose.  Its existence, too, can be inconsistent with the state
+    indicated by the metadata entries.
+
+    To find the metadata entry for a file, we use an abstraction
+    called the metadata database; for our purposes, all we need is
+    that the metadata database supports a getentry() method which
+    returns the metadata as a dict.  Changes to this dict will cause
+    changes to the metadata.
 
-    The purpose of the merge() function is to merging the remote
+    The purpose of the merge_files() method is to merging the remote
     changes into the local copy as the best it can, resolving
     inconsistencies if possible.  It should not raise an exception
     unless there are file/directory permission problems.  Its return
-    value is an indicator of what it dit.
+    value is an indicator of the final state.
 
-    The classify() function is a helper for merge(); it looks at all
-    the evidence and decides what merge() should do, without actually
-    touching any files or the metadata.  Possible actions are:
+    The classify_files() methods is a helper for merge_files(); it
+    looks at all the evidence and decides what merge_files() should
+    do, without actually touching any files or metadata.  Possible
+    actions are:
 
     Fix      -- copy the remote copy to the local original, nothing else
     Copy     -- copy the remote copy over the local copy
@@ -68,15 +69,15 @@
     Fix, Copy and Merge; it is deleted for action Delete; it is
     untouched for action Nothing.
 
-    It should also indicate the final state of the local copy after
-    the action is taken:
+    The classify_files() method should also indicate the final state
+    of the local copy after the action is taken:
 
-    Conflict -- there is a conflict of some kind
-    Uptodate -- the local copy is the same as the remote copy
-    Modified -- the local copy is marked (to be) modified
-    Added    -- the local copy is marked (to be) added
-    Removed  -- the local copy is marked (to be) removed
-    Spurious -- there is an unregistered local file only
+    Conflict    -- there is a conflict of some kind
+    Uptodate    -- the local copy is the same as the remote copy
+    Modified    -- the local copy is marked (to be) modified
+    Added       -- the local copy is marked (to be) added
+    Removed     -- the local copy is marked (to be) removed
+    Spurious    -- there is an unregistered local file only
     Nonexistent -- there is nothing locally or remotely
 
     For Conflict, Added and Removed, the action will always be
@@ -89,9 +90,9 @@
     next commit.
 
     Note that carrying out the Merge action can change the resulting
-    state to become Uptodate or Conflict instead of Modified, if there
-    are merge conflicts (which classify() can't detect without doing
-    more work than reasonable).
+    state to become Conflict instead of Modified, if there are merge
+    conflicts (which classify_files() can't detect without doing more
+    work than reasonable).
     """
 
     def __init__(self, metadata):
@@ -114,7 +115,7 @@
         """Helper to abstract away the existence of self.metadata."""
         return self.metadata.getentry(file)
 
-    def merge_files(self, local, orig, remote, action, state):
+    def merge_files(self, local, original, remote, action, state):
         """Helper to carry out a file merge.
 
         The action and state arguments correspond to the return value
@@ -125,30 +126,30 @@
         based upon the effect of the action.
         """
         method = getattr(self, "merge_files_" + action.lower())
-        return method(local, orig, remote) or state
+        return method(local, original, remote) or state
 
-    def merge_files_nothing(self, local, orig, remote):
+    def merge_files_nothing(self, local, original, remote):
         return None
 
-    def merge_files_remove(self, local, orig, remote):
+    def merge_files_remove(self, local, original, remote):
         if isfile(local):
             os.remove(local)
-        if isfile(orig):
-            os.remove(orig)
+        if isfile(original):
+            os.remove(original)
         self.getentry(local).clear()
         return None
 
-    def merge_files_copy(self, local, orig, remote):
+    def merge_files_copy(self, local, original, remote):
         shutil.copy(remote, local)
-        shutil.copy(remote, orig)
+        shutil.copy(remote, original)
         self.getentry(local).update(self.getentry(remote))
         self.clearflag(local)
         return None
 
-    def merge_files_merge(self, local, orig, remote):
+    def merge_files_merge(self, local, original, remote):
         # XXX This is platform dependent
-        if exists(orig):
-            origfile = orig
+        if exists(original):
+            origfile = original
         else:
             origfile = "/dev/null"
         cmd = "diff3 -m -E %s %s %s" % (commands.mkarg(local),
@@ -160,7 +161,7 @@
             f.write(output)
         finally:
             f.close()
-        shutil.copy(remote, orig)
+        shutil.copy(remote, original)
         self.getentry(local).update(self.getentry(remote))
         self.clearflag(local)
         if sts:
@@ -169,8 +170,8 @@
         else:
             return "Modified"
 
-    def merge_files_fix(self, local, orig, remote):
-        shutil.copy(remote, orig)
+    def merge_files_fix(self, local, original, remote):
+        shutil.copy(remote, original)
         self.clearflag(local)
         self.getentry(local).update(self.getentry(remote))
 
@@ -180,7 +181,7 @@
         if "flag" in metadata:
             del metadata["flag"]
 
-    def classify_files(self, local, orig, remote):
+    def classify_files(self, local, original, remote):
         """Helper for merge to classify file changes.
 
         Arguments are pathnames to the local, original, and remote
@@ -227,7 +228,7 @@
                 return ("Remove", "Nonexistent")
             else:
                 # Removed locally
-                if self.cmpfile(orig, remote):
+                if self.cmpfile(original, remote):
                     return ("Nothing", "Removed")
                 else:
                     return ("Nothing", "Conflict")
@@ -246,9 +247,9 @@
 
         # Sort out cases involving simple changes to files
 
-        if self.cmpfile(orig, remote):
+        if self.cmpfile(original, remote):
             # No remote changes; classify local changes
-            if self.cmpfile(local, orig):
+            if self.cmpfile(local, original):
                 # No changes
                 return ("Nothing", "Uptodate")
             else:
@@ -256,7 +257,7 @@
                 return ("Nothing", "Modified")
         else:
             # Some local changes; classify local changes
-            if self.cmpfile(local, orig):
+            if self.cmpfile(local, original):
                 # Only remote changes
                 return ("Copy", "Uptodate")
             else: