class Git::Status
The status class gets the status of a git repository
This identifies which files have been modified, added, or deleted from the worktree. Untracked files are also identified.
The Status
object is an Enumerable that contains StatusFile
objects.
@api public
Public Class Methods
# File lib/git/status.rb, line 14 def initialize(base) @base = base construct_status end
Public Instance Methods
enumerable method
# File lib/git/status.rb, line 124 def [](file) @files[file] end
Returns an Enumerable containing files that have been added. File path starts at git base directory
@return [Enumerable]
# File lib/git/status.rb, line 44 def added @_added ||= @files.select { |_k, f| f.type == 'A' } end
Determines whether the given file has been added to the repository
File path starts at git base directory
@param file [String] The name of the file. @example Check if lib/git.rb is added.
added?('lib/git.rb')
@return [Boolean]
# File lib/git/status.rb, line 56 def added?(file) case_aware_include?(:added, :lc_added, file) end
Returns an Enumerable containing files that have changed from the git base directory
@return [Enumerable]
# File lib/git/status.rb, line 24 def changed @_changed ||= @files.select { |_k, f| f.type == 'M' } end
Determines whether the given file has been changed. File path starts at git base directory
@param file [String] The name of the file. @example Check if lib/git.rb has changed.
changed?('lib/git.rb')
@return [Boolean]
# File lib/git/status.rb, line 36 def changed?(file) case_aware_include?(:changed, :lc_changed, file) end
Returns an Enumerable containing files that have been deleted. File path starts at git base directory
@return [Enumerable]
# File lib/git/status.rb, line 65 def deleted @_deleted ||= @files.select { |_k, f| f.type == 'D' } end
Determines whether the given file has been deleted from the repository File path starts at git base directory
@param file [String] The name of the file. @example Check if lib/git.rb is deleted.
deleted?('lib/git.rb')
@return [Boolean]
# File lib/git/status.rb, line 77 def deleted?(file) case_aware_include?(:deleted, :lc_deleted, file) end
# File lib/git/status.rb, line 128 def each(&block) @files.values.each(&block) end
# File lib/git/status.rb, line 102 def pretty out = '' each do |file| out << pretty_file(file) end out << "\n" out end
# File lib/git/status.rb, line 111 def pretty_file(file) <<~FILE #{file.path} \tsha(r) #{file.sha_repo} #{file.mode_repo} \tsha(i) #{file.sha_index} #{file.mode_index} \ttype #{file.type} \tstage #{file.stage} \tuntrac #{file.untracked} FILE end
Returns an Enumerable containing files that are not tracked in git. File path starts at git base directory
@return [Enumerable]
# File lib/git/status.rb, line 86 def untracked @_untracked ||= @files.select { |_k, f| f.untracked } end
Determines whether the given file has is tracked by git. File path starts at git base directory
@param file [String] The name of the file. @example Check if lib/git.rb is an untracked file.
untracked?('lib/git.rb')
@return [Boolean]
# File lib/git/status.rb, line 98 def untracked?(file) case_aware_include?(:untracked, :lc_untracked, file) end
Private Instance Methods
# File lib/git/status.rb, line 298 def case_aware_include?(cased_hash, downcased_hash, file) if ignore_case? send(downcased_hash).include?(file.downcase) else send(cased_hash).include?(file) end end
# File lib/git/status.rb, line 219 def construct_status # Lists all files in the index and the worktree # git ls-files --stage # { file => { path: file, mode_index: '100644', sha_index: 'dd4fc23', stage: '0' } } @files = @base.lib.ls_files # Lists files in the worktree that are not in the index # Add untracked files to @files fetch_untracked # Lists files that are different between the index vs. the worktree fetch_modified # Lists files that are different between the repo HEAD vs. the worktree fetch_added @files.each do |k, file_hash| @files[k] = StatusFile.new(@base, file_hash) end end
# File lib/git/status.rb, line 278 def downcase_keys(hash) hash.map { |k, v| [k.downcase, v] }.to_h end
# File lib/git/status.rb, line 257 def fetch_added unless @base.lib.empty? # Files changed between the repo HEAD vs. the worktree # git diff-index HEAD # { file => { path: file, type: 'M', mode_index: '100644', mode_repo: '100644', sha_index: '0000000', :sha_repo: '52c6c4e' } } @base.lib.diff_index('HEAD').each do |path, data| @files[path] ? @files[path].merge!(data) : @files[path] = data end end end
# File lib/git/status.rb, line 248 def fetch_modified # Files changed between the index vs. the worktree # git diff-files # { file => { path: file, type: 'M', mode_index: '100644', mode_repo: '100644', sha_index: '0000000', :sha_repo: '52c6c4e' } } @base.lib.diff_files.each do |path, data| @files[path] ? @files[path].merge!(data) : @files[path] = data end end
# File lib/git/status.rb, line 240 def fetch_untracked # git ls-files --others --exclude-standard, chdir: @git_work_dir) # { file => { path: file, untracked: true } } @base.lib.untracked_files.each do |file| @files[file] = { path: file, untracked: true } end end
It’s worth noting that (like git itself) this gem will not behave well if ignoreCase is set inconsistently with the file-system itself. For details: git-scm.com/docs/git-config#Documentation/git-config.txt-coreignoreCase
# File lib/git/status.rb, line 271 def ignore_case? return @_ignore_case if defined?(@_ignore_case) @_ignore_case = @base.config('core.ignoreCase') == 'true' rescue Git::FailedError @_ignore_case = false end
# File lib/git/status.rb, line 286 def lc_added @_lc_added ||= added.transform_keys(&:downcase) end
# File lib/git/status.rb, line 282 def lc_changed @_lc_changed ||= changed.transform_keys(&:downcase) end
# File lib/git/status.rb, line 290 def lc_deleted @_lc_deleted ||= deleted.transform_keys(&:downcase) end
# File lib/git/status.rb, line 294 def lc_untracked @_lc_untracked ||= untracked.transform_keys(&:downcase) end