git 1.19.1 → 3.1.1

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.commitlintrc.yml +38 -0
  3. data/.github/pull_request_template.md +8 -0
  4. data/.github/workflows/continuous_integration.yml +19 -21
  5. data/.github/workflows/enforce_conventional_commits.yml +28 -0
  6. data/.github/workflows/experimental_continuous_integration.yml +50 -0
  7. data/.github/workflows/release.yml +52 -0
  8. data/.gitignore +3 -0
  9. data/.husky/commit-msg +1 -0
  10. data/.release-please-manifest.json +3 -0
  11. data/.yardopts +0 -1
  12. data/CHANGELOG.md +211 -0
  13. data/CONTRIBUTING.md +290 -102
  14. data/README.md +180 -62
  15. data/Rakefile +7 -0
  16. data/git.gemspec +11 -11
  17. data/lib/git/author.rb +3 -2
  18. data/lib/git/base.rb +222 -59
  19. data/lib/git/branch.rb +2 -0
  20. data/lib/git/branches.rb +15 -14
  21. data/lib/git/command_line.rb +287 -0
  22. data/lib/git/config.rb +7 -1
  23. data/lib/git/diff.rb +2 -0
  24. data/lib/git/errors.rb +206 -0
  25. data/lib/git/escaped_path.rb +1 -1
  26. data/lib/git/index.rb +2 -1
  27. data/lib/git/lib.rb +604 -234
  28. data/lib/git/log.rb +74 -6
  29. data/lib/git/object.rb +80 -76
  30. data/lib/git/path.rb +9 -8
  31. data/lib/git/remote.rb +2 -0
  32. data/lib/git/repository.rb +2 -0
  33. data/lib/git/stash.rb +7 -6
  34. data/lib/git/stashes.rb +11 -10
  35. data/lib/git/status.rb +135 -25
  36. data/lib/git/version.rb +3 -1
  37. data/lib/git/working_directory.rb +2 -0
  38. data/lib/git/worktree.rb +2 -0
  39. data/lib/git/worktrees.rb +2 -0
  40. data/lib/git.rb +21 -7
  41. data/package.json +10 -0
  42. data/release-please-config.json +36 -0
  43. metadata +52 -38
  44. data/.github/stale.yml +0 -25
  45. data/Dockerfile.changelog-rs +0 -12
  46. data/PULL_REQUEST_TEMPLATE.md +0 -9
  47. data/RELEASING.md +0 -70
  48. data/lib/git/base/factory.rb +0 -99
  49. data/lib/git/failed_error.rb +0 -53
  50. data/lib/git/git_execute_error.rb +0 -7
  51. data/lib/git/signaled_error.rb +0 -50
  52. /data/{ISSUE_TEMPLATE.md → .github/issue_template.md} +0 -0
