os.makedirs(self.__class__.repodirectory)
except OSError:
raise FatalException("can't create RCS directory.")
+ self.branch_tips = {}
+ def get_tip(self, path, branch):
+ "Get the tip ID for a patch/branch combination that already exists."
+ return self.branch_tips[(path, branch)]
+ def make_tip(self, commit, path):
+ "Make a new tip ID for a given path and branch."
+ # This is the only manipulation of the branch structure there is.
+ if not os.path.exists(self.master(path)):
+ myrev = self.revfactory()
+ else:
+ parents = commit.parents()
+ if len(parents) > 1:
+ complain("cannot preserve merge information.")
+ # 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.
+ myrev = tip.successor()
+ else:
+ # Going down a branch point.
+ if commit.branch not in parents[0].childbranches:
+ parents[0].childbranches.append(commit.branch)
+ branchnum = parents[0].childbranches.index(commit.branch) + 1
+ myrev = tip.branch(branchnum)
+ if verbose >= DEBUG_BRANCHING:
+ print "Assigning", myrev, "to", path
+ self.branch_tips[(path, commit.branch)] = myrev
+ return myrev
def master(self, filename):
"Return the master file corresponding to a specified filename."
parts = list(os.path.split(filename))
"Class encapsulating RCS version-control operations."
repodirectory = "RCS"
mastertemplate = "%s,v"
+ revfactory = RCSRev
def __init__(self):
Generic.__init__(self)
- self.branch_tips = {}
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.
- if not os.path.exists(self.master(path)):
- myrev = RCSRev()
- else:
- parents = commit.parents()
- if len(parents) > 1:
- complain("RCS cannot preserve merge information.")
- # 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.
- myrev = tip.successor()
- else:
- # Going down a branch point.
- if commit.branch not in parents[0].childbranches:
- parents[0].childbranches.append(commit.branch)
- branchnum = parents[0].childbranches.index(commit.branch) + 1
- myrev = tip.branch(branchnum)
- 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
+ command = "ci -l%s" % self.make_tip(commit, path)
if op == "D":
command += " -sDeleted"
command += " -d'%s'" % event.committer.date.rfc822()
return command
def checkout(self, path, branch):
"Check out the latest revision corresponding to path and branch"
- return "co -r%s %s" \
- % (self.branch_tips[(path, branch)], self.master(path))
+ return "co -r%s %s" % (self.get_tip(path, branch), self.master(path))
def postcommit(self, event):
# Save annotated tags for round-tripping
for tag in event.taglist: