summaryrefslogtreecommitdiffstats
path: root/lib/git/status.rb
blob: 7dcd28488b371d4fbbcd9d4773898f5e369025e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
module Git
  
  class Status
    include Enumerable
    
    @base = nil
    @files = nil
    
    def initialize(base)
      @base = base
      construct_status
    end
    
    def changed
      @files.select { |k, f| f.type == 'M' }
    end
    
    def added
      @files.select { |k, f| f.type == 'A' }
    end

    def deleted
      @files.select { |k, f| f.type == 'D' }
    end
    
    def untracked
      @files.select { |k, f| f.untracked }
    end
    
    def pretty
      out = ''
      self.each do |file|
        out << file.path
        out << "\n\tsha(r) " + file.sha_repo.to_s + ' ' + file.mode_repo.to_s
        out << "\n\tsha(i) " + file.sha_index.to_s + ' ' + file.mode_index.to_s
        out << "\n\ttype   " + file.type.to_s
        out << "\n\tstage  " + file.stage.to_s
        out << "\n\tuntrac " + file.untracked.to_s
        out << "\n"
      end
      out << "\n"
      out
    end
    
    # enumerable method
    
    def [](file)
      @files[file]
    end
    
    def each
      @files.each do |k, file|
        yield file
      end
    end
    
    class StatusFile
      attr_accessor :path, :type, :stage, :untracked
      attr_accessor :mode_index, :mode_repo
      attr_accessor :sha_index, :sha_repo
      
      @base = nil
      
      def initialize(base, hash)
        @base = base
        @path = hash[:path]
        @type = hash[:type]
        @stage = hash[:stage]
        @mode_index = hash[:mode_index]
        @mode_repo = hash[:mode_repo]
        @sha_index = hash[:sha_index]
        @sha_repo = hash[:sha_repo]
        @untracked = hash[:untracked]
      end
      
      def blob(type = :index)
        if type == :repo
          @base.object(@sha_repo)
        else
          @base.object(@sha_index) rescue @base.object(@sha_repo)
        end
      end
      
      
    end
    
    private
    
      def construct_status
        @files = @base.lib.ls_files
        
        # find untracked in working dir
        Dir.chdir(@base.dir.path) do
          Dir.glob('**/*') do |file|
            if !@files[file]
              @files[file] = {:path => file, :untracked => true} if !File.directory?(file)
            end
          end
        end

        # find modified in tree
        @base.lib.diff_files.each do |path, data|
          @files[path] ? @files[path].merge!(data) : @files[path] = data
        end
        
        # find added but not committed - new files
        @base.lib.diff_index('HEAD').each do |path, data|
          @files[path] ? @files[path].merge!(data) : @files[path] = data
        end
        
        @files.each do |k, file_hash|
          @files[k] = StatusFile.new(@base, file_hash)
        end
      end
      
  end
  
end