@@ -0,0 +1,287 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'git/base'
4
+ require 'git/command_line_result'
5
+ require 'git/errors'
6
+ require 'stringio'
7
+
8
+ module Git
9
+ # Runs a git command and returns the result
10
+ #
11
+ # @api public
12
+ #
13
+ class CommandLine
14
+ # Create a Git::CommandLine object
15
+ #
16
+ # @example
17
+ # env = { 'GIT_DIR' => '/path/to/git/dir' }
18
+ # binary_path = '/usr/bin/git'
19
+ # global_opts = %w[--git-dir /path/to/git/dir]
20
+ # logger = Logger.new(STDOUT)
21
+ # cli = CommandLine.new(env, binary_path, global_opts, logger)
22
+ # cli.run('version') #=> #<Git::CommandLineResult:0x00007f9b0c0b0e00
23
+ #
24
+ # @param env [Hash<String, String>] environment variables to set
25
+ # @param global_opts [Array<String>] global options to pass to git
26
+ # @param logger [Logger] the logger to use
27
+ #
28
+ def initialize(env, binary_path, global_opts, logger)
29
+ @env = env
30
+ @binary_path = binary_path
31
+ @global_opts = global_opts
32
+ @logger = logger
33
+ end
34
+
35
+ # @attribute [r] env
36
+ #
37
+ # Variables to set (or unset) in the git command's environment
38
+ #
39
+ # @example
40
+ # env = { 'GIT_DIR' => '/path/to/git/dir' }
41
+ # command_line = Git::CommandLine.new(env, '/usr/bin/git', [], Logger.new(STDOUT))
42
+ # command_line.env #=> { 'GIT_DIR' => '/path/to/git/dir' }
43
+ #
44
+ # @return [Hash<String, String>]
45
+ #
46
+ # @see https://ruby-doc.org/3.2.1/Process.html#method-c-spawn Process.spawn
47
+ # for details on how to set environment variables using the `env` parameter
48
+ #
49
+ attr_reader :env
50
+
51
+ # @attribute [r] binary_path
52
+ #
53
+ # The path to the command line binary to run
54
+ #
55
+ # @example
56
+ # binary_path = '/usr/bin/git'
57
+ # command_line = Git::CommandLine.new({}, binary_path, ['version'], Logger.new(STDOUT))
58
+ # command_line.binary_path #=> '/usr/bin/git'
59
+ #
60
+ # @return [String]
61
+ #
62
+ attr_reader :binary_path
63
+
64
+ # @attribute [r] global_opts
65
+ #
66
+ # The global options to pass to git
67
+ #
68
+ # These are options that are passed to git before the command name and
69
+ # arguments. For example, in `git --git-dir /path/to/git/dir version`, the
70
+ # global options are %w[--git-dir /path/to/git/dir].
71
+ #
72
+ # @example
73
+ # env = {}
74
+ # global_opts = %w[--git-dir /path/to/git/dir]
75
+ # logger = Logger.new(nil)
76
+ # cli = CommandLine.new(env, '/usr/bin/git', global_opts, logger)
77
+ # cli.global_opts #=> %w[--git-dir /path/to/git/dir]
78
+ #
79
+ # @return [Array<String>]
80
+ #
81
+ attr_reader :global_opts
82
+
83
+ # @attribute [r] logger
84
+ #
85
+ # The logger to use for logging git commands and results
86
+ #
87
+ # @example
88
+ # env = {}
89
+ # global_opts = %w[]
90
+ # logger = Logger.new(STDOUT)
91
+ # cli = CommandLine.new(env, '/usr/bin/git', global_opts, logger)
92
+ # cli.logger == logger #=> true
93
+ #
94
+ # @return [Logger]
95
+ #
96
+ attr_reader :logger
97
+
98
+ # Execute a git command, wait for it to finish, and return the result
99
+ #
100
+ # NORMALIZATION
101
+ #
102
+ # The command output is returned as a Unicde string containing the binary output
103
+ # from the command. If the binary output is not valid UTF-8, the output will
104
+ # cause problems because the encoding will be invalid.
105
+ #
106
+ # Normalization is a process that trys to convert the binary output to a valid
107
+ # UTF-8 string. It uses the `rchardet` gem to detect the encoding of the binary
108
+ # output and then converts it to UTF-8.
109
+ #
110
+ # Normalization is not enabled by default. Pass `normalize: true` to Git::CommandLine#run
111
+ # to enable it. Normalization will only be performed on stdout and only if the `out:`` option
112
+ # is nil or is a StringIO object. If the out: option is set to a file or other IO object,
113
+ # the normalize option will be ignored.
114
+ #
115
+ # @example Run a command and return the output
116
+ # cli.run('version') #=> "git version 2.39.1\n"
117
+ #
118
+ # @example The args array should be splatted into the parameter list
119
+ # args = %w[log -n 1 --oneline]
120
+ # cli.run(*args) #=> "f5baa11 beginning of Ruby/Git project\n"
121
+ #
122
+ # @example Run a command and return the chomped output
123
+ # cli.run('version', chomp: true) #=> "git version 2.39.1"
124
+ #
125
+ # @example Run a command and without normalizing the output
126
+ # cli.run('version', normalize: false) #=> "git version 2.39.1\n"
127
+ #
128
+ # @example Capture stdout in a temporary file
129
+ # require 'tempfile'
130
+ # tempfile = Tempfile.create('git') do |file|
131
+ # cli.run('version', out: file)
132
+ # file.rewind
133
+ # file.read #=> "git version 2.39.1\n"
134
+ # end
135
+ #
136
+ # @example Capture stderr in a StringIO object
137
+ # require 'stringio'
138
+ # stderr = StringIO.new
139
+ # begin
140
+ # cli.run('log', 'nonexistent-branch', err: stderr)
141
+ # rescue Git::FailedError => e
142
+ # stderr.string #=> "unknown revision or path not in the working tree.\n"
143
+ # end
144
+ #
145
+ # @param args [Array<String>] the command line arguements to pass to git
146
+ #
147
+ # This array should be splatted into the parameter list.
148
+ #
149
+ # @param out [#write, nil] the object to write stdout to or nil to ignore stdout
150
+ #
151
+ # If this is a 'StringIO' object, then `stdout_writer.string` will be returned.
152
+ #
153
+ # In general, only specify a `stdout_writer` object when you want to redirect
154
+ # stdout to a file or some other object that responds to `#write`. The default
155
+ # behavior will return the output of the command.
156
+ #
157
+ # @param err [#write] the object to write stderr to or nil to ignore stderr
158
+ #
159
+ # If this is a 'StringIO' object and `merged_output` is `true`, then
160
+ # `stderr_writer.string` will be merged into the output returned by this method.
161
+ #
162
+ # @param normalize [Boolean] whether to normalize the output to a valid encoding
163
+ #
164
+ # @param chomp [Boolean] whether to chomp the output
165
+ #
166
+ # @param merge [Boolean] whether to merge stdout and stderr in the string returned
167
+ #
168
+ # @param chdir [String] the directory to run the command in
169
+ #
170
+ # @param timeout [Numeric, nil] the maximum seconds to wait for the command to complete
171
+ #
172
+ # If timeout is zero, the timeout will not be enforced.
173
+ #
174
+ # If the command times out, it is killed via a `SIGKILL` signal and `Git::TimeoutError` is raised.
175
+ #
176
+ # If the command does not respond to SIGKILL, it will hang this method.
177
+ #
178
+ # @return [Git::CommandLineResult] the output of the command
179
+ #
180
+ # This result of running the command.
181
+ #
182
+ # @raise [ArgumentError] if `args` is not an array of strings
183
+ #
184
+ # @raise [Git::SignaledError] if the command was terminated because of an uncaught signal
185
+ #
186
+ # @raise [Git::FailedError] if the command returned a non-zero exitstatus
187
+ #
188
+ # @raise [Git::ProcessIOError] if an exception was raised while collecting subprocess output
189
+ #
190
+ # @raise [Git::TimeoutError] if the command times out
191
+ #
192
+ def run(*args, out: nil, err: nil, normalize:, chomp:, merge:, chdir: nil, timeout: nil)
193
+ git_cmd = build_git_cmd(args)
194
+ begin
195
+ result = ProcessExecuter.run(env, *git_cmd, out: out, err: err, merge:, chdir: (chdir || :not_set), timeout: timeout, raise_errors: false)
196
+ rescue ProcessExecuter::Command::ProcessIOError => e
197
+ raise Git::ProcessIOError.new(e.message), cause: e.exception.cause
198
+ end
199
+ process_result(result, normalize, chomp, timeout)
200
+ end
201
+
202
+ private
203
+
204
+ # Build the git command line from the available sources to send to `Process.spawn`
205
+ # @return [Array<String>]
206
+ # @api private
207
+ #
208
+ def build_git_cmd(args)
209
+ raise ArgumentError.new('The args array can not contain an array') if args.any? { |a| a.is_a?(Array) }
210
+
211
+ [binary_path, *global_opts, *args].map { |e| e.to_s }
212
+ end
213
+
214
+ # Process the result of the command and return a Git::CommandLineResult
215
+ #
216
+ # Post process output, log the command and result, and raise an error if the
217
+ # command failed.
218
+ #
219
+ # @param result [ProcessExecuter::Command::Result] the result it is a Process::Status and include command, stdout, and stderr
220
+ # @param normalize [Boolean] whether to normalize the output of each writer
221
+ # @param chomp [Boolean] whether to chomp the output of each writer
222
+ # @param timeout [Numeric, nil] the maximum seconds to wait for the command to complete
223
+ #
224
+ # @return [Git::CommandLineResult] the result of the command to return to the caller
225
+ #
226
+ # @raise [Git::FailedError] if the command failed
227
+ # @raise [Git::SignaledError] if the command was signaled
228
+ # @raise [Git::TimeoutError] if the command times out
229
+ # @raise [Git::ProcessIOError] if an exception was raised while collecting subprocess output
230
+ #
231
+ # @api private
232
+ #
233
+ def process_result(result, normalize, chomp, timeout)
234
+ command = result.command
235
+ processed_out, processed_err = post_process_all([result.stdout, result.stderr], normalize, chomp)
236
+ logger.info { "#{command} exited with status #{result}" }
237
+ logger.debug { "stdout:\n#{processed_out.inspect}\nstderr:\n#{processed_err.inspect}" }
238
+ Git::CommandLineResult.new(command, result, processed_out, processed_err).tap do |processed_result|
239
+ raise Git::TimeoutError.new(processed_result, timeout) if result.timeout?
240
+ raise Git::SignaledError.new(processed_result) if result.signaled?
241
+ raise Git::FailedError.new(processed_result) unless result.success?
242
+ end
243
+ end
244
+
245
+ # Post-process command output and return an array of the results
246
+ #
247
+ # @param raw_outputs [Array] the output to post-process
248
+ # @param normalize [Boolean] whether to normalize the output of each writer
249
+ # @param chomp [Boolean] whether to chomp the output of each writer
250
+ #
251
+ # @return [Array<String, nil>] the processed output of each command output object that supports `#string`
252
+ #
253
+ # @api private
254
+ #
255
+ def post_process_all(raw_outputs, normalize, chomp)
256
+ Array.new.tap do |result|
257
+ raw_outputs.each { |raw_output| result << post_process(raw_output, normalize, chomp) }
258
+ end
259
+ end
260
+
261
+ # Determine the output to return in the `CommandLineResult`
262
+ #
263
+ # If the writer can return the output by calling `#string` (such as a StringIO),
264
+ # then return the result of normalizing the encoding and chomping the output
265
+ # as requested.
266
+ #
267
+ # If the writer does not support `#string`, then return nil. The output is
268
+ # assumed to be collected by the writer itself such as when the writer
269
+ # is a file instead of a StringIO.
270
+ #
271
+ # @param raw_output [#string] the output to post-process
272
+ # @return [String, nil]
273
+ #
274
+ # @api private
275
+ #
276
+ def post_process(raw_output, normalize, chomp)
277
+ if raw_output.respond_to?(:string)
278
+ output = raw_output.string.dup
279
+ output = output.lines.map { |l| Git::EncodingUtils.normalize_encoding(l) }.join if normalize
280
+ output.chomp! if chomp
281
+ output
282
+ else
283
+ nil
284
+ end
285
+ end
286
+ end
287
+ end
data/lib/git/config.rb CHANGED
@@ -1,12 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Git
2
4
 
