Class: Amp::VersionedFile
- Includes:
- RevlogSupport::Node
- Defined in:
- lib/amp/repository/versioned_file.rb
Overview
This class allows you to access a file at a given revision in the repo’s history. You can compare them, sort them, access the changeset, and all sorts of stuff.
Direct Known Subclasses
Constant Summary
Constants included from RevlogSupport::Node
RevlogSupport::Node::NULL_ID, RevlogSupport::Node::NULL_REV
Instance Attribute Summary collapse
-
#change_id ⇒ Object
The revision index into the history of the repository.
-
#file_id ⇒ Object
Returns the value of attribute file_id.
-
#path ⇒ Object
The path to this file.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
-
#==(other) ⇒ Object
Equality! Compares paths and revision indexes.
-
#===(other) ⇒ Boolean
Just the opposite of #cmp.
- #ancestor(file_2) ⇒ Object
- #annotate(follow_copies = false, line_number = false) ⇒ Object
- #annotate_decorate(text, revision, line_number = false) ⇒ Object
- #annotate_diff_pair(parent, child) ⇒ Object
- #annotate_get_file(path, file_id) ⇒ Object
- #annotate_parents_helper(file, follow_copies = false) ⇒ Object
-
#branch ⇒ Object
The branch this tracked file belongs to.
-
#changeset ⇒ Changeset
Returns the changeset that this file belongs to.
-
#children ⇒ Object
What are this file’s children?.
-
#cmp(text) ⇒ Object
Compares to a bit of text.
-
#data ⇒ Object
The data in this file.
-
#date ⇒ Object
Date this revision to this file was committed.
-
#description ⇒ Object
The description of the commit that contained this file revision.
-
#file(file_id) ⇒ Object
Retrieves the file with a different ID.
-
#file_log ⇒ FileLog
The file log that tracks this file.
- #file_node ⇒ Object
-
#file_rev ⇒ Object
Returns the index into the file log’s history for this file.
-
#files ⇒ Object
All files in this changeset that this revision of this file was committed.
-
#flags ⇒ Object
Gets the flags for this file (x and l).
- #get_parents_helper(vertex, ancestor_cache, filelog_cache) ⇒ Object
-
#hash ⇒ Object
Hash value for sticking this fucker in a hash.
-
#initialize(repo, path, opts = {}) ⇒ VersionedFile
constructor
Creates a new VersionedFile.
-
#inspect ⇒ Object
IRB Inspector string representation.
-
#linkrev ⇒ Object
Link-revision index.
-
#manifest ⇒ Object
THe manifest that this file revision is from.
-
#nil? ⇒ Boolean
Is this a null version?.
-
#node ⇒ Object
Node ID for this file’s revision.
-
#parents ⇒ Object
What are this revised file’s parents? Return them as VersionedFiles.
-
#renamed ⇒ Object
Has this file been renamed? If so, return some useful info.
-
#repo_path ⇒ Object
Dunno why this is here.
-
#revision ⇒ Object
Returns the revision index.
-
#size ⇒ Object
The size of this file.
- #to_i ⇒ Object
-
#to_s ⇒ Object
String representation.
-
#user ⇒ Object
User who committed this revision to this file.
Methods included from RevlogSupport::Node
Constructor Details
#initialize(repo, path, opts = {}) ⇒ VersionedFile
Creates a new Amp::VersionedFile. You need to pass in the repo and the path to the file, as well as one of the following: a revision index/ID, the node_id of the file’s revision in the filelog, or a changeset at a given index.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/amp/repository/versioned_file.rb', line 31 def initialize(repo, path, opts={}) @repo, @path = repo, path raise StandardError.new("specify a revision!") unless opts[:change_id] || opts[:file_id] || opts[:changeset] @file_log = opts[:file_log] if opts[:file_log] @change_id = opts[:change_id] if opts[:change_id] @changeset = opts[:changeset] if opts[:changeset] @file_id = opts[:file_id] if opts[:file_id] end |
Instance Attribute Details
#change_id ⇒ Object
The revision index into the history of the repository. Could also be a node_id
77 78 79 80 81 |
# File 'lib/amp/repository/versioned_file.rb', line 77 def change_id @change_id ||= @changeset.revision if @changeset @change_id ||= file_log[file_rev].link_rev unless @changeset @change_id end |
#file_id ⇒ Object
Returns the value of attribute file_id.
11 12 13 |
# File 'lib/amp/repository/versioned_file.rb', line 11 def file_id @file_id end |
#path ⇒ Object
The path to this file
162 |
# File 'lib/amp/repository/versioned_file.rb', line 162 def path; @path; end |
Instance Method Details
#<=>(other) ⇒ Object
43 44 45 |
# File 'lib/amp/repository/versioned_file.rb', line 43 def <=>(other) to_i <=> other.to_i end |
#==(other) ⇒ Object
Equality! Compares paths and revision indexes
121 122 123 124 |
# File 'lib/amp/repository/versioned_file.rb', line 121 def ==(other) return false unless @path && @file_id && other.path && other.file_id @path == other.path && @file_id == other.file_id end |
#===(other) ⇒ Boolean
Just the opposite of #cmp
179 180 181 |
# File 'lib/amp/repository/versioned_file.rb', line 179 def ===(other) !self.cmp(other.data) end |
#ancestor(file_2) ⇒ Object
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/amp/repository/versioned_file.rb', line 330 def ancestor(file_2) ancestor_cache = {} [self, file_2].each do |c| if c.file_rev == NULL_REV || c.file_rev.nil? parent_list = c.parents.map {|n| [n.path, n.file_node]} ancestor_cache[[c.path, c.file_node]] = parent_list end end filelog_cache = {repo_path => file_log, file_2.repo_path => file_2.file_log} a, b = [path, file_node], [file_2.path, file_2.file_node] parents_proc = proc {|vertex| get_parents_helper(vertex, ancestor_cache, filelog_cache)} v = Graphs::AncestorCalculator.ancestors(a, b, parents_proc) if v file, node = v return VersionedFile.new(@repo, file, :file_id => node, :file_log => filelog_cache[file]) end return nil end |
#annotate(follow_copies = false, line_number = false) ⇒ Object
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/amp/repository/versioned_file.rb', line 265 def annotate(follow_copies = false, line_number = false) base = (revision != linkrev) ? file(file_rev) : self needed = {base => 1} counters = {(base.path + base.file_id.to_s) => 1} visit = [base] files = [base.path] while visit.any? file = visit.shift annotate_parents_helper(file).each do |p| unless needed.include? p needed[p] = 1 counters[p.path + p.file_id.to_s] = 1 visit << p files << p.path unless files.include? p.path end end end visit = [] files.each do |f| filenames = needed.keys.select {|k| k.path == f}.map {|n| [n.revision, n]} visit += filenames end hist = {} lastfile = "" visit.sort.each do |rev, file_ann| curr = annotate_decorate(file_ann.data, file_ann, line_number) annotate_parents_helper(file_ann).each do |p| next if p.file_id == NULL_ID curr = annotate_diff_pair(hist[p.path + p.file_id.to_s], curr) counters[p.path + p.file_id.to_s] -= 1 hist.delete(p.path + p.file_id.to_s) if counters[p.path + p.file_id.to_s] == 0 end hist[file_ann.path+file_ann.file_id.to_s] = curr lastfile = file_ann end returnarr = [] hist[lastfile.path+lastfile.file_id.to_s].inspect # force all lazy-loading to stoppeth ret = hist[lastfile.path+lastfile.file_id.to_s][0].each_with_index do |obj, i| returnarr << obj + [hist[lastfile.path+lastfile.file_id.to_s][1].split_newlines[i]] end # hist[lastfile.path+lastfile.file_id.to_s][0][i] + hist[lastfile.path+lastfile.file_id.to_s][1].split_newlines[i] # end ret = hist[lastfile.path+lastfile.file_id.to_s][0].zip(hist[lastfile.path+lastfile.file_id.to_s][1].split_newlines) returnarr end |
#annotate_decorate(text, revision, line_number = false) ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/amp/repository/versioned_file.rb', line 225 def annotate_decorate(text, revision, line_number = false) if line_number size = text.split("\n").size retarr = [nil,text] retarr[0] = (1..size).map {|i| [revision, i]} else retarr = [nil, text] retarr[0] = [[revision, false]] * text.split("\n").size end retarr end |
#annotate_diff_pair(parent, child) ⇒ Object
237 238 239 240 241 242 |
# File 'lib/amp/repository/versioned_file.rb', line 237 def annotate_diff_pair(parent, child) Diffs::BinaryDiff.blocks_as_array(parent[1], child[1]).each do |a1,a2,b1,b2| child[0][b1..(b2-1)] = parent[0][a1..(a2-1)] end child end |
#annotate_get_file(path, file_id) ⇒ Object
244 245 246 247 |
# File 'lib/amp/repository/versioned_file.rb', line 244 def annotate_get_file(path, file_id) log = (path == @path) ? file_log : @repo.get_file(path) return VersionedFile.new(@repo, path, :file_id => file_id, :file_log => log) end |
#annotate_parents_helper(file, follow_copies = false) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/amp/repository/versioned_file.rb', line 249 def annotate_parents_helper(file, follow_copies = false) path = file.path if file.file_rev.nil? parent_list = file.parents.map {|n| [n.path, n.file_rev]} else parent_list = file.file_log.parent_indices_for_index(file.file_rev) parent_list.map! {|n| [path, n]} end if follow_copies r = file.renamed pl[0] = [r[0], @repo.get_file(r[0]).revision(r[1])] if r end return parent_list.select {|p, n| n != NULL_REV}. map {|p, n| annotate_get_file(p, n)} end |
#branch ⇒ Object
The branch this tracked file belongs to
156 |
# File 'lib/amp/repository/versioned_file.rb', line 156 def branch; changeset.branch; end |
#changeset ⇒ Changeset
Returns the changeset that this file belongs to
55 56 57 |
# File 'lib/amp/repository/versioned_file.rb', line 55 def changeset @changeset ||= Changeset.new @repo, change_id end |
#children ⇒ Object
What are this file’s children?
218 219 220 221 222 223 |
# File 'lib/amp/repository/versioned_file.rb', line 218 def children c = file_log.children(file_node) c.map do |x| VersionedFile.new(@repo, @path, :file_id => x, :file_log => file_log) end end |
#cmp(text) ⇒ Object
Compares to a bit of text. Returns true if different, false for the same. (much like <=> == 0 for the same)
170 171 172 |
# File 'lib/amp/repository/versioned_file.rb', line 170 def cmp(text) file_log.cmp(file_node, text) end |
#data ⇒ Object
The data in this file
160 |
# File 'lib/amp/repository/versioned_file.rb', line 160 def data; file_log.read(file_node); end |
#date ⇒ Object
Date this revision to this file was committed
150 |
# File 'lib/amp/repository/versioned_file.rb', line 150 def date; changeset.date; end |
#description ⇒ Object
The description of the commit that contained this file revision
154 |
# File 'lib/amp/repository/versioned_file.rb', line 154 def description; changeset.description; end |
#file(file_id) ⇒ Object
Retrieves the file with a different ID
130 131 132 |
# File 'lib/amp/repository/versioned_file.rb', line 130 def file(file_id) self.class.new @repo, @path, :file_id => file_id, :file_log => file_log end |
#file_log ⇒ FileLog
The file log that tracks this file
70 71 72 |
# File 'lib/amp/repository/versioned_file.rb', line 70 def file_log @file_log ||= @repo.file @path end |
#file_node ⇒ Object
83 84 85 86 87 |
# File 'lib/amp/repository/versioned_file.rb', line 83 def file_node @file_node ||= file_log.lookup_id(@file_id) if @file_id @file_node ||= changeset.file_node(@path) unless @file_id @file_node ||= NULL_ID end |
#file_rev ⇒ Object
Returns the index into the file log’s history for this file
91 92 93 |
# File 'lib/amp/repository/versioned_file.rb', line 91 def file_rev @file_rev ||= file_log.rev(file_node) end |
#files ⇒ Object
All files in this changeset that this revision of this file was committed
152 |
# File 'lib/amp/repository/versioned_file.rb', line 152 def files; changeset.files; end |
#flags ⇒ Object
Gets the flags for this file (x and l)
135 |
# File 'lib/amp/repository/versioned_file.rb', line 135 def flags; changeset.flags(@path); end |
#get_parents_helper(vertex, ancestor_cache, filelog_cache) ⇒ Object
315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/amp/repository/versioned_file.rb', line 315 def get_parents_helper(vertex, ancestor_cache, filelog_cache) return ancestor_cache[vertex] if ancestor_cache[vertex] file, node = vertex filelog_cache[file] = @repo.get_file(file) unless filelog_cache[file] filelog = filelog_cache[file] parent_list = filelog.parents(node).select {|p| p != NULL_ID}.map {|p| [file, p]} has_renamed = filelog.renamed(node) parent_list << has_renamed if has_renamed ancestor_cache[vertex] = parent_list parent_list end |
#hash ⇒ Object
Hash value for sticking this fucker in a hash
115 116 117 |
# File 'lib/amp/repository/versioned_file.rb', line 115 def hash return (path + file_id.to_s).hash end |
#inspect ⇒ Object
IRB Inspector string representation
109 110 111 |
# File 'lib/amp/repository/versioned_file.rb', line 109 def inspect "#<Versioned File: #{to_s}>" end |
#linkrev ⇒ Object
Link-revision index
144 |
# File 'lib/amp/repository/versioned_file.rb', line 144 def linkrev; file_log[file_rev].link_rev; end |
#manifest ⇒ Object
THe manifest that this file revision is from
158 |
# File 'lib/amp/repository/versioned_file.rb', line 158 def manifest; changeset.manifest; end |
#nil? ⇒ Boolean
Is this a null version?
97 98 99 |
# File 'lib/amp/repository/versioned_file.rb', line 97 def nil? file_node.nil? end |
#node ⇒ Object
Node ID for this file’s revision
146 |
# File 'lib/amp/repository/versioned_file.rb', line 146 def node; changeset.node; end |
#parents ⇒ Object
What are this revised file’s parents? Return them as Amp::VersionedFiles.
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/amp/repository/versioned_file.rb', line 203 def parents p = @path fl = file_log pl = file_log.parents(file_node).map {|n| [p, n, fl]} r = file_log.renamed(file_node) pl[0] = [r[0], r[1], nil] if r pl.select {|parent,n,l| n != NULL_ID}.map do |parent, n, l| VersionedFile.new(@repo, parent, :file_id => n, :file_log => l) end end |
#renamed ⇒ Object
Has this file been renamed? If so, return some useful info
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/amp/repository/versioned_file.rb', line 185 def renamed renamed = file_log.renamed(file_node) return renamed unless renamed return renamed if rev == linkrev name = path fnode = file_node changeset.parents.each do |p| pnode = p.filenode(name) next if pnode.nil? return nil if fnode == pnode end renamed end |
#repo_path ⇒ Object
Dunno why this is here
62 63 64 |
# File 'lib/amp/repository/versioned_file.rb', line 62 def repo_path @path end |
#revision ⇒ Object
Returns the revision index
138 139 140 141 |
# File 'lib/amp/repository/versioned_file.rb', line 138 def revision return changeset.rev if @changeset || @change_id file_log[file_rev].link_rev end |
#size ⇒ Object
The size of this file
164 |
# File 'lib/amp/repository/versioned_file.rb', line 164 def size; file_log.size(file_rev); end |
#to_i ⇒ Object
47 48 49 |
# File 'lib/amp/repository/versioned_file.rb', line 47 def to_i change_id end |
#to_s ⇒ Object
String representation.
103 104 105 |
# File 'lib/amp/repository/versioned_file.rb', line 103 def to_s "#{path}@#{node.hexlify[0..11]}" end |
#user ⇒ Object
User who committed this revision to this file
148 |
# File 'lib/amp/repository/versioned_file.rb', line 148 def user; changeset.user; end |