git 1.19.1 → 4.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.commitlintrc.yml +38 -0
- data/.github/copilot-instructions.md +2733 -0
- data/.github/pull_request_template.md +17 -0
- data/.github/workflows/continuous_integration.yml +92 -21
- data/.github/workflows/enforce_conventional_commits.yml +29 -0
- data/.github/workflows/experimental_continuous_integration.yml +59 -0
- data/.github/workflows/release.yml +53 -0
- data/.gitignore +5 -0
- data/.husky/commit-msg +1 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +55 -0
- data/.rubocop_todo.yml +12 -0
- data/.yardopts +4 -1
- data/AI_POLICY.md +24 -0
- data/CHANGELOG.md +501 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +323 -102
- data/GOVERNANCE.md +106 -0
- data/LICENSE +1 -1
- data/MAINTAINERS.md +17 -4
- data/README.md +575 -246
- data/Rakefile +13 -55
- data/git.gemspec +36 -30
- data/lib/git/args_builder.rb +111 -0
- data/lib/git/author.rb +9 -7
- data/lib/git/base.rb +602 -173
- data/lib/git/branch.rb +318 -38
- data/lib/git/branches.rb +21 -24
- data/lib/git/command_line.rb +330 -0
- data/lib/git/command_line_result.rb +9 -3
- data/lib/git/config.rb +10 -6
- data/lib/git/diff.rb +149 -81
- data/lib/git/diff_path_status.rb +46 -0
- data/lib/git/diff_stats.rb +59 -0
- data/lib/git/errors.rb +212 -0
- data/lib/git/escaped_path.rb +2 -2
- data/lib/git/fsck_object.rb +48 -0
- data/lib/git/fsck_result.rb +121 -0
- data/lib/git/index.rb +2 -1
- data/lib/git/lib.rb +1648 -643
- data/lib/git/log.rb +143 -106
- data/lib/git/object.rb +151 -125
- data/lib/git/path.rb +23 -16
- data/lib/git/remote.rb +5 -4
- data/lib/git/repository.rb +2 -2
- data/lib/git/stash.rb +11 -12
- data/lib/git/stashes.rb +16 -15
- data/lib/git/status.rb +104 -143
- data/lib/git/url.rb +3 -3
- data/lib/git/version.rb +3 -1
- data/lib/git/working_directory.rb +2 -0
- data/lib/git/worktree.rb +6 -5
- data/lib/git/worktrees.rb +6 -6
- data/lib/git.rb +131 -28
- data/package.json +10 -0
- data/redesign/1_architecture_existing.md +66 -0
- data/redesign/2_architecture_redesign.md +130 -0
- data/redesign/3_architecture_implementation.md +138 -0
- data/redesign/index.md +34 -0
- data/release-please-config.json +36 -0
- data/tasks/gem_tasks.rake +10 -0
- data/tasks/rubocop.rake +12 -0
- data/tasks/test.rake +13 -0
- data/tasks/test_gem.rake +12 -0
- data/tasks/yard.rake +23 -0
- metadata +114 -37
- data/.github/stale.yml +0 -25
- data/Dockerfile.changelog-rs +0 -12
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- data/RELEASING.md +0 -70
- data/lib/git/base/factory.rb +0 -99
- data/lib/git/failed_error.rb +0 -53
- data/lib/git/git_execute_error.rb +0 -7
- data/lib/git/signaled_error.rb +0 -50
- /data/{ISSUE_TEMPLATE.md → .github/issue_template.md} +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# The files and their status (e.g., added, modified, deleted) between two commits
|
|
5
|
+
class DiffPathStatus
|
|
6
|
+
include Enumerable
|
|
7
|
+
|
|
8
|
+
# @private
|
|
9
|
+
def initialize(base, from, to, path_limiter = nil)
|
|
10
|
+
# Eagerly check for invalid arguments
|
|
11
|
+
[from, to].compact.each do |arg|
|
|
12
|
+
raise ArgumentError, "Invalid argument: '#{arg}'" if arg.start_with?('-')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
@base = base
|
|
16
|
+
@from = from
|
|
17
|
+
@to = to
|
|
18
|
+
@path_limiter = path_limiter
|
|
19
|
+
@path_status = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Iterates over each file's status.
|
|
23
|
+
#
|
|
24
|
+
# @yield [path, status]
|
|
25
|
+
def each(&)
|
|
26
|
+
fetch_path_status.each(&)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns the name-status report as a Hash.
|
|
30
|
+
#
|
|
31
|
+
# @return [Hash<String, String>] A hash where keys are file paths
|
|
32
|
+
# and values are their status codes.
|
|
33
|
+
def to_h
|
|
34
|
+
fetch_path_status
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# Lazily fetches and caches the path status from the git lib.
|
|
40
|
+
def fetch_path_status
|
|
41
|
+
@fetch_path_status ||= @base.lib.diff_path_status(
|
|
42
|
+
@from, @to, { path_limiter: @path_limiter }
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Provides access to the statistics of a diff between two commits,
|
|
5
|
+
# including insertions, deletions, and file-level details.
|
|
6
|
+
class DiffStats
|
|
7
|
+
# @private
|
|
8
|
+
def initialize(base, from, to, path_limiter = nil)
|
|
9
|
+
# Eagerly check for invalid arguments
|
|
10
|
+
[from, to].compact.each do |arg|
|
|
11
|
+
raise ArgumentError, "Invalid argument: '#{arg}'" if arg.start_with?('-')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@base = base
|
|
15
|
+
@from = from
|
|
16
|
+
@to = to
|
|
17
|
+
@path_limiter = path_limiter
|
|
18
|
+
@stats = nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Returns the total number of lines deleted.
|
|
22
|
+
def deletions
|
|
23
|
+
fetch_stats[:total][:deletions]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns the total number of lines inserted.
|
|
27
|
+
def insertions
|
|
28
|
+
fetch_stats[:total][:insertions]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns the total number of lines changed (insertions + deletions).
|
|
32
|
+
def lines
|
|
33
|
+
fetch_stats[:total][:lines]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Returns a hash of statistics for each file in the diff.
|
|
37
|
+
#
|
|
38
|
+
# @return [Hash<String, {insertions: Integer, deletions: Integer}>]
|
|
39
|
+
def files
|
|
40
|
+
fetch_stats[:files]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns a hash of the total statistics for the diff.
|
|
44
|
+
#
|
|
45
|
+
# @return [{insertions: Integer, deletions: Integer, lines: Integer, files: Integer}]
|
|
46
|
+
def total
|
|
47
|
+
fetch_stats[:total]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
# Lazily fetches and caches the stats from the git lib.
|
|
53
|
+
def fetch_stats
|
|
54
|
+
@fetch_stats ||= @base.lib.diff_stats(
|
|
55
|
+
@from, @to, { path_limiter: @path_limiter }
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/git/errors.rb
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# rubocop:disable Layout/LineLength
|
|
5
|
+
|
|
6
|
+
# Base class for all custom git module errors
|
|
7
|
+
#
|
|
8
|
+
# The git gem will only raise an `ArgumentError` or an error that is a subclass of
|
|
9
|
+
# `Git::Error`. It does not explicitly raise any other types of errors.
|
|
10
|
+
#
|
|
11
|
+
# It is recommended to rescue `Git::Error` to catch any runtime error raised by
|
|
12
|
+
# this gem unless you need more specific error handling.
|
|
13
|
+
#
|
|
14
|
+
# Git's custom errors are arranged in the following class heirarchy:
|
|
15
|
+
#
|
|
16
|
+
# ```text
|
|
17
|
+
# StandardError
|
|
18
|
+
# └─> Git::Error
|
|
19
|
+
# ├─> Git::CommandLineError
|
|
20
|
+
# │ ├─> Git::FailedError
|
|
21
|
+
# │ └─> Git::SignaledError
|
|
22
|
+
# │ └─> Git::TimeoutError
|
|
23
|
+
# ├─> Git::ProcessIOError
|
|
24
|
+
# └─> Git::UnexpectedResultError
|
|
25
|
+
# ```
|
|
26
|
+
#
|
|
27
|
+
# | Error Class | Description |
|
|
28
|
+
# | --- | --- |
|
|
29
|
+
# | `Error` | This catch-all error serves as the base class for other custom errors raised by the git gem. |
|
|
30
|
+
# | `CommandLineError` | A subclass of this error is raised when there is a problem executing the git command line. |
|
|
31
|
+
# | `FailedError` | This error is raised when the git command line exits with a non-zero status code that is not expected by the git gem. |
|
|
32
|
+
# | `SignaledError` | This error is raised when the git command line is terminated as a result of receiving a signal. This could happen if the process is forcibly terminated or if there is a serious system error. |
|
|
33
|
+
# | `TimeoutError` | This is a specific type of `SignaledError` that is raised when the git command line operation times out and is killed via the SIGKILL signal. This happens if the operation takes longer than the timeout duration configured in `Git.config.timeout` or via the `:timeout` parameter given in git methods that support timeouts. |
|
|
34
|
+
# | `ProcessIOError` | An error was encountered reading or writing to a subprocess. |
|
|
35
|
+
# | `UnexpectedResultError` | The command line ran without error but did not return the expected results. |
|
|
36
|
+
#
|
|
37
|
+
# @example Rescuing a generic error
|
|
38
|
+
# begin
|
|
39
|
+
# # some git operation
|
|
40
|
+
# rescue Git::Error => e
|
|
41
|
+
# puts "An error occurred: #{e.message}"
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# @example Rescuing a timeout error
|
|
45
|
+
# begin
|
|
46
|
+
# timeout_duration = 0.001 # seconds
|
|
47
|
+
# repo = Git.clone('https://github.com/ruby-git/ruby-git', 'ruby-git-temp', timeout: timeout_duration)
|
|
48
|
+
# rescue Git::TimeoutError => e # Catch the more specific error first!
|
|
49
|
+
# puts "Git clone took too long and timed out #{e}"
|
|
50
|
+
# rescue Git::Error => e
|
|
51
|
+
# puts "Received the following error: #{e}"
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# @see Git::CommandLineError
|
|
55
|
+
# @see Git::FailedError
|
|
56
|
+
# @see Git::SignaledError
|
|
57
|
+
# @see Git::TimeoutError
|
|
58
|
+
# @see Git::ProcessIOError
|
|
59
|
+
# @see Git::UnexpectedResultError
|
|
60
|
+
#
|
|
61
|
+
# @api public
|
|
62
|
+
#
|
|
63
|
+
class Error < StandardError; end
|
|
64
|
+
|
|
65
|
+
# rubocop:enable Layout/LineLength
|
|
66
|
+
|
|
67
|
+
# An alias for Git::Error
|
|
68
|
+
#
|
|
69
|
+
# Git::GitExecuteError error class is an alias for Git::Error for backwards
|
|
70
|
+
# compatibility. It is recommended to use Git::Error directly.
|
|
71
|
+
#
|
|
72
|
+
# @deprecated Use Git::Error instead
|
|
73
|
+
#
|
|
74
|
+
GitExecuteError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Git::GitExecuteError', 'Git::Error', Git::Deprecation)
|
|
75
|
+
|
|
76
|
+
# Raised when a git command fails or exits because of an uncaught signal
|
|
77
|
+
#
|
|
78
|
+
# The git command executed, status, stdout, and stderr are available from this
|
|
79
|
+
# object.
|
|
80
|
+
#
|
|
81
|
+
# The Gem will raise a more specific error for each type of failure:
|
|
82
|
+
#
|
|
83
|
+
# * {Git::FailedError}: when the git command exits with a non-zero status
|
|
84
|
+
# * {Git::SignaledError}: when the git command exits because of an uncaught signal
|
|
85
|
+
# * {Git::TimeoutError}: when the git command times out
|
|
86
|
+
#
|
|
87
|
+
# @api public
|
|
88
|
+
#
|
|
89
|
+
class CommandLineError < Git::Error
|
|
90
|
+
# Create a CommandLineError object
|
|
91
|
+
#
|
|
92
|
+
# @example
|
|
93
|
+
# `exit 1` # set $? appropriately for this example
|
|
94
|
+
# result = Git::CommandLineResult.new(%w[git status], $?, 'stdout', 'stderr')
|
|
95
|
+
# error = Git::CommandLineError.new(result)
|
|
96
|
+
# error.to_s #=> '["git", "status"], status: pid 89784 exit 1, stderr: "stderr"'
|
|
97
|
+
#
|
|
98
|
+
# @param result [Git::CommandLineResult] the result of the git command including
|
|
99
|
+
# the git command, status, stdout, and stderr
|
|
100
|
+
#
|
|
101
|
+
def initialize(result)
|
|
102
|
+
@result = result
|
|
103
|
+
super(error_message)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# The human readable representation of this error
|
|
107
|
+
#
|
|
108
|
+
# @example
|
|
109
|
+
# error.error_message #=> '["git", "status"], status: pid 89784 exit 1, stderr: "stderr"'
|
|
110
|
+
#
|
|
111
|
+
# @return [String]
|
|
112
|
+
#
|
|
113
|
+
def error_message = <<~MESSAGE.chomp
|
|
114
|
+
#{result.git_cmd}, status: #{result.status}, stderr: #{result.stderr.inspect}
|
|
115
|
+
MESSAGE
|
|
116
|
+
|
|
117
|
+
# @attribute [r] result
|
|
118
|
+
#
|
|
119
|
+
# The result of the git command including the git command and its status and output
|
|
120
|
+
#
|
|
121
|
+
# @example
|
|
122
|
+
# error.result #=> #<Git::CommandLineResult:0x00000001046bd488 ...>
|
|
123
|
+
#
|
|
124
|
+
# @return [Git::CommandLineResult]
|
|
125
|
+
#
|
|
126
|
+
attr_reader :result
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# This error is raised when a git command returns a non-zero exitstatus
|
|
130
|
+
#
|
|
131
|
+
# The git command executed, status, stdout, and stderr are available from this
|
|
132
|
+
# object.
|
|
133
|
+
#
|
|
134
|
+
# @api public
|
|
135
|
+
#
|
|
136
|
+
class FailedError < Git::CommandLineError; end
|
|
137
|
+
|
|
138
|
+
# This error is raised when a git command exits because of an uncaught signal
|
|
139
|
+
#
|
|
140
|
+
# @api public
|
|
141
|
+
#
|
|
142
|
+
class SignaledError < Git::CommandLineError; end
|
|
143
|
+
|
|
144
|
+
# This error is raised when a git command takes longer than the configured timeout
|
|
145
|
+
#
|
|
146
|
+
# The git command executed, status, stdout, and stderr, and the timeout duration
|
|
147
|
+
# are available from this object.
|
|
148
|
+
#
|
|
149
|
+
# result.status.timeout? will be `true`
|
|
150
|
+
#
|
|
151
|
+
# @api public
|
|
152
|
+
#
|
|
153
|
+
class TimeoutError < Git::SignaledError
|
|
154
|
+
# Create a TimeoutError object
|
|
155
|
+
#
|
|
156
|
+
# @example
|
|
157
|
+
# command = %w[sleep 10]
|
|
158
|
+
# timeout_duration = 1
|
|
159
|
+
# status = ProcessExecuter.spawn(*command, timeout: timeout_duration)
|
|
160
|
+
# result = Git::CommandLineResult.new(command, status, 'stdout', 'err output')
|
|
161
|
+
# error = Git::TimeoutError.new(result, timeout_duration)
|
|
162
|
+
# error.error_message
|
|
163
|
+
# #=> '["sleep", "10"], status: pid 70144 SIGKILL (signal 9), stderr: "err output", timed out after 1s'
|
|
164
|
+
#
|
|
165
|
+
# @param result [Git::CommandLineResult] the result of the git command including
|
|
166
|
+
# the git command, status, stdout, and stderr
|
|
167
|
+
#
|
|
168
|
+
# @param timeout_duration [Numeric] the amount of time the subprocess was allowed
|
|
169
|
+
# to run before being killed
|
|
170
|
+
#
|
|
171
|
+
def initialize(result, timeout_duration)
|
|
172
|
+
@timeout_duration = timeout_duration
|
|
173
|
+
super(result)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# The human readable representation of this error
|
|
177
|
+
#
|
|
178
|
+
# @example
|
|
179
|
+
# error.error_message
|
|
180
|
+
# #=> '["sleep", "10"], status: pid 88811 SIGKILL (signal 9), stderr: "err output", timed out after 1s'
|
|
181
|
+
#
|
|
182
|
+
# @return [String]
|
|
183
|
+
#
|
|
184
|
+
def error_message = <<~MESSAGE.chomp
|
|
185
|
+
#{super}, timed out after #{timeout_duration}s
|
|
186
|
+
MESSAGE
|
|
187
|
+
|
|
188
|
+
# The amount of time the subprocess was allowed to run before being killed
|
|
189
|
+
#
|
|
190
|
+
# @example
|
|
191
|
+
# `kill -9 $$` # set $? appropriately for this example
|
|
192
|
+
# result = Git::CommandLineResult.new(%w[git status], $?, '', "killed")
|
|
193
|
+
# error = Git::TimeoutError.new(result, 10)
|
|
194
|
+
# error.timeout_duration #=> 10
|
|
195
|
+
#
|
|
196
|
+
# @return [Numeric]
|
|
197
|
+
#
|
|
198
|
+
attr_reader :timeout_duration
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Raised when the output of a git command can not be read
|
|
202
|
+
#
|
|
203
|
+
# @api public
|
|
204
|
+
#
|
|
205
|
+
class ProcessIOError < Git::Error; end
|
|
206
|
+
|
|
207
|
+
# Raised when the git command result was not as expected
|
|
208
|
+
#
|
|
209
|
+
# @api public
|
|
210
|
+
#
|
|
211
|
+
class UnexpectedResultError < Git::Error; end
|
|
212
|
+
end
|
data/lib/git/escaped_path.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Git
|
|
4
4
|
# Represents an escaped Git path string
|
|
5
5
|
#
|
|
6
|
-
# Git commands that output paths (e.g. ls-files, diff), will escape
|
|
6
|
+
# Git commands that output paths (e.g. ls-files, diff), will escape unusual
|
|
7
7
|
# characters in the path with backslashes in the same way C escapes control
|
|
8
8
|
# characters (e.g. \t for TAB, \n for LF, \\ for backslash) or bytes with values
|
|
9
9
|
# larger than 0x80 (e.g. octal \302\265 for "micro" in UTF-8).
|
|
@@ -42,7 +42,7 @@ module Git
|
|
|
42
42
|
private
|
|
43
43
|
|
|
44
44
|
def extract_octal(path, index)
|
|
45
|
-
[path[index + 1..index + 3].to_i(8), 4]
|
|
45
|
+
[path[(index + 1)..(index + 3)].to_i(8), 4]
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def extract_escape(path, index)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Represents an object returned by `git fsck`
|
|
5
|
+
#
|
|
6
|
+
# This class provides information about dangling, missing, unreachable, or
|
|
7
|
+
# problematic Git objects found during repository integrity checks.
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
#
|
|
11
|
+
class FsckObject
|
|
12
|
+
# The type of the Git object
|
|
13
|
+
# @return [Symbol] one of :commit, :tree, :blob, or :tag
|
|
14
|
+
attr_reader :type
|
|
15
|
+
|
|
16
|
+
# The SHA-1 hash of the object
|
|
17
|
+
# @return [String] the 40-character SHA-1 hash
|
|
18
|
+
attr_reader :sha
|
|
19
|
+
|
|
20
|
+
# A warning or error message associated with this object
|
|
21
|
+
# @return [String, nil] the message, or nil if no message
|
|
22
|
+
attr_reader :message
|
|
23
|
+
|
|
24
|
+
# A name describing how the object is reachable (from --name-objects)
|
|
25
|
+
# @return [String, nil] the name, or nil if not provided
|
|
26
|
+
attr_reader :name
|
|
27
|
+
|
|
28
|
+
# Create a new FsckObject
|
|
29
|
+
#
|
|
30
|
+
# @param type [Symbol] the object type (:commit, :tree, :blob, or :tag)
|
|
31
|
+
# @param sha [String] the 40-character SHA-1 hash
|
|
32
|
+
# @param message [String, nil] optional warning/error message
|
|
33
|
+
# @param name [String, nil] optional name from --name-objects (e.g., "HEAD~2^2:src/")
|
|
34
|
+
#
|
|
35
|
+
def initialize(type:, sha:, message: nil, name: nil)
|
|
36
|
+
@type = type
|
|
37
|
+
@sha = sha
|
|
38
|
+
@message = message
|
|
39
|
+
@name = name
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Returns the SHA as the string representation
|
|
43
|
+
# @return [String] the SHA-1 hash
|
|
44
|
+
def to_s
|
|
45
|
+
sha
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Represents the result of running `git fsck`
|
|
5
|
+
#
|
|
6
|
+
# This class provides structured access to the objects found during a
|
|
7
|
+
# repository integrity check, categorized by their status.
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
#
|
|
11
|
+
class FsckResult
|
|
12
|
+
# Objects not referenced by any other object
|
|
13
|
+
# @return [Array<Git::FsckObject>]
|
|
14
|
+
attr_reader :dangling
|
|
15
|
+
|
|
16
|
+
# Objects that are referenced but not present in the repository
|
|
17
|
+
# @return [Array<Git::FsckObject>]
|
|
18
|
+
attr_reader :missing
|
|
19
|
+
|
|
20
|
+
# Objects not reachable from any ref
|
|
21
|
+
# @return [Array<Git::FsckObject>]
|
|
22
|
+
attr_reader :unreachable
|
|
23
|
+
|
|
24
|
+
# Objects with warnings (each includes a message)
|
|
25
|
+
# @return [Array<Git::FsckObject>]
|
|
26
|
+
attr_reader :warnings
|
|
27
|
+
|
|
28
|
+
# Root nodes (commits with no parents) when --root is used
|
|
29
|
+
# @return [Array<Git::FsckObject>]
|
|
30
|
+
attr_reader :root
|
|
31
|
+
|
|
32
|
+
# Tagged objects when --tags is used
|
|
33
|
+
# @return [Array<Git::FsckObject>]
|
|
34
|
+
attr_reader :tagged
|
|
35
|
+
|
|
36
|
+
# rubocop:disable Metrics/ParameterLists
|
|
37
|
+
|
|
38
|
+
# Create a new FsckResult
|
|
39
|
+
#
|
|
40
|
+
# @param dangling [Array<Git::FsckObject>] dangling objects
|
|
41
|
+
# @param missing [Array<Git::FsckObject>] missing objects
|
|
42
|
+
# @param unreachable [Array<Git::FsckObject>] unreachable objects
|
|
43
|
+
# @param warnings [Array<Git::FsckObject>] objects with warnings
|
|
44
|
+
# @param root [Array<Git::FsckObject>] root nodes
|
|
45
|
+
# @param tagged [Array<Git::FsckObject>] tagged objects
|
|
46
|
+
#
|
|
47
|
+
def initialize(dangling: [], missing: [], unreachable: [], warnings: [], root: [], tagged: [])
|
|
48
|
+
@dangling = dangling
|
|
49
|
+
@missing = missing
|
|
50
|
+
@unreachable = unreachable
|
|
51
|
+
@warnings = warnings
|
|
52
|
+
@root = root
|
|
53
|
+
@tagged = tagged
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# rubocop:enable Metrics/ParameterLists
|
|
57
|
+
|
|
58
|
+
# Returns true if any issues were found
|
|
59
|
+
#
|
|
60
|
+
# @return [Boolean]
|
|
61
|
+
#
|
|
62
|
+
# @example
|
|
63
|
+
# result = git.fsck
|
|
64
|
+
# puts "Repository has issues!" if result.any_issues?
|
|
65
|
+
#
|
|
66
|
+
def any_issues?
|
|
67
|
+
[dangling, missing, unreachable, warnings].any?(&:any?)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns true if no issues were found
|
|
71
|
+
#
|
|
72
|
+
# @return [Boolean]
|
|
73
|
+
#
|
|
74
|
+
# @example
|
|
75
|
+
# result = git.fsck
|
|
76
|
+
# puts "Repository is clean" if result.empty?
|
|
77
|
+
#
|
|
78
|
+
def empty?
|
|
79
|
+
!any_issues?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns all objects from all categories (excluding informational root/tagged)
|
|
83
|
+
#
|
|
84
|
+
# @return [Array<Git::FsckObject>]
|
|
85
|
+
#
|
|
86
|
+
# @example
|
|
87
|
+
# result = git.fsck
|
|
88
|
+
# result.all_objects.each { |obj| puts obj.sha }
|
|
89
|
+
#
|
|
90
|
+
def all_objects
|
|
91
|
+
dangling + missing + unreachable + warnings
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Returns the total number of issues found
|
|
95
|
+
#
|
|
96
|
+
# @return [Integer]
|
|
97
|
+
#
|
|
98
|
+
# @example
|
|
99
|
+
# result = git.fsck
|
|
100
|
+
# puts "Found #{result.count} issues"
|
|
101
|
+
#
|
|
102
|
+
def count
|
|
103
|
+
all_objects.size
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Returns a hash representation of the result
|
|
107
|
+
#
|
|
108
|
+
# @return [Hash{Symbol => Array<Git::FsckObject>}]
|
|
109
|
+
#
|
|
110
|
+
# @example
|
|
111
|
+
# result = git.fsck
|
|
112
|
+
# result.to_h # => { dangling: [...], missing: [...], ... }
|
|
113
|
+
#
|
|
114
|
+
def to_h
|
|
115
|
+
{
|
|
116
|
+
dangling: dangling, missing: missing, unreachable: unreachable,
|
|
117
|
+
warnings: warnings, root: root, tagged: tagged
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|