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

new(base) click to toggle source
# File lib/git/status.rb, line 14
def initialize(base)
  @base = base
  construct_status
end

Public Instance Methods

[](file) click to toggle source

enumerable method

# File lib/git/status.rb, line 124
def [](file)
  @files[file]
end
added() click to toggle source

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
added?(file) click to toggle source

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
changed() click to toggle source

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
changed?(file) click to toggle source

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
deleted() click to toggle source

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
deleted?(file) click to toggle source

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
each(&block) click to toggle source
# File lib/git/status.rb, line 128
def each(&block)
  @files.values.each(&block)
end
pretty() click to toggle source
# File lib/git/status.rb, line 102
def pretty
  out = ''
  each do |file|
    out << pretty_file(file)
  end
  out << "\n"
  out
end
pretty_file(file) click to toggle source
# 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
untracked() click to toggle source

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
untracked?(file) click to toggle source

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

case_aware_include?(cased_hash, downcased_hash, file) click to toggle source
# 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
construct_status() click to toggle source
# 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
downcase_keys(hash) click to toggle source
# File lib/git/status.rb, line 278
def downcase_keys(hash)
  hash.map { |k, v| [k.downcase, v] }.to_h
end
fetch_added() click to toggle source
# 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
fetch_modified() click to toggle source
# 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
fetch_untracked() click to toggle source
# 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
ignore_case?() click to toggle source

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
lc_added() click to toggle source
# File lib/git/status.rb, line 286
def lc_added
  @_lc_added ||= added.transform_keys(&:downcase)
end
lc_changed() click to toggle source
# File lib/git/status.rb, line 282
def lc_changed
  @_lc_changed ||= changed.transform_keys(&:downcase)
end
lc_deleted() click to toggle source
# File lib/git/status.rb, line 290
def lc_deleted
  @_lc_deleted ||= deleted.transform_keys(&:downcase)
end
lc_untracked() click to toggle source
# File lib/git/status.rb, line 294
def lc_untracked
  @_lc_untracked ||= untracked.transform_keys(&:downcase)
end