Commits

ZyX_I committed 10d78e7

@aurum/drivers/svn: Added rf-revrange(), rf-updatechangesets() and rf-getchangesets() implementations (untested)

Comments (0)

Files changed (2)

 Repository is a dictionary containing at least the following keys:
 
 cslist :: [ cs ]                                           *aurum-repo.cslist*
-    List of |aurum-changeset| objects. If it is not empty, then for each 
-    changeset in repository cs is repo.cslist[cs.rev] unless cs.rev is not 
-    String. It is empty by default and may be populated only when you call 
-    |aurum-rf-getchangesets|. See also |aurum-cs.rev|.
+    List of |aurum-changeset| objects. It is empty by default and may be 
+    populated only when you call |aurum-rf-getchangesets|. See also 
+    |aurum-cs.rev|.
     Obsolete, use |aurum-rf-revrange|.
 changesets :: {hex : cs}                               *aurum-repo.changesets*
     Dictionary containing all |aurum-changeset| objects that are associated 
     a string.
 |aurum-cs.renames| and |aurum-cs.copies| are always empty.
 |aurum-cs.time| is always 0 if “date” programm from coreutils is missing.
+|aurum-cs.hex| contains the stringified value of |aurum-cs.rev| and thus is 
+    not fixed-length.
+|auurm-repo.cslist|: repo.cslist[cs.rev] is any revision with .rev≥cs.rev, not 
+    necessary cs itself.
 |aurum-rf-diff|: Options "git", "iblanks", "dates", "alltext" are not 
     supported, option "reverse" is supported only if two revisions are given.
 

plugin/aurum/drivers/svn.vim

             \           'with “Revision: ” in the output of “svn info”',
             \  'ndate': 'You must install “date” programm in order to get '.
             \           'time information for Subversion revisions',
+            \  'r2fst': 'Second revision was found before the first',
         \}
 let s:svn={}
 "▶1 s:hypsites
             \'branch': 'default',
             \'renames': {},
             \'copies': {},
+            \'tags': [],
+            \'bookmarks': [],
         \}
 let s:hasdateexe=executable('date')
 " TODO HEAD, ... in cs.tags
     if a:csdata[line] isnot# '</logentry>'
         call s:_f.throw('perr', '</logentry>', a:csdata[line])
     endif
+    let line+=1
     "▲2
     return [cs, line]
 endfunction
-"▶1 svn.getchangesets :: repo → []
-function s:svn.getchangesets(repo, ...)
+"▶1 getchangesets :: repo → [cs]
+function s:F.getchangesets(repo, ...)
     let args=[]
-    let kwargs={}
-    let log=s:F.svn(a:repo, 'log', args, kwargs, 0, 'logf')
+    let kwargs={'xml': 1}
+    if a:0==1
+        if type(a:1)==type(0)
+            let kwargs.limit=''.a:1
+        else
+            let kwargs.revision=a:1
+        endif
+    elseif a:0==2
+        let kwargs.revision=a:1.':'.a:2
+    endif
+    let log=s:F.svn(a:repo, 'log', args, kwargs, 0, 'logf')[2:-3]
     let cslist=[]
     let llog=len(log)
     let line=0
-    while i<llog
+    while line<llog
         let [cs, line]=s:F.parsecs(log, line)
-        let cslist+=[cs]
+        call insert(a:repo.cslist, cs)
         let a:repo.changesets[cs.hex]=cs
     endwhile
-    if !a:0
-        let a:repo.cslist=copy(cslist)
-    endif
     return cslist
 endfunction
+"▶1 svn.getchangesets :: repo → [cs]
+function s:svn.getchangesets(repo)
+    if empty(a:repo.cslist)
+        let cslist=s:F.getchangesets(a:repo)
+        call map(cslist, 'extend(v:val, {"parents": '.
+                    \'(v:key ? [cslist[v:key-1]] : [])})')
+        " TODO children
+        let a:repo.cslist+=cslist
+    else
+        call a:repo.functions.updatechangesets(a:repo)
+    endif
+    return a:repo.cslist
+endfunction
 "▶1 svn.updatechangesets :: repo → _
-let s:svn.updatechangesets=s:svn.getchangesets
+function s:svn.updatechangesets(repo)
+    let oldtiphex=a:repo.cslist[-1].hex
+    let tiphex=a:repo.functions.gettiphex(a:repo)
+    if tiphex<oldtiphex
+        call remove(a:repo.cslist, +tiphex, -1)
+    elseif tiphex>oldtiphex
+        let cslist=a:repo.functions.revrange(a:repo, oldtiphex, tiphex)
+        call map(cslist, 'extend(v:val, {"parents": '.
+                    \'(v:key ? [cslist[v:key-1]] : [oldtiphex])})')
+        " TODO children
+        let a:repo.cslist+=cslist
+    endif
+endfunction
 "▶1 svn.revrange :: repo, rev1, rev2 → [cs]
-let s:svn.revrange=s:svn.getchangesets
+function s:svn.revrange(repo, rev1, rev2)
+    if a:rev1 is 0 && a:rev2 is -1
+        return a:repo.functions.getchangesets(a:repo)
+    elseif a:rev2 is -1 && type(a:rev1)==type(0) && a:rev1<0
+        if empty(a:repo.cslist)
+            return s:F.getchangesets(a:repo, -a:rev1)
+        else
+            return a:repo.functions.getchangesets(a:repo)[(a:rev1):]
+        endif
+    elseif a:rev1 is 0
+        if type(a:rev2)==type(0)
+            return a:repo.functions.getchangesets(a:repo)[:(a:rev2)]
+        elseif empty(a:repo.cslist)
+            return s:F.getchangesets(a:repo, a:rev2)
+        else
+            call a:repo.functions.updatechangesets(a:repo)
+            let rev2=a:repo.functions.getrevhex(a:repo, a:rev2)
+            let i=len(a:repo.cslist)-1
+            while i>=0 && a:repo.cslist[i].hex isnot# rev2
+                let i-=1
+            endwhile
+            return a:repo.cslist[:(i)]
+        endif
+    elseif empty(a:repo.cslist)
+        return s:F.getchangesets(a:repo, a:rev1, a:rev2)
+    else
+        call a:repo.functions.updatechangesets(a:repo)
+        let rev1=a:repo.functions.getrevhex(a:repo, a:rev1)
+        let rev2=a:repo.functions.getrevhex(a:repo, a:rev2)
+        let i=len(a:repo.cslist)-1
+        while i>=0 && a:repo.cslist[i].hex isnot# rev1
+            if a:repo.cslist[i].hex is# rev2
+                let r2i=i
+            endif
+            let i-=1
+        endwhile
+        if !exists('r2i')
+            call s:_f.throw('r2fst', a:rev2, a:rev1)
+        endif
+        return a:repo.cslist[(i):(r2i)]
+    endif
+endfunction
 "▶1 svn.getcs :: repo, rev → cs
 function s:svn.getcs(repo, rev)
     let cs=s:F.parsecs(s:F.svn(a:repo, 'log', [],