diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2010-11-24 19:36:34 +0100 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2010-11-24 19:37:06 +0100 |
commit | 98a313305f0d554a179b93695d333199feb5266c (patch) | |
tree | 853a7029fa8c532da110b11afc2b60027e267625 | |
parent | 86523260c495d9a29aa5ab29d50d30a5d1981a0c (diff) | |
download | gitpython-98a313305f0d554a179b93695d333199feb5266c.tar.gz |
RefLog: added entry_at method, which is a faster way of reading single entries, including test
-rw-r--r-- | doc/source/changes.rst | 1 | ||||
-rw-r--r-- | refs/log.py | 31 | ||||
-rw-r--r-- | refs/symbolic.py | 9 | ||||
-rw-r--r-- | repo/fun.py | 2 | ||||
-rw-r--r-- | test/test_reflog.py | 13 |
5 files changed, 55 insertions, 1 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 5d6848eb..7b959532 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -15,6 +15,7 @@ Changelog * ``log_append(...)`` method added * ``set_reference(...)`` method added (reflog support) * ``set_commit(...)`` method added (reflog support) + * ``set_object(...)`` method added (reflog support) * Intrusive Changes to ``Head`` type diff --git a/refs/log.py b/refs/log.py index 129803b4..6c734ad4 100644 --- a/refs/log.py +++ b/refs/log.py @@ -173,6 +173,37 @@ class RefLog(list, Serializable): return yield new_entry(line.strip()) #END endless loop + + @classmethod + def entry_at(cls, filepath, index): + """:return: RefLogEntry at the given index + :param filepath: full path to the index file from which to read the entry + :param index: python list compatible index, i.e. it may be negative to + specifiy an entry counted from the end of the list + + :raise IndexError: If the entry didn't exist + .. note:: This method is faster as it only parses the entry at index, skipping + all other lines. Nonetheless, the whole file has to be read if + the index is negative + """ + fp = open(filepath, 'rb') + if index < 0: + return RefLogEntry.from_line(fp.readlines()[index].strip()) + else: + # read until index is reached + for i in xrange(index+1): + line = fp.readline() + if not line: + break + #END abort on eof + #END handle runup + + if i != index or not line: + raise IndexError + #END handle exception + + return RefLogEntry.from_line(line.strip()) + #END handle index def to_file(self, filepath): """Write the contents of the reflog instance to a file at the given filepath. diff --git a/refs/symbolic.py b/refs/symbolic.py index f333bd46..6ba8083f 100644 --- a/refs/symbolic.py +++ b/refs/symbolic.py @@ -354,6 +354,15 @@ class SymbolicReference(object): (newbinsha is None and self.commit.binsha) or newbinsha, message) + def log_entry(self, index): + """:return: RefLogEntry at the given index + :param index: python list compatible positive or negative index + + .. note:: This method must read part of the reflog during execution, hence + it should be used sparringly, or only if you need just one index. + In that case, it will be faster than the ``log()`` method""" + return RefLog.entry_at(RefLog.path(self), index) + @classmethod def to_full_path(cls, path): """ diff --git a/repo/fun.py b/repo/fun.py index aa938477..c523a3e1 100644 --- a/repo/fun.py +++ b/repo/fun.py @@ -191,7 +191,7 @@ def rev_parse(repo, rev): #END handle revlog index try: - entry = ref.log()[revlog_index] + entry = ref.log_entry(revlog_index) except IndexError: raise BadObject("Invalid revlog index: %i" % revlog_index) #END handle index out of bound diff --git a/test/test_reflog.py b/test/test_reflog.py index 520be590..5c4a21b8 100644 --- a/test/test_reflog.py +++ b/test/test_reflog.py @@ -79,6 +79,19 @@ class TestRefLog(TestBase): assert entry.newhexsha == 'f'*40 assert entry.message == msg assert RefLog.from_file(tfile)[-1] == entry + + # index entry + # raises on invalid index + self.failUnlessRaises(IndexError, RefLog.entry_at, rlp, 10000) + + # indices can be positive ... + assert isinstance(RefLog.entry_at(rlp, 0), RefLogEntry) + RefLog.entry_at(rlp, 23) + + # ... and negative + for idx in (-1, -24): + RefLog.entry_at(rlp, idx) + #END for each index to read # END for each reflog |