Class: Amp::Manifest

Inherits:
Revlog show all
Defined in:
lib/amp/revlogs/manifest.rb

Overview

Manifest

A Manifest is a special type of revision log. It stores lists of files that are being tracked, with some flags associated with each one. The manifest is where you can go to find what files a revision changed, and any extra information about the file via its flags.

Direct Known Subclasses

Bundles::BundleManifest

Constant Summary

Constants included from RevlogSupport::Node

RevlogSupport::Node::NULL_ID, RevlogSupport::Node::NULL_REV

Instance Attribute Summary collapse

Attributes inherited from Revlog

#data_file, #index, #index_file

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Revlog

#[], #add_group, #add_revision, #all_indices, #ancestor, #ancestors, #base_revision_for_index, #check_inline_size, #checksize, #children, #cmp, #data_end_for_index, #data_size_for_index, #data_start_for_index, #decompress_revision, #descendants, #each, #empty?, #files, #find_missing, #get_chunk, #group, #heads, #id_match, #link_revision_for_index, #load_cache, #lookup_id, #node_id_for_index, #nodes_between, #open, #parent_indices_for_index, #parents_for_node, #partial_id_match, #reachable_nodes_for_node, #revision_diff, #revision_index_for_node, #size, #strip, #tip, #uncompressed_size_for_index, #unified_revision_diff

Methods included from RevlogSupport::Node

#short

Methods included from Enumerable

#inject, #select_map

Constructor Details

#initialize(opener) ⇒ Manifest

Returns a new instance of Manifest.



90
91
92
93
94
# File 'lib/amp/revlogs/manifest.rb', line 90

def initialize(opener)
  @map_cache = nil
  @list_cache = nil
  super(opener, "00manifest.i")
end

Instance Attribute Details

#manifest_listObject

Returns the value of attribute manifest_list.



65
66
67
# File 'lib/amp/revlogs/manifest.rb', line 65

def manifest_list
  @manifest_list
end

Class Method Details

.parse(lines) ⇒ Object

Parses a bunch of text and interprets it as a manifest entry. It then maps them onto a ManifestEntry that stores the real info.

Parameters:

  • lines (String)

    the string that contains the information we need to parse.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/amp/revlogs/manifest.rb', line 74

def self.parse(lines)
  mf_dict = ManifestEntry.new
  
  lines.split("\n").each do |line|
    f, n = line.split("\0")
    if n.size > 40
      mf_dict.flags[f] = n[40..-1]
      mf_dict[f] = n[0..39].unhexlify
    else
      mf_dict[f] = n.unhexlify
    end
  end
  
  mf_dict
end

Instance Method Details

#add(map, journal, link, p1 = nil, p2 = nil, changed = nil) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/amp/revlogs/manifest.rb', line 165

def add(map, journal, link, p1=nil, p2=nil, changed=nil)
  if changed || changed.empty? || @list_cache ||
      @list_cache.empty? || p1.nil? || @map_cache[0] != p1
    check_forbidden map
    @list_cache = map.map {|f,n| f}.sort.map {|f| encode_file f, map }.join
    
    n = add_revision(@list_cache, journal, link, p1, p2)
    @map_cache = [n, map]
    
    return n
  end
  
  check_forbidden changed[0] # added files, check if they're forbidden
  
  mapping = Manifest.parse(@list_cache)
  
  changed[0].each do |x| 
    mapping[x] = map[x].hexlify
    mapping.flags[x] = map.flags[x]
  end
  
  changed[1].each {|x| mapping.delete x }
  @list_cache = mapping.map {|k, v| k}.sort.map {|fn| encode_file(fn, mapping)}.join
  
  n = add_revision(@list_cache, journal, link, p1, p2)
  @map_cache = [n, map]
  
  n
end

#check_forbidden(list) ⇒ Object

Checks the list for files invalid characters that aren’t allowed in filenames.

Raises:



151
152
153
154
155
156
157
158
# File 'lib/amp/revlogs/manifest.rb', line 151

def check_forbidden(list)
  list.each do |f|
    if f =~ /\n/ || f =~ /\r/
      raise RevlogSupport::RevlogError.new("\\r and \\n are disallowed in "+
                                           "filenames")
    end
  end
end

#encode_file(file, manifest) ⇒ Object



160
161
162
# File 'lib/amp/revlogs/manifest.rb', line 160

def encode_file(file, manifest)
  "#{file}\000#{manifest[file].hexlify}#{manifest.flags[file]}\n"
end

#find(node, f) ⇒ [String, String], [nil, nil]

Digs up the information about how a file changed in the revision specified by the provided node_id.

Parameters:

  • nodes (String)

    the node_id of the revision we’re interested in

  • f (String)

    the path to the file we’re interested in

Returns:

  • ([String, String], [nil, nil])

    The data stored in the manifest about the file. The first String is a digest, the second String is the extra info stored alongside the file. Returns [nil, nil] if the node is not there



138
139
140
141
142
143
144
# File 'lib/amp/revlogs/manifest.rb', line 138

def find(node, f)
  if @map_cache && node == @map_cache[0]
    return [@map_cache[1][f], @map_cache[1].flags[f]]
  end
  mapping = read(node)
  return [mapping[f],  (mapping.flags[f] || "")]
end

#read(node) ⇒ ManifestEntry

Parses the manifest’s data at a given revision’s node_id

Parameters:

  • node (String, Symbol)

    the node_id of the revision. If a symbol, it better be :tip or else shit will go down.

Returns:

  • (ManifestEntry)

    the dictionary mapping the flags, filenames, digests, etc from the parsed data



115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/amp/revlogs/manifest.rb', line 115

def read(node)
  node = tip if node == :tip
  
  return ManifestEntry.new if node == NULL_ID
  return @map_cache[1] if @map_cache && @map_cache[0] == node
  
  text = decompress_revision node
  
  @list_cache = text
  mapping = self.class.parse(text)
  @map_cache = [node, mapping]
  mapping
end

#read_delta(node) ⇒ ManifestEntry

Reads the difference between the given node and the revision before that.

Parameters:

  • node (String)

    the node_id of the revision to diff

Returns:

  • (ManifestEntry)

    the dictionary with the info between the given revision and the one before that



103
104
105
106
# File 'lib/amp/revlogs/manifest.rb', line 103

def read_delta(node)
  r = self.revision_index_for_node node
  return self.class.parse(Diffs::MercurialDiff.patch_text(self.revision_diff(r-1, r)))
end