Class: Mist::GitFileSystemHistory

Inherits:
Object
  • Object
show all
Defined in:
lib/mist/git_file_system_history.rb

Instance Method Summary collapse

Constructor Details

#initialize(path_or_repo) ⇒ GitFileSystemHistory

Returns a new instance of GitFileSystemHistory.



2
3
4
5
# File 'lib/mist/git_file_system_history.rb', line 2

def initialize(path_or_repo)
  @files = ActiveSupport::OrderedHash.new
  @repo = path_or_repo.kind_of?(Git::Base) ? path_or_repo : Git.open(path_or_repo)
end

Instance Method Details

#filesObject

Returns files in order of discovery. Since they are discovered by traveling up the tree and backward in time, this is the REVERSE of the order of their actual creation.



10
11
12
# File 'lib/mist/git_file_system_history.rb', line 10

def files
  @files.keys.select { |filename| @files[filename] > 0 }
end

#find(count, path = /./) ⇒ Object

Finds and returns ‘count` files, in the order of creation, in descending order (most recent files first), after accounting for deletion.

If count is nil, all matches will be returned.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/mist/git_file_system_history.rb', line 35

def find(count, path = /./)
  begin
    commit = @repo.log(1).first
  rescue Git::GitExecuteError => err
    # empty repository, no commits = no matches
    return [] if err.message =~ /bad default revision 'HEAD'/
    raise err
  end
  
  while commit.parent
    commit.diff_parent.each do |diff|
      next if diff.type == 'modified' # only care about new or deleted files
      next unless diff.path[path]
      
      case diff.type                               # because parent is B, changes are reversed.
        when 'deleted' then mark_file diff.path, :created # file was created in this commit
        when 'new'     then mark_file diff.path, :deleted # file was deleted in this commit
      end
      
      return files if count and files.length == count
    end
    
    commit = commit.parent
  end
  
  # if we made it this far then commit is the initial commit
  # so at this stage, mark each file in the tree.
  mark_tree commit.gtree, :created, path
  
  count && files.length > count ? files[0...count] : files
end

#mark_file(path, mode) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/mist/git_file_system_history.rb', line 14

def mark_file(path, mode)
  @files[path] ||= 0
  case mode
    when :created then @files[path] += 1
    when :deleted then @files[path] -= 1
  end
end

#mark_tree(tree, mode, path = /./) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/mist/git_file_system_history.rb', line 22

def mark_tree(tree, mode, path = /./)
  tree.full_tree.each do |entry|
    file = entry.split(/\t/)[1]
    next unless file[path]
    mark_file file, mode
  end
end