Class: Git::Diff

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/git/diff.rb

Overview

Diff between two commits or between a commit and the working tree

Examples:

Diff between two commits

diff = repo.diff('HEAD~1', 'HEAD')
diff.size       # => 3
diff.insertions # => 20
diff.deletions  # => 5

Limit diff to a specific path

diff = repo.diff('HEAD~1', 'HEAD').path('lib/')

Defined Under Namespace

Classes: DiffFile, FullDiffParser

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, from = nil, to = nil)

Creates a new Diff

Examples:

diff = Git::Diff.new(base, 'HEAD~1', 'HEAD')

Parameters:

  • base (Git::Base, Git::Repository)

    the git repository

  • from (String, nil) (defaults to: nil)

    the starting commit ref, or nil to compare from the index

  • to (String, nil) (defaults to: nil)

    the ending commit ref, or nil to compare to the working tree



38
39
40
41
42
43
44
45
# File 'lib/git/diff.rb', line 38

def initialize(base, from = nil, to = nil)
  @base = base
  @from = from&.to_s
  @to = to&.to_s

  @path = nil
  @full_diff_files = nil
end

Instance Attribute Details

#fromString? (readonly)

The starting commit ref

Returns:

  • (String, nil)

    the starting commit ref, or nil if not set



51
52
53
# File 'lib/git/diff.rb', line 51

def from
  @from
end

#toString? (readonly)

The ending commit ref

Returns:

  • (String, nil)

    the ending commit ref, or nil if not set



57
58
59
# File 'lib/git/diff.rb', line 57

def to
  @to
end

Instance Method Details

#[](key) ⇒ Git::Diff::DiffFile

Returns the diff file info for the given path

Examples:

diff['lib/git.rb'] # => #<Git::Diff::DiffFile ...>

Parameters:

  • key (String)

    the file path to look up

Returns:



122
123
124
125
# File 'lib/git/diff.rb', line 122

def [](key)
  process_full
  @full_diff_files.assoc(key)[1]
end

#deletionsInteger

Returns the total number of deleted lines in the diff

Examples:

diff.deletions # => 10

Returns:

  • (Integer)

    the number of deleted lines



197
198
199
# File 'lib/git/diff.rb', line 197

def deletions
  stats_provider.deletions
end

#eachEnumerator<Git::Diff::DiffFile> #each {|file| ... } ⇒ Array<Git::Diff::DiffFile>

Iterates over each changed file in the diff

Overloads:

  • #eachEnumerator<Git::Diff::DiffFile>

    Returns an enumerator over the changed files.

    Examples:

    Get an enumerator

    diff.each.map(&:path) # => ["lib/git.rb", "README.md"]

    Returns:

  • #each {|file| ... } ⇒ Array<Git::Diff::DiffFile>

    Returns the array of changed files.

    Examples:

    Iterate with a block

    diff.each { |file| puts file.path }

    Yields:

    • (file)

      each changed file in the diff

    Yield Parameters:

    Yield Returns:

    • (void)

    Returns:



148
149
150
151
# File 'lib/git/diff.rb', line 148

def each(&)
  process_full
  @full_diff_files.map { |file| file[1] }.each(&)
end

#insertionsInteger

Returns the total number of inserted lines in the diff

Examples:

diff.insertions # => 32

Returns:

  • (Integer)

    the number of inserted lines



208
209
210
# File 'lib/git/diff.rb', line 208

def insertions
  stats_provider.insertions
end

#linesInteger

Returns the total number of changed lines in the diff

Examples:

diff.lines # => 42

Returns:

  • (Integer)

    the total number of inserted and deleted lines



186
187
188
# File 'lib/git/diff.rb', line 186

def lines
  stats_provider.lines
end

#name_statusHash<String, String>

Returns the path-to-status hash for all changed files in the diff

Examples:

diff.name_status # => { "lib/git.rb" => "M", "README.md" => "A" }

Returns:

  • (Hash<String, String>)

    map of file path to git status letter



175
176
177
# File 'lib/git/diff.rb', line 175

def name_status
  path_status_provider.to_h
end

#patchString Also known as: to_s

Returns the full diff output as a string

Examples:

diff.patch # => "diff --git a/file.rb b/file.rb\n..."

Returns:

  • (String)

    the raw output of git diff



104
105
106
107
108
109
110
# File 'lib/git/diff.rb', line 104

def patch
  if @base.respond_to?(:diff_full)
    @base.diff_full(@from, @to, path_limiter: @path)
  else
    @base.lib.diff_full(@from, @to, { path_limiter: @path })
  end
end

#path(*paths) ⇒ self

Limits the diff to the specified path(s)

When called with no arguments (or only nil arguments), removes any existing path filter, showing all files in the diff. Internally stores a single path as a String and multiple paths as an Array for efficiency.

Examples:

Limit diff to a single path

git.diff('HEAD~3', 'HEAD').path('lib/')

Limit diff to multiple paths

git.diff('HEAD~3', 'HEAD').path('src/', 'docs/', 'README.md')

Remove path filtering (show all files)

diff.path  # or diff.path(nil)

Parameters:

  • paths (String, Pathname)

    one or more paths to filter the diff; pass no arguments to remove filtering

Returns:

  • (self)

    returns self for method chaining

Raises:

  • (ArgumentError)

    if any path is an Array (use splatted arguments instead)



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/git/diff.rb', line 81

def path(*paths)
  validate_paths_not_arrays(paths)

  cleaned_paths = paths.compact

  @path = if cleaned_paths.empty?
            nil
          elsif cleaned_paths.length == 1
            cleaned_paths.first
          else
            cleaned_paths
          end

  self
end

#sizeInteger

Returns the number of changed files in the diff

Examples:

diff.size # => 3

Returns:

  • (Integer)

    the number of changed files



160
161
162
# File 'lib/git/diff.rb', line 160

def size
  stats_provider.total[:files]
end

#statsHash

Returns a statistics hash for the diff

Examples:

diff.stats
# => {
#   files: { "lib/git.rb" => { insertions: 5, deletions: 2 } },
#   total: { insertions: 5, deletions: 2, lines: 7 }
# }

Returns:

  • (Hash)

    statistics including per-file and total insert/delete counts



223
224
225
226
227
228
# File 'lib/git/diff.rb', line 223

def stats
  {
    files: stats_provider.files,
    total: stats_provider.total
  }
end