3
5
  class Config
4
6
 
5
- attr_writer :binary_path, :git_ssh
7
+ attr_writer :binary_path, :git_ssh, :timeout
6
8
 
7
9
  def initialize
8
10
  @binary_path = nil
9
11
  @git_ssh = nil
12
+ @timeout = nil
10
13
  end
11
14
 
12
15
  def binary_path
@@ -17,6 +20,9 @@ module Git
17
20
  @git_ssh || ENV['GIT_SSH']
18
21
  end
19
22
 
23
+ def timeout
24
+ @timeout || (ENV['GIT_TIMEOUT'] && ENV['GIT_TIMEOUT'].to_i)
25
+ end
20
26
  end
21
27
 
22
28
  end
data/lib/git/diff.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Git
2
4
 
3
5
  # object that holds the last X commits on given branch
data/lib/git/errors.rb ADDED
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Git
4
+ # Base class for all custom git module errors
5
+ #
6
+ # The git gem will only raise an `ArgumentError` or an error that is a subclass of
7
+ # `Git::Error`. It does not explicitly raise any other types of errors.
8
+ #
9
+ # It is recommended to rescue `Git::Error` to catch any runtime error raised by
10
+ # this gem unless you need more specific error handling.
11
+ #
12
+ # Git's custom errors are arranged in the following class heirarchy:
13
+ #
14
+ # ```text
15
+ # StandardError
16
+ # └─> Git::Error
17
+ # ├─> Git::CommandLineError
18
+ # │ ├─> Git::FailedError
19
+ # │ └─> Git::SignaledError
20
+ # │ └─> Git::TimeoutError
21
+ # ├─> Git::ProcessIOError
22
+ # └─> Git::UnexpectedResultError
23
+ # ```
24
+ #
25
+ # | Error Class | Description |
26
+ # | --- | --- |
27
+ # | `Error` | This catch-all error serves as the base class for other custom errors raised by the git gem. |
28
+ # | `CommandLineError` | A subclass of this error is raised when there is a problem executing the git command line. |
29
+ # | `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. |
30
+ # | `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. |
31
+ # | `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. |
32
+ # | `ProcessIOError` | An error was encountered reading or writing to a subprocess. |
33
+ # | `UnexpectedResultError` | The command line ran without error but did not return the expected results. |
34
+ #
35
+ # @example Rescuing a generic error
36
+ # begin
37
+ # # some git operation
38
+ # rescue Git::Error => e
39
+ # puts "An error occurred: #{e.message}"
40
+ # end
41
+ #
42
+ # @example Rescuing a timeout error
43
+ # begin
44
+ # timeout_duration = 0.001 # seconds
45
+ # repo = Git.clone('https://github.com/ruby-git/ruby-git', 'ruby-git-temp', timeout: timeout_duration)
46
+ # rescue Git::TimeoutError => e # Catch the more specific error first!
47
+ # puts "Git clone took too long and timed out #{e}"
48
+ # rescue Git::Error => e
49
+ # puts "Received the following error: #{e}"
50
+ # end
51
+ #
52
+ # @see Git::CommandLineError
53
+ # @see Git::FailedError
54
+ # @see Git::SignaledError
55
+ # @see Git::TimeoutError
56
+ # @see Git::ProcessIOError
57
+ # @see Git::UnexpectedResultError
58
+ #
59
+ # @api public
60
+ #
61
+ class Error < StandardError; end
62
+
63
+ # An alias for Git::Error
64
+ #
65
+ # Git::GitExecuteError error class is an alias for Git::Error for backwards
66
+ # compatibility. It is recommended to use Git::Error directly.
67
+ #
68
+ # @deprecated Use Git::Error instead
69
+ #
70
+ GitExecuteError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Git::GitExecuteError', 'Git::Error', Git::Deprecation)
71
+
72
+ # Raised when a git command fails or exits because of an uncaught signal
73
+ #
74
+ # The git command executed, status, stdout, and stderr are available from this
75
+ # object.
76
+ #
77
+ # The Gem will raise a more specific error for each type of failure:
78
+ #
79
+ # * {Git::FailedError}: when the git command exits with a non-zero status
80
+ # * {Git::SignaledError}: when the git command exits because of an uncaught signal
81
+ # * {Git::TimeoutError}: when the git command times out
82
+ #
83
+ # @api public
84
+ #
85
+ class CommandLineError < Git::Error
86
+ # Create a CommandLineError object
87
+ #
88
+ # @example
89
+ # `exit 1` # set $? appropriately for this example
90
+ # result = Git::CommandLineResult.new(%w[git status], $?, 'stdout', 'stderr')
91
+ # error = Git::CommandLineError.new(result)
92
+ # error.to_s #=> '["git", "status"], status: pid 89784 exit 1, stderr: "stderr"'
93
+ #
94
+ # @param result [Git::CommandLineResult] the result of the git command including
95
+ # the git command, status, stdout, and stderr
96
+ #
97
+ def initialize(result)
98
+ @result = result
99
+ super(error_message)
100
+ end
101
+
102
+ # The human readable representation of this error
103
+ #
104
+ # @example
105
+ # error.error_message #=> '["git", "status"], status: pid 89784 exit 1, stderr: "stderr"'
106
+ #
107
+ # @return [String]
108
+ #
109
+ def error_message = <<~MESSAGE.chomp
110
+ #{result.git_cmd}, status: #{result.status}, stderr: #{result.stderr.inspect}
111
+ MESSAGE
112
+
113
+ # @attribute [r] result
114
+ #
115
+ # The result of the git command including the git command and its status and output
116
+ #
117
+ # @example
118
+ # error.result #=> #<Git::CommandLineResult:0x00000001046bd488 ...>
119
+ #
120
+ # @return [Git::CommandLineResult]
121
+ #
122
+ attr_reader :result
123
+ end
124
+
125
+ # This error is raised when a git command returns a non-zero exitstatus
126
+ #
127
+ # The git command executed, status, stdout, and stderr are available from this
128
+ # object.
129
+ #
130
+ # @api public
131
+ #
132
+ class FailedError < Git::CommandLineError; end
133
+
134
+ # This error is raised when a git command exits because of an uncaught signal
135
+ #
136
+ # @api public
137
+ #
138
+ class SignaledError < Git::CommandLineError; end
139
+
140
+ # This error is raised when a git command takes longer than the configured timeout
141
+ #
142
+ # The git command executed, status, stdout, and stderr, and the timeout duration
143
+ # are available from this object.
144
+ #
145
+ # result.status.timeout? will be `true`
146
+ #
147
+ # @api public
148
+ #
149
+ class TimeoutError < Git::SignaledError
150
+ # Create a TimeoutError object
151
+ #
152
+ # @example
153
+ # command = %w[sleep 10]
154
+ # timeout_duration = 1
155
+ # status = ProcessExecuter.spawn(*command, timeout: timeout_duration)
156
+ # result = Git::CommandLineResult.new(command, status, 'stdout', 'err output')
157
+ # error = Git::TimeoutError.new(result, timeout_duration)
158
+ # error.error_message #=> '["sleep", "10"], status: pid 70144 SIGKILL (signal 9), stderr: "err output", timed out after 1s'
159
+ #
160
+ # @param result [Git::CommandLineResult] the result of the git command including
161
+ # the git command, status, stdout, and stderr
162
+ #
163
+ # @param timeout_duration [Numeric] the amount of time the subprocess was allowed
164
+ # to run before being killed
165
+ #
166
+ def initialize(result, timeout_duration)
167
+ @timeout_duration = timeout_duration
168
+ super(result)
169
+ end
170
+
171
+ # The human readable representation of this error
172
+ #
173
+ # @example
174
+ # error.error_message #=> '["sleep", "10"], status: pid 88811 SIGKILL (signal 9), stderr: "err output", timed out after 1s'
175
+ #
176
+ # @return [String]
177
+ #
178
+ def error_message = <<~MESSAGE.chomp
179
+ #{super}, timed out after #{timeout_duration}s
180
+ MESSAGE
181
+
182
+ # The amount of time the subprocess was allowed to run before being killed
183
+ #
184
+ # @example
185
+ # `kill -9 $$` # set $? appropriately for this example
186
+ # result = Git::CommandLineResult.new(%w[git status], $?, '', "killed")
187
+ # error = Git::TimeoutError.new(result, 10)
188
+ # error.timeout_duration #=> 10
189
+ #
190
+ # @return [Numeric]
191
+ #
192
+ attr_reader :timeout_duration
193
+ end
194
+
195
+ # Raised when the output of a git command can not be read
196
+ #
197
+ # @api public
198
+ #
199
+ class ProcessIOError < Git::Error; end
200
+
201
+ # Raised when the git command result was not as expected
202
+ #
203
+ # @api public
204
+ #
205
+ class UnexpectedResultError < Git::Error; end
206
+ end
@@ -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 usual
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).
data/lib/git/index.rb CHANGED
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Git
2
4
  class Index < Git::Path
3
-
4
5
  end
5
6
  end