Skip to content

Commit

Permalink
issue mhagger#18: Use internal lines instead of plain text in checkou…
Browse files Browse the repository at this point in the history
…t_db.

As the return value of RCSStream.invert_diff() is not to be applied
for flat text content but for internal logical lines in RCSStream,
which may contain some unterminated logical lines at any position,
so we should use the content of internal logical lines in RCSStream
as base text which is used to get the content of the next newer revision.
With this commit, it is implemented by splitting the checkout() method
in TextRecord, checkout() method for external use for as in the past
and checkout_as_lines() method for internal use.

* cvs2svn_lib/checkout_internal.py
  (TextRecord.checout_as_lines): New method. Replacement of checkout()
    method but returns internal lines in RCSStream instead of a plain
    text.
  (TextRecord.checkout):
    Use checkout_as_lines() for default implementation.
  (FullTextRecord.checkout, DeltaTextRecord.checkout):
    Removed to use default implementation.
  (FullTextRecord.checkout_as_lines):
    New method. Just same logic as the past checkout() method.
  (DeltaTextRecord.checkout_as_lines):
    New method. Just same logic as the past checkout() method but
    uses internal lines in rcs_stream instead of its text.
  (_Sink.set_revision_info):
    Record the internal lines in rcs_stream instead of its text
    at revision 1.1.

* cvs2svn_lib/rcs_stream.py
  (RCSStream.__init__):
    Allow to set lines directly in addition to a text.
  (RCSStream.get_lines):
    New method.
  • Loading branch information
futatuki committed Dec 20, 2021
1 parent f32ce3e commit ae478af
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 18 deletions.
41 changes: 24 additions & 17 deletions cvs2svn_lib/checkout_internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,22 @@ def decrement_refcount(self, text_record_db):
if self.refcount == 0:
text_record_db.discard(self.id)

def checkout(self, text_record_db):
def checkout_as_lines(self, text_record_db):
"""Workhorse of the checkout process.
Return the text for this revision, decrement our reference count,
and update the databases depending on whether there will be future
checkouts."""
Return the text for this revision as list of logical lines,
decrement our reference count, and update the databases depending
on whether there will be future checkouts."""

raise NotImplementedError()

def checkout(self, text_record_db):
"""Return the text for this revision.
Just same as checkout_as_lines() but returns text as flat text string."""

return "".join(self.checkout_as_lines(text_record_db))

def free(self, text_record_db):
"""This instance will never again be checked out; free it.
Expand All @@ -168,10 +175,10 @@ def __getstate__(self):
def __setstate__(self, state):
(self.id, self.refcount,) = state

def checkout(self, text_record_db):
text = text_record_db.delta_db[self.id]
def checkout_as_lines(self, text_record_db):
lines = text_record_db.delta_db[self.id]
self.decrement_refcount(text_record_db)
return text
return lines

def free(self, text_record_db):
del text_record_db.delta_db[self.id]
Expand Down Expand Up @@ -205,12 +212,12 @@ def __setstate__(self, state):
def increment_dependency_refcounts(self, text_record_db):
text_record_db[self.pred_id].refcount += 1

def checkout(self, text_record_db):
base_text = text_record_db[self.pred_id].checkout(text_record_db)
rcs_stream = RCSStream(base_text)
def checkout_as_lines(self, text_record_db):
base_lines = text_record_db[self.pred_id].checkout_as_lines(text_record_db)
rcs_stream = RCSStream(base_lines)
delta_text = text_record_db.delta_db[self.id]
rcs_stream.apply_diff(delta_text)
text = rcs_stream.get_text()
lines = rcs_stream.get_lines()
del rcs_stream
self.refcount -= 1
if self.refcount == 0:
Expand All @@ -220,11 +227,11 @@ def checkout(self, text_record_db):
del text_record_db[self.id]
else:
# Store a new CheckedOutTextRecord in place of ourselves:
text_record_db.checkout_db['%x' % self.id] = text
text_record_db.checkout_db['%x' % self.id] = lines
new_text_record = CheckedOutTextRecord(self.id)
new_text_record.refcount = self.refcount
text_record_db.replace(new_text_record)
return text
return lines

def free(self, text_record_db):
del text_record_db.delta_db[self.id]
Expand All @@ -251,10 +258,10 @@ def __getstate__(self):
def __setstate__(self, state):
(self.id, self.refcount,) = state

def checkout(self, text_record_db):
text = text_record_db.checkout_db['%x' % self.id]
def checkout_as_lines(self, text_record_db):
lines = text_record_db.checkout_db['%x' % self.id]
self.decrement_refcount(text_record_db)
return text
return lines

def free(self, text_record_db):
del text_record_db.checkout_db['%x' % self.id]
Expand Down Expand Up @@ -533,7 +540,7 @@ def set_revision_info(self, revision, log, text):
# This is revision 1.1. Write its fulltext:
text_record = FullTextRecord(cvs_rev_id)
self.revision_collector._writeout(
text_record, self._rcs_stream.get_text()
text_record, self._rcs_stream.get_lines()
)

# There will be no more trunk revisions delivered, so free the
Expand Down
10 changes: 9 additions & 1 deletion cvs2svn_lib/rcs_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,21 @@ class RCSStream:
def __init__(self, text):
"""Instantiate and initialize the file content with TEXT."""

self.set_text(text)
if isinstance(text, bytes):
self.set_text(text)
else:
self.set_lines(text)

def get_text(self):
"""Return the current file content."""

return "".join(self._lines)

def get_lines(self):
"""Return the current file content as list of logical lines."""

return self._lines

def set_lines(self, lines):
"""Set the current contents to the specified LINES.
Expand Down

0 comments on commit ae478af

Please sign in to comment.