self.fileops = [] # blob and file operation list
self.properties = {} # commit properties (extension)
self.taglist = [] # Tags that point at this commit
- self.branchlist = [] # Branches that point at this commit
+ self.resetlist = [] # Branches that point at this commit
+ self.childbranches = [] # Count of child branches at this point.
def children(self):
"Get a list of this commit's children."
return filter(lambda e:self.mark in e.parent_marks,self.repo.commits())
+ def parents(self):
+ "Get a list of this commit's parents."
+ return filter(lambda e:e.mark in self.parent_marks,self.repo.commits())
def is_tip(self):
"Is this commit a branch tip?"
for child in self.children():
elif isinstance(event, Reset) and event.committish is not None:
for commit in self.commits():
if commit.mark == event.committish:
- commit.branchlist.append(tag)
+ # FIXME: Not yet used for anything
+ commit.resetlist.append(tag)
break
else:
raise FatalException("reset points at nonexistent %s"
"Class encapsulating RCS version-control operations."
repodirectory = "RCS"
mastertemplate = "%s,v"
- def gethdr(self, path, header):
- "Retrieve a required header from a master file"
- master = self.master(path)
- for line in file(master):
- if line.startswith(header):
- value = line.split()[1].strip()
- if value.endswith(";"):
- value = value[:-1]
- return value
- raise FatalException("missing '%s' in %s" % (header, master))
+ def __init__(self):
+ Generic.__init__(self)
+ self.branch_tips = {}
def sanecheck(self, event, path, mode, copyfile):
if mode == "160000":
raise FatalException("ignoring a submodule link %s", path)
raise FatalException("unknown mode %s on %s", (mode, path))
def checkin(self, commit, comment, op, path):
"Check in a new revision - also used to create new masters."
- command = "ci -l"
+ # This is the only manipulation of the branch structure there is.
+ parents = commit.parents()
+ if not os.path.exists(self.master(path)):
+ myrev = "1.1"
+ else:
+ 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:
+ # Not going down a branch point. Just bump the last
+ # field of the tip revision.
+ fields = map(int, tip.split("."))
+ fields[-1] += 1
+ myrev = ".".join(map(str, fields))
+ 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 + "." + `branchnum` + ".1"
+ print "**** Assigning", myrev, "to", (path, commit.branch)
+ self.branch_tips[(path, commit.branch)] = myrev
+ # Branch hackery ends here
+ command = "ci -l%s" % myrev
if op == "D":
command += " -sDeleted"
command += " -d'%s'" % event.committer.date.rfc822()
command += ' -m"%s"' % comment.replace('"', '\\"')
command += " " + path + " " + self.master(path)
return command
- def checkout(self, source, branch):
- "Check out the latest revision correspinding to path and branch"
- # FIXME: not presently adjusted for commit's branch
- return "co %s" % self.master(source)
+ 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))
def postcommit(self, event):
# Save annotated tags for round-tripping
for tag in event.taglist: