From b26dc7e61fcec8edd386e5c82c1182d0004f13c8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 10 Nov 2010 16:03:23 -0500 Subject: [PATCH] Now seems to be issuing reasonable-looking commands. --- rcs-fast-import | 79 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/rcs-fast-import b/rcs-fast-import index 25d8f2a..d247f88 100755 --- a/rcs-fast-import +++ b/rcs-fast-import @@ -53,6 +53,8 @@ DEBUG_SHUFFLE = 2 # Debug directory handling DEBUG_DELETE = 2 # Debug canonicalization after deletes DEBUG_COMMANDS = 2 # Show commands as they are executed +dryrun = False + class Baton: "Ship progress indications to stdout." def __init__(self, prompt, endmsg='done', enable=False): @@ -512,12 +514,43 @@ def complain(msg): def announce(msg): print "rcs-fast-import:", msg +class popen_or_die: + "Read or write from a subordinate process." + def __init__(self, cmd, legend="", mode="r"): + assert mode in ("r", "w") + self.cmd = cmd + self.legend = legend + self.mode = mode + if self.legend: + self.legend = " " + self.legend + def __enter__(self): + if verbose >= DEBUG_COMMANDS: + if self.mode == "r": + announce("reading from '%s'%s" % (self.cmd, self.legend)) + else: + announce("writing to '%s'%s" % (self.cmd, self.legend)) + if dryrun: + self.fp = file("/dev/null", self.mode) + return self.fp + try: + self.fp = os.popen(self.cmd, self.mode) + return self.fp + except OSError, e: + raise FatalException("execution of %s%s failed: %s" \ + % (self.cmd, self.legend, e)) + def __exit__(self, type, value, traceback): + if self.fp.close() is not None: + raise FatalException("%s%s returned error." \ + % (self.cmd, self.legend)) + return False def do_or_die(cmd, legend=""): "Either execute a command or raise a fatal exception." if legend: legend = " " + legend if verbose >= DEBUG_COMMANDS: announce("executing '%s'%s" % (cmd, legend)) + if dryrun: + return try: retcode = subprocess.call(cmd, shell=True) if retcode < 0: @@ -541,24 +574,31 @@ class RCS: @staticmethod def master(filename): "Return the master file corresponding to a specified filename." - parts = os.path.split(filename) + parts = list(os.path.split(filename)) parts.insert(-1, "RCS") - return os.path.join(parts) - def modify(self, event, path, mode, copyfile): + return os.path.join(*parts) + def commit(self, event, committables): "Perform RCS file checkins and modifications," - rcsdir = os.path.join(os.path.dirname(path), "RCS") - if not os.path.exists(rcsdir): - try: - os.makdirs(rcsdir) - except OSError: - raise FatalException("can't create %s." % rcsdir) - workdir = os.path.dirname(filename) - masterfile = RCS.master(filename) - exists = os.path.exists(path) - shutil.copy(copyfile, workdir) - exists = os.path.exists(path) - if exists: - fp = do_or_die("ci -m '%s'" % (event.comment)) + inargs = [] + for (path, mode, copyfile) in committables: + if mode == "160000": + announce("ignoring a submodule link %s", path) + continue + else: + inargs.append(RCS.master(path)) + rcsdir = os.path.join(os.path.dirname(path), "RCS") + if not os.path.exists(rcsdir): + try: + os.makedirs(rcsdir) + except OSError: + raise FatalException("can't create %s." % rcsdir) + if verbose >= DEBUG_SHUFFLE: + announce("copying %s to %s" \ + % (copyfile, os.path.dirname(path) or '.')) + if not dryrun: + shutil.copy(copyfile, os.path.dirname(path)) + with popen_or_die("ci " + " ".join(inargs), "checkin", "w") as fp: + fp.write(event.comment) def rename(self, source, target): "Perform RCS renames." # Dodgy, but since user is more likely to be @@ -583,7 +623,6 @@ if __name__ == '__main__': (options, arguments) = getopt.getopt(sys.argv[1:], "dlnuvV?") do_unlocked_checkouts = False checkout_mode = None - dryrun = False for (switch, val) in options: if (switch == '-?'): print __doc__ @@ -612,13 +651,12 @@ if __name__ == '__main__': announce("Tagging %s with %s" % (event.committish, event.name)) vcs.tag(event) elif isinstance(event, Commit): + committables = [] for op in event.fileops: if op.op == "M": if verbose: announce("%5d M %s" % (i+1, op.path)) - if not dryrun: - vcs.modify_file(event, - op.path, op.mode, op.copyname) + committables.append((op.path, op.mode, op.copyname)) elif op.op in ("D", "deleteall"): # If we delete masters, we lose ability to # retrieve old versions. @@ -641,6 +679,7 @@ if __name__ == '__main__': vcs.copy(ops.source, op.target) else: raise FatalException("unknown op type %s" % op.op) + vcs.commit(event, committables) vcs.checkout(checkout_mode) raise SystemExit, 0 except FatalException, e: -- 2.43.0