1
1
module Git
2
-
2
+ #
3
+ # A class for git status
4
+ #
3
5
class Status
4
6
include Enumerable
5
-
7
+
6
8
def initialize ( base )
7
9
@base = base
8
10
construct_status
9
11
end
10
-
12
+
13
+ #
14
+ # Returns an Enumerable containing files that have changed from the
15
+ # git base directory
16
+ #
17
+ # @return [Enumerable]
11
18
def changed
12
- @files . select { |k , f | f . type == 'M' }
19
+ @files . select { |_k , f | f . type == 'M' }
13
20
end
14
-
21
+
22
+ #
23
+ # Determines whether the given file has been changed.
24
+ # File path starts at git base directory
25
+ #
26
+ # @param file [String] The name of the file.
27
+ # @example Check if lib/git.rb has changed.
28
+ # changed?('lib/git.rb')
29
+ # @return [Boolean]
30
+ def changed? ( file )
31
+ changed . member? ( file )
32
+ end
33
+
34
+ #
35
+ # Returns an Enumerable containing files that have been added.
36
+ # File path starts at git base directory
37
+ #
38
+ # @return [Enumerable]
15
39
def added
16
- @files . select { |k , f | f . type == 'A' }
40
+ @files . select { |_k , f | f . type == 'A' }
17
41
end
18
42
43
+ #
44
+ # Determines whether the given file has been added to the repository
45
+ # File path starts at git base directory
46
+ #
47
+ # @param file [String] The name of the file.
48
+ # @example Check if lib/git.rb is added.
49
+ # added?('lib/git.rb')
50
+ # @return [Boolean]
51
+ def added? ( file )
52
+ added . member? ( file )
53
+ end
54
+
55
+ #
56
+ # Returns an Enumerable containing files that have been deleted.
57
+ # File path starts at git base directory
58
+ #
59
+ # @return [Enumerable]
19
60
def deleted
20
- @files . select { |k , f | f . type == 'D' }
61
+ @files . select { |_k , f | f . type == 'D' }
21
62
end
22
-
63
+
64
+ #
65
+ # Determines whether the given file has been deleted from the repository
66
+ # File path starts at git base directory
67
+ #
68
+ # @param file [String] The name of the file.
69
+ # @example Check if lib/git.rb is deleted.
70
+ # deleted?('lib/git.rb')
71
+ # @return [Boolean]
72
+ def deleted? ( file )
73
+ deleted . member? ( file )
74
+ end
75
+
76
+ #
77
+ # Returns an Enumerable containing files that are not tracked in git.
78
+ # File path starts at git base directory
79
+ #
80
+ # @return [Enumerable]
23
81
def untracked
24
- @files . select { |k , f | f . untracked }
82
+ @files . select { |_k , f | f . untracked }
25
83
end
26
-
84
+
85
+ #
86
+ # Determines whether the given file has is tracked by git.
87
+ # File path starts at git base directory
88
+ #
89
+ # @param file [String] The name of the file.
90
+ # @example Check if lib/git.rb is an untracked file.
91
+ # untracked?('lib/git.rb')
92
+ # @return [Boolean]
93
+ def untracked? ( file )
94
+ untracked . member? ( file )
95
+ end
96
+
27
97
def pretty
28
98
out = ''
29
- self . each do |file |
99
+ each do |file |
30
100
out << pretty_file ( file )
31
101
end
32
102
out << "\n "
33
103
out
34
104
end
35
105
36
106
def pretty_file ( file )
37
- <<FILE
38
- #{ file . path }
39
- \t sha(r) #{ file . sha_repo . to_s } #{ file . mode_repo . to_s }
40
- \t sha(i) #{ file . sha_index . to_s } #{ file . mode_index . to_s }
41
- \t type #{ file . type . to_s }
42
- \t stage #{ file . stage . to_s }
43
- \t untrac #{ file . untracked . to_s }
44
- FILE
45
- end
46
-
107
+ <<- FILE . strip_heredoc
108
+ #{ file . path }
109
+ \t sha(r) #{ file . sha_repo } #{ file . mode_repo }
110
+ \t sha(i) #{ file . sha_index } #{ file . mode_index }
111
+ \t type #{ file . type }
112
+ \t stage #{ file . stage }
113
+ \t untrac #{ file . untracked }
114
+ FILE
115
+ end
116
+
47
117
# enumerable method
48
-
118
+
49
119
def []( file )
50
120
@files [ file ]
51
121
end
52
-
122
+
53
123
def each ( &block )
54
124
@files . values . each ( &block )
55
125
end
56
-
126
+
127
+ # subclass that does heavy lifting
57
128
class StatusFile
58
129
attr_accessor :path , :type , :stage , :untracked
59
130
attr_accessor :mode_index , :mode_repo
@@ -70,48 +141,59 @@ def initialize(base, hash)
70
141
@sha_repo = hash [ :sha_repo ]
71
142
@untracked = hash [ :untracked ]
72
143
end
73
-
144
+
74
145
def blob ( type = :index )
75
146
if type == :repo
76
147
@base . object ( @sha_repo )
77
148
else
78
- @base . object ( @sha_index ) rescue @base . object ( @sha_repo )
149
+ begin
150
+ @base . object ( @sha_index )
151
+ rescue
152
+ @base . object ( @sha_repo )
153
+ end
79
154
end
80
155
end
81
-
82
-
83
156
end
84
-
157
+
85
158
private
86
-
87
- def construct_status
88
- @files = @base . lib . ls_files
89
- ignore = @base . lib . ignored_files
90
-
91
- # find untracked in working dir
92
- Dir . chdir ( @base . dir . path ) do
93
- Dir . glob ( '**/*' , File ::FNM_DOTMATCH ) do |file |
94
- next if @files [ file ] || File . directory? ( file ) || ignore . include? ( file ) || file =~ /^.git\/ .+/
95
-
96
- @files [ file ] = { :path => file , :untracked => true }
97
- end
98
- end
99
-
100
- # find modified in tree
101
- @base . lib . diff_files . each do |path , data |
102
- @files [ path ] ? @files [ path ] . merge! ( data ) : @files [ path ] = data
103
- end
104
-
105
- # find added but not committed - new files
106
- @base . lib . diff_index ( 'HEAD' ) . each do |path , data |
107
- @files [ path ] ? @files [ path ] . merge! ( data ) : @files [ path ] = data
108
- end
109
-
110
- @files . each do |k , file_hash |
111
- @files [ k ] = StatusFile . new ( @base , file_hash )
159
+
160
+ def construct_status
161
+ @files = @base . lib . ls_files
162
+
163
+ fetch_untracked
164
+ fetch_modified
165
+ fetch_added
166
+
167
+ @files . each do |k , file_hash |
168
+ @files [ k ] = StatusFile . new ( @base , file_hash )
169
+ end
170
+ end
171
+
172
+ def fetch_untracked
173
+ ignore = @base . lib . ignored_files
174
+
175
+ Dir . chdir ( @base . dir . path ) do
176
+ Dir . glob ( '**/*' , File ::FNM_DOTMATCH ) do |file |
177
+ next if @files [ file ] || File . directory? ( file ) ||
178
+ ignore . include? ( file ) || file =~ %r{^.git\/ .+}
179
+
180
+ @files [ file ] = { path : file , untracked : true }
112
181
end
113
182
end
114
-
183
+ end
184
+
185
+ def fetch_modified
186
+ # find modified in tree
187
+ @base . lib . diff_files . each do |path , data |
188
+ @files [ path ] ? @files [ path ] . merge! ( data ) : @files [ path ] = data
189
+ end
190
+ end
191
+
192
+ def fetch_added
193
+ # find added but not committed - new files
194
+ @base . lib . diff_index ( 'HEAD' ) . each do |path , data |
195
+ @files [ path ] ? @files [ path ] . merge! ( data ) : @files [ path ] = data
196
+ end
197
+ end
115
198
end
116
-
117
199
end
0 commit comments