@@ -11,6 +11,50 @@ module GitRepo
1111 \s @@.*$
1212 /x
1313
14+ # Regular expression used to extract information from lines of
15+ # `git submodule status` output
16+ SUBMODULE_STATUS_REGEX = /
17+ ^\s *(?<prefix>[-+U]?)(?<sha1>\w +)
18+ \s (?<path>[^\s ]+?)
19+ (?:\s \( (?<describe>.+)\) )?$
20+ /x
21+
22+ # Struct encapsulating submodule information extracted from the
23+ # output of `git submodule status`
24+ SubmoduleStatus = Struct . new ( :prefix , :sha1 , :path , :describe ) do
25+ # Returns whether the submodule has not been initialized
26+ def uninitialized?
27+ prefix == '-'
28+ end
29+
30+ # Returns whether the submodule is out of date with the current
31+ # index, i.e. its checked-out commit differs from that stored in
32+ # the index of the parent repo
33+ def outdated?
34+ prefix == '+'
35+ end
36+
37+ # Returns whether the submodule reference has a merge conflict
38+ def merge_conflict?
39+ prefix == 'U'
40+ end
41+ end
42+
43+ # Returns a list of SubmoduleStatus objects, one for each submodule in the
44+ # parent repository.
45+ #
46+ # @option options [Boolean] recursive check submodules recursively
47+ # @return [Array<SubmoduleStatus>]
48+ def submodule_statuses ( options = { } )
49+ flags = '--recursive' if options [ :recursive ]
50+
51+ `git submodule status #{ flags } ` .
52+ scan ( SUBMODULE_STATUS_REGEX ) .
53+ map do |prefix , sha1 , path , describe |
54+ SubmoduleStatus . new ( prefix , sha1 , path , describe )
55+ end
56+ end
57+
1458 # Extract the set of modified lines from a given file.
1559 #
1660 # @param file_path [String]
0 commit comments