]> thyrsus.com Git - rcs-fast-import.git/commitdiff
Looking further back in ancestry works.
authorEric S. Raymond <esr@thyrsus.com>
Sun, 14 Nov 2010 02:59:28 +0000 (21:59 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Sun, 14 Nov 2010 02:59:28 +0000 (21:59 -0500)
rcs-fast-import

index 21d2e11a08f469ad5e5826c82b9af17566f3ba07..cdde124b1ed153fbf203536f0934ac5aa4e0a90a 100755 (executable)
@@ -40,9 +40,12 @@ version="0.1"
 #
 
 verbose         = 0
-DEBUG_SHUFFLE   = 2    # Debug directory handling
-DEBUG_DELETE    = 2    # Debug canonicalization after deletes
-DEBUG_COMMANDS  = 2    # Show commands as they are executed
+DEBUG_BRANCHING = 1    # Debug revision assignment and branch mapping
+DEBUG_OPS       = 2    # Show import-stream operations
+DEBUG_UNQUIET   = 2    # Don't suppress messages from RCS tools
+DEBUG_SHUFFLE   = 3    # Debug directory handling
+DEBUG_COMMANDS  = 3    # Show commands as they are executed
+DEBUG_DELETE    = 4    # Debug canonicalization after deletes
 
 dryrun = False
 
@@ -547,7 +550,7 @@ def do_or_die(cmd, legend=""):
         legend = " "  + legend
     if verbose >= DEBUG_COMMANDS:
         announce("executing '%s'%s" % (cmd, legend))
-    if not verbose:
+    if not verbose >= DEBUG_UNQUIET:
         cmd += ">/dev/null 2>&1" 
     if dryrun:
         return
@@ -585,12 +588,11 @@ class Generic:
     "Generic file-oriented VCS - could be used for, say. SCCS as well as RCS."
     def __init__(self):
         self.roundtrip = False
-        if verbose:
-            if not os.path.exists(self.__class__.repodirectory):
-                try:
-                    os.makedirs(self.__class__.repodirectory)
-                except OSError:
-                    raise FatalException("can't create RCS directory.")
+        if not os.path.exists(self.__class__.repodirectory):
+            try:
+                os.makedirs(self.__class__.repodirectory)
+            except OSError:
+                raise FatalException("can't create RCS directory.")
     def master(self, filename):
         "Return the master file corresponding to a specified filename."
         parts = list(os.path.split(filename))
@@ -675,21 +677,26 @@ class RCS(Generic):
     def checkin(self, commit, comment, op, path):
         "Check in a new revision - also used to create new masters."
         # This is the only manipulation of the branch structure there is.
-        parents = commit.parents()
+        if verbose >= DEBUG_BRANCHING:
+            print "commit", commit.branch
         if not os.path.exists(self.master(path)):
             myrev = "1.1"
         else:
+            parents = commit.parents()
             if len(parents) > 1:
                 complain("RCS cannot preserve merge information.")
-            try:
-                tip = self.branch_tips[(path, parents[0].branch)]
-            except KeyError:
-                # If this ever happens, it means some child commits
-                # are in the input stream before parents.  That is
-                # too screwed up to cope with.  Bail out.
-                raise FatalException("unknown parent branch %s %s" \
-                                         % (path, parents[0].branch))
-            if parents[0].branch == commit.branch:
+            # Find an ancestor commit that checked in this file.
+            # That rev is the branch tip for this file.
+            ancestor = commit
+            while True:
+                if not ancestor.parents:
+                    raise FatalException("can't find ancestor for %s %s" \
+                                     % (path, commit.branch))
+                ancestor = ancestor.parents()[0]
+                if (path, ancestor.branch) in self.branch_tips:
+                    tip = self.branch_tips[(path, ancestor.branch)]
+                    break
+            if ancestor.branch == commit.branch:
                 # Not going down a branch point.  Just bump the last
                 # field of the tip revision.
                 fields = map(int, tip.split("."))
@@ -701,7 +708,8 @@ class RCS(Generic):
                     parents[0].childbranches.append(commit.branch)
                 branchnum = parents[0].childbranches.index(commit.branch) + 1
                 myrev = tip + "." + `branchnum` + ".1"
-        print "**** Assigning", myrev, "to", (path, commit.branch)
+        if verbose >= DEBUG_BRANCHING:
+            print "Assigning", myrev, "to", path
         self.branch_tips[(path, commit.branch)] = myrev
         # Branch hackery ends here
         command = "ci -l%s" % myrev
@@ -768,27 +776,24 @@ if __name__ == '__main__':
                     vcs.precommit(event)
                     for op in event.fileops:
                         if op.op == "M":
-                            if verbose:
+                            if verbose >= DEBUG_OPS:
                                 announce("%5s M %s" % (event.mark, op.path))
                             if op.mode == "160000":
                                 complain("cannot represent a submodule link in RCS")
                             else:
                                 vcs.modify(event, op.path, op.mode, op.copyname)
                         elif op.op in ("D", "deleteall"):
-                            if verbose:
+                            if verbose >= DEBUG_OPS:
                                 announce("%5s D %s" % (event.mark, op.path))
-                            if not dryrun:
-                                vcs.remove(op.path)
+                            vcs.delete(op.path)
                         elif op.op == "R":
-                            if verbose:
+                            if verbose >= DEBUG_OPS:
                                 announce("%5s R '%s' '%s'" % (event.mark, op.source, op.target))
-                            if not dryrun:
-                                vcs.rename(event, op.source, op.target)
+                            vcs.rename(event, op.source, op.target)
                         elif op.op == "C":
-                            if verbose:
+                            if verbose >= DEBUG_OPS:
                                 announce("%5s C '%s' '%s'" % (event.mark, op.source, op.target))
-                            if not dryrun:
-                                vcs.copy(commit, ops.source, op.target)
+                            vcs.copy(commit, ops.source, op.target)
                         else:
                             raise FatalException("unknown op type %s" % op.op)
                     vcs.postcommit(event)