class GitDS::Index

# ============================================================================= A Git Index.

Public Instance Methods

add(path, data, on_fs=false) click to toggle source
Calls superclass method
# File lib/git-ds/index.rb, line 71
def add(path, data, on_fs=false)
  super(path, data)
  add_fs_item(path, data) if on_fs
end
Also aliased as: add_db
add_db(path, data, on_fs=false)

Add a DB entry at the virtual path ‘path’ with contents ‘contents’

Alias for: add
add_fs(path, data) click to toggle source

Convenience function to add an on-filesystem object.

# File lib/git-ds/index.rb, line 79
def add_fs(path, data)
  add(path, data, true)
end
delete(path) click to toggle source

Wrapper for Grit::Index#delete that removes the file if it exists on the filesystem.

Calls superclass method
# File lib/git-ds/index.rb, line 87
def delete(path)
  super
  @repo.exec_in_git_dir {
    ::FileUtils.remove_entry(path) if ::File.exist?(path)
  }
end
include?(path) click to toggle source

Return true if index includes path.

# File lib/git-ds/index.rb, line 97
def include?(path)
  path_to_object(path) ? true : false
end
local_write_tree(tree, now_tree=nil) click to toggle source

Re-implemented from Grit. Grit adds a trailing / to directory names, which makes it impossible to delete Tree objects!

# File lib/git-ds/index.rb, line 36
def local_write_tree(tree, now_tree=nil)
  tree_contents = {}
  now_tree.contents.each do |obj|
    sha = [obj.id].pack("H*")
    k = obj.name
    tree_contents[k] = "%s %s\0%s" % [obj.mode.to_i.to_s, obj.name, sha]
  end if now_tree

  tree.each do |k, v|
    case v
      when String
        sha = write_blob(v)
        sha = [sha].pack("H*")
        str = "%s %s\0%s" % ['100644', k, sha]
        tree_contents[k] = str
      when Hash
        ctree = now_tree/k if now_tree
        sha = local_write_tree(v, ctree)
        sha = [sha].pack("H*")
        str = "%s %s\0%s" % ['40000', k, sha]
        tree_contents[k] = str
      when false
        tree_contents.delete(k)
    end
  end

  tr = tree_contents.sort.map { |k, v| v }.join('')
  self.repo.git.put_raw_object(tr, 'tree')
end
path_to_object(path) click to toggle source

Return the data for the object at ‘path’. This is required in order for in-memory indexes to work properly.

# File lib/git-ds/index.rb, line 105
def path_to_object(path)
  # Note: this algorithm is re-implemented from Grit::Index#add
  arr = path.split('/')
  fname = arr.pop
  curr = self.tree
  arr.each do |dir|
    curr = curr[dir] if curr
  end

  #TODO: it would be nice to return a Grit::Blob or Grit::Tree here.
  (curr && fname && curr[fname]) ? curr[fname] : nil
end
write() click to toggle source

Write index to the object db, then read the object DB into the GIT staging index. Returns SHA of new tree.

# File lib/git-ds/index.rb, line 27
def write
  sha = local_write_tree(self.tree, self.current_tree)
  sha
end

Private Instance Methods

add_fs_item( path, data ) click to toggle source

Add a DB entry at the filesystem path ‘path’ with contents ‘contents’

# File lib/git-ds/index.rb, line 123
def add_fs_item( path, data )
  fs_path = @repo.top_level + ::File::SEPARATOR + path
  make_parent_dirs(fs_path)

  # Create file in filesystem
  @repo.exec_in_git_dir { ::File.open(fs_path, 'w') {|f| f.write(data)} }
end
make_parent_dirs(path) click to toggle source

Add parent directories as-needed to create ‘path’ on the filesystem.

# File lib/git-ds/index.rb, line 134
def make_parent_dirs(path)
  tmp_path = ''

  ::File.dirname(path).split(::File::SEPARATOR).each do |dir|
    next if dir.empty?
    tmp_path << ::File::SEPARATOR << dir
    Dir.mkdir(tmp_path) if not ::File.exist?(tmp_path)
  end
end