1
1
module Git
2
+ # The status class gets the status of a git repository
2
3
#
3
- # A class for git status
4
+ # This identifies which files have been modified, added, or deleted from the
5
+ # worktree. Untracked files are also identified.
6
+ #
7
+ # The Status object is an Enumerable that contains StatusFile objects.
8
+ #
9
+ # @api public
4
10
#
5
11
class Status
6
12
include Enumerable
@@ -31,7 +37,6 @@ def changed?(file)
31
37
changed . member? ( file )
32
38
end
33
39
34
- #
35
40
# Returns an Enumerable containing files that have been added.
36
41
# File path starts at git base directory
37
42
#
@@ -40,8 +45,8 @@ def added
40
45
@files . select { |_k , f | f . type == 'A' }
41
46
end
42
47
43
- #
44
48
# Determines whether the given file has been added to the repository
49
+ #
45
50
# File path starts at git base directory
46
51
#
47
52
# @param file [String] The name of the file.
@@ -126,9 +131,63 @@ def each(&block)
126
131
127
132
# subclass that does heavy lifting
128
133
class StatusFile
129
- attr_accessor :path , :type , :stage , :untracked
130
- attr_accessor :mode_index , :mode_repo
131
- attr_accessor :sha_index , :sha_repo
134
+ # @!attribute [r] path
135
+ # The path of the file relative to the project root directory
136
+ # @return [String]
137
+ attr_accessor :path
138
+
139
+ # @!attribute [r] type
140
+ # The type of change
141
+ #
142
+ # * 'M': modified
143
+ # * 'A': added
144
+ # * 'D': deleted
145
+ # * nil: ???
146
+ #
147
+ # @return [String]
148
+ attr_accessor :type
149
+
150
+ # @!attribute [r] mode_index
151
+ # The mode of the file in the index
152
+ # @return [String]
153
+ # @example 100644
154
+ #
155
+ attr_accessor :mode_index
156
+
157
+ # @!attribute [r] mode_repo
158
+ # The mode of the file in the repo
159
+ # @return [String]
160
+ # @example 100644
161
+ #
162
+ attr_accessor :mode_repo
163
+
164
+ # @!attribute [r] sha_index
165
+ # The sha of the file in the index
166
+ # @return [String]
167
+ # @example 123456
168
+ #
169
+ attr_accessor :sha_index
170
+
171
+ # @!attribute [r] sha_repo
172
+ # The sha of the file in the repo
173
+ # @return [String]
174
+ # @example 123456
175
+ attr_accessor :sha_repo
176
+
177
+ # @!attribute [r] untracked
178
+ # Whether the file is untracked
179
+ # @return [Boolean]
180
+ attr_accessor :untracked
181
+
182
+ # @!attribute [r] stage
183
+ # The stage of the file
184
+ #
185
+ # * '0': the unmerged state
186
+ # * '1': the common ancestor (or original) version
187
+ # * '2': "our version" from the current branch head
188
+ # * '3': "their version" from the other branch head
189
+ # @return [String]
190
+ attr_accessor :stage
132
191
133
192
def initialize ( base , hash )
134
193
@base = base
@@ -158,10 +217,19 @@ def blob(type = :index)
158
217
private
159
218
160
219
def construct_status
220
+ # Lists all files in the index and the worktree
221
+ # git ls-files --stage
222
+ # { file => { path: file, mode_index: '100644', sha_index: 'dd4fc23', stage: '0' } }
161
223
@files = @base . lib . ls_files
162
224
225
+ # Lists files in the worktree that are not in the index
226
+ # Add untracked files to @files
163
227
fetch_untracked
228
+
229
+ # Lists files that are different between the index vs. the worktree
164
230
fetch_modified
231
+
232
+ # Lists files that are different between the repo HEAD vs. the worktree
165
233
fetch_added
166
234
167
235
@files . each do |k , file_hash |
@@ -170,22 +238,28 @@ def construct_status
170
238
end
171
239
172
240
def fetch_untracked
241
+ # git ls-files --others --exclude-standard, chdir: @git_work_dir)
242
+ # { file => { path: file, untracked: true } }
173
243
@base . lib . untracked_files . each do |file |
174
244
@files [ file ] = { path : file , untracked : true }
175
245
end
176
246
end
177
247
178
248
def fetch_modified
179
- # find modified in tree
249
+ # Files changed between the index vs. the worktree
250
+ # git diff-files
251
+ # { file => { path: file, type: 'M', mode_index: '100644', mode_repo: '100644', sha_index: '0000000', :sha_repo: '52c6c4e' } }
180
252
@base . lib . diff_files . each do |path , data |
181
253
@files [ path ] ? @files [ path ] . merge! ( data ) : @files [ path ] = data
182
254
end
183
255
end
184
256
185
257
def fetch_added
186
258
unless @base . lib . empty?
187
- # find added but not committed - new files
188
- @base . lib . diff_index ( 'HEAD' ) . each do |path , data |
259
+ # Files changed between the repo HEAD vs. the worktree
260
+ # git diff-index HEAD
261
+ # { file => { path: file, type: 'M', mode_index: '100644', mode_repo: '100644', sha_index: '0000000', :sha_repo: '52c6c4e' } }
262
+ @base . lib . diff_index ( 'HEAD' ) . each do |path , data |
189
263
@files [ path ] ? @files [ path ] . merge! ( data ) : @files [ path ] = data
190
264
end
191
265
end
0 commit comments