git 1.19.1 → 5.5.0
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/.yardopts +5 -1
- data/AI_POLICY.md +24 -0
- data/CHANGELOG.md +689 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +1175 -97
- data/GOVERNANCE.md +106 -0
- data/LICENSE +1 -1
- data/MAINTAINERS.md +17 -4
- data/README.md +476 -320
- data/UPGRADING.md +1138 -0
- data/git.gemspec +124 -36
- data/lib/git/author.rb +39 -7
- data/lib/git/author_info.rb +66 -0
- data/lib/git/branch.rb +615 -65
- data/lib/git/branch_delete_failure.rb +34 -0
- data/lib/git/branch_delete_result.rb +66 -0
- data/lib/git/branch_info.rb +237 -0
- data/lib/git/branches.rb +167 -44
- data/lib/git/command_line/base.rb +247 -0
- data/lib/git/command_line/capturing.rb +308 -0
- data/lib/git/command_line/result.rb +88 -0
- data/lib/git/command_line/streaming.rb +236 -0
- data/lib/git/command_line.rb +52 -0
- data/lib/git/commands/add.rb +139 -0
- data/lib/git/commands/am/abort.rb +43 -0
- data/lib/git/commands/am/apply.rb +263 -0
- data/lib/git/commands/am/continue.rb +43 -0
- data/lib/git/commands/am/quit.rb +43 -0
- data/lib/git/commands/am/retry.rb +49 -0
- data/lib/git/commands/am/show_current_patch.rb +64 -0
- data/lib/git/commands/am/skip.rb +42 -0
- data/lib/git/commands/am.rb +33 -0
- data/lib/git/commands/apply.rb +242 -0
- data/lib/git/commands/archive/list_formats.rb +46 -0
- data/lib/git/commands/archive.rb +145 -0
- data/lib/git/commands/arguments.rb +4521 -0
- data/lib/git/commands/base.rb +502 -0
- data/lib/git/commands/branch/copy.rb +102 -0
- data/lib/git/commands/branch/create.rb +177 -0
- data/lib/git/commands/branch/delete.rb +88 -0
- data/lib/git/commands/branch/list.rb +178 -0
- data/lib/git/commands/branch/move.rb +102 -0
- data/lib/git/commands/branch/set_upstream.rb +86 -0
- data/lib/git/commands/branch/show_current.rb +49 -0
- data/lib/git/commands/branch/unset_upstream.rb +53 -0
- data/lib/git/commands/branch.rb +34 -0
- data/lib/git/commands/cat_file/batch.rb +385 -0
- data/lib/git/commands/cat_file/filtered.rb +105 -0
- data/lib/git/commands/cat_file/raw.rb +271 -0
- data/lib/git/commands/cat_file.rb +49 -0
- data/lib/git/commands/checkout/branch.rb +153 -0
- data/lib/git/commands/checkout/files.rb +116 -0
- data/lib/git/commands/checkout.rb +38 -0
- data/lib/git/commands/checkout_index.rb +106 -0
- data/lib/git/commands/clean.rb +102 -0
- data/lib/git/commands/clone.rb +241 -0
- data/lib/git/commands/commit.rb +273 -0
- data/lib/git/commands/commit_tree.rb +101 -0
- data/lib/git/commands/config_option_syntax/add.rb +86 -0
- data/lib/git/commands/config_option_syntax/get.rb +121 -0
- data/lib/git/commands/config_option_syntax/get_all.rb +118 -0
- data/lib/git/commands/config_option_syntax/get_color.rb +95 -0
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +96 -0
- data/lib/git/commands/config_option_syntax/get_regexp.rb +119 -0
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +111 -0
- data/lib/git/commands/config_option_syntax/list.rb +111 -0
- data/lib/git/commands/config_option_syntax/remove_section.rb +79 -0
- data/lib/git/commands/config_option_syntax/rename_section.rb +83 -0
- data/lib/git/commands/config_option_syntax/replace_all.rb +109 -0
- data/lib/git/commands/config_option_syntax/set.rb +119 -0
- data/lib/git/commands/config_option_syntax/unset.rb +92 -0
- data/lib/git/commands/config_option_syntax/unset_all.rb +94 -0
- data/lib/git/commands/config_option_syntax.rb +56 -0
- data/lib/git/commands/describe.rb +156 -0
- data/lib/git/commands/diff.rb +657 -0
- data/lib/git/commands/diff_files.rb +519 -0
- data/lib/git/commands/diff_index.rb +499 -0
- data/lib/git/commands/fetch.rb +354 -0
- data/lib/git/commands/fsck.rb +138 -0
- data/lib/git/commands/gc.rb +134 -0
- data/lib/git/commands/grep.rb +339 -0
- data/lib/git/commands/init.rb +101 -0
- data/lib/git/commands/log.rb +634 -0
- data/lib/git/commands/ls_files.rb +195 -0
- data/lib/git/commands/ls_remote.rb +161 -0
- data/lib/git/commands/ls_tree.rb +135 -0
- data/lib/git/commands/maintenance/register.rb +77 -0
- data/lib/git/commands/maintenance/run.rb +109 -0
- data/lib/git/commands/maintenance/start.rb +71 -0
- data/lib/git/commands/maintenance/stop.rb +60 -0
- data/lib/git/commands/maintenance/unregister.rb +84 -0
- data/lib/git/commands/maintenance.rb +31 -0
- data/lib/git/commands/merge/abort.rb +44 -0
- data/lib/git/commands/merge/continue.rb +44 -0
- data/lib/git/commands/merge/quit.rb +46 -0
- data/lib/git/commands/merge/start.rb +250 -0
- data/lib/git/commands/merge.rb +28 -0
- data/lib/git/commands/merge_base.rb +91 -0
- data/lib/git/commands/mv.rb +82 -0
- data/lib/git/commands/name_rev.rb +119 -0
- data/lib/git/commands/pull.rb +382 -0
- data/lib/git/commands/push.rb +251 -0
- data/lib/git/commands/read_tree.rb +154 -0
- data/lib/git/commands/remote/add.rb +96 -0
- data/lib/git/commands/remote/get_url.rb +68 -0
- data/lib/git/commands/remote/list.rb +56 -0
- data/lib/git/commands/remote/prune.rb +63 -0
- data/lib/git/commands/remote/remove.rb +52 -0
- data/lib/git/commands/remote/rename.rb +76 -0
- data/lib/git/commands/remote/set_branches.rb +70 -0
- data/lib/git/commands/remote/set_head.rb +89 -0
- data/lib/git/commands/remote/set_url.rb +78 -0
- data/lib/git/commands/remote/set_url_add.rb +70 -0
- data/lib/git/commands/remote/set_url_delete.rb +71 -0
- data/lib/git/commands/remote/show.rb +77 -0
- data/lib/git/commands/remote/update.rb +79 -0
- data/lib/git/commands/remote.rb +42 -0
- data/lib/git/commands/repack.rb +281 -0
- data/lib/git/commands/reset.rb +154 -0
- data/lib/git/commands/rev_parse.rb +304 -0
- data/lib/git/commands/revert/abort.rb +45 -0
- data/lib/git/commands/revert/continue.rb +62 -0
- data/lib/git/commands/revert/quit.rb +47 -0
- data/lib/git/commands/revert/skip.rb +44 -0
- data/lib/git/commands/revert/start.rb +158 -0
- data/lib/git/commands/revert.rb +29 -0
- data/lib/git/commands/rm.rb +113 -0
- data/lib/git/commands/show.rb +632 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +119 -0
- data/lib/git/commands/show_ref/exists.rb +80 -0
- data/lib/git/commands/show_ref/list.rb +149 -0
- data/lib/git/commands/show_ref/verify.rb +122 -0
- data/lib/git/commands/show_ref.rb +42 -0
- data/lib/git/commands/stash/apply.rb +81 -0
- data/lib/git/commands/stash/branch.rb +67 -0
- data/lib/git/commands/stash/clear.rb +43 -0
- data/lib/git/commands/stash/create.rb +60 -0
- data/lib/git/commands/stash/drop.rb +73 -0
- data/lib/git/commands/stash/list.rb +43 -0
- data/lib/git/commands/stash/pop.rb +87 -0
- data/lib/git/commands/stash/push.rb +112 -0
- data/lib/git/commands/stash/show.rb +158 -0
- data/lib/git/commands/stash/store.rb +72 -0
- data/lib/git/commands/stash.rb +38 -0
- data/lib/git/commands/status.rb +174 -0
- data/lib/git/commands/symbolic_ref/delete.rb +72 -0
- data/lib/git/commands/symbolic_ref/read.rb +99 -0
- data/lib/git/commands/symbolic_ref/update.rb +79 -0
- data/lib/git/commands/symbolic_ref.rb +38 -0
- data/lib/git/commands/tag/create.rb +142 -0
- data/lib/git/commands/tag/delete.rb +57 -0
- data/lib/git/commands/tag/list.rb +146 -0
- data/lib/git/commands/tag/verify.rb +71 -0
- data/lib/git/commands/tag.rb +26 -0
- data/lib/git/commands/update_ref/batch.rb +145 -0
- data/lib/git/commands/update_ref/delete.rb +90 -0
- data/lib/git/commands/update_ref/update.rb +103 -0
- data/lib/git/commands/update_ref.rb +42 -0
- data/lib/git/commands/version.rb +60 -0
- data/lib/git/commands/worktree/add.rb +139 -0
- data/lib/git/commands/worktree/list.rb +64 -0
- data/lib/git/commands/worktree/lock.rb +58 -0
- data/lib/git/commands/worktree/management_base.rb +51 -0
- data/lib/git/commands/worktree/move.rb +66 -0
- data/lib/git/commands/worktree/prune.rb +67 -0
- data/lib/git/commands/worktree/remove.rb +63 -0
- data/lib/git/commands/worktree/repair.rb +76 -0
- data/lib/git/commands/worktree/unlock.rb +47 -0
- data/lib/git/commands/worktree.rb +43 -0
- data/lib/git/commands/write_tree.rb +68 -0
- data/lib/git/commands.rb +88 -0
- data/lib/git/config.rb +72 -5
- data/lib/git/config_entry_info.rb +106 -0
- data/lib/git/configuring.rb +795 -0
- data/lib/git/detached_head_info.rb +57 -0
- data/lib/git/diff.rb +437 -86
- data/lib/git/diff_file_numstat_info.rb +31 -0
- data/lib/git/diff_file_patch_info.rb +136 -0
- data/lib/git/diff_file_raw_info.rb +129 -0
- data/lib/git/diff_info.rb +162 -0
- data/lib/git/diff_path_status.rb +107 -0
- data/lib/git/diff_result.rb +34 -0
- data/lib/git/diff_stats.rb +111 -0
- data/lib/git/dirstat_info.rb +102 -0
- data/lib/git/encoding_utils.rb +32 -1
- data/lib/git/errors.rb +285 -0
- data/lib/git/escaped_path.rb +57 -5
- data/lib/git/execution_context/global.rb +31 -0
- data/lib/git/execution_context/repository.rb +151 -0
- data/lib/git/execution_context.rb +559 -0
- data/lib/git/factories.rb +813 -0
- data/lib/git/file_ref.rb +77 -0
- data/lib/git/fsck_object.rb +56 -0
- data/lib/git/fsck_result.rb +132 -0
- data/lib/git/log.rb +306 -90
- data/lib/git/object.rb +563 -141
- data/lib/git/parsers/branch.rb +240 -0
- data/lib/git/parsers/cat_file.rb +111 -0
- data/lib/git/parsers/config_entry.rb +110 -0
- data/lib/git/parsers/diff.rb +792 -0
- data/lib/git/parsers/fsck.rb +144 -0
- data/lib/git/parsers/grep.rb +42 -0
- data/lib/git/parsers/ls_remote.rb +79 -0
- data/lib/git/parsers/ls_tree.rb +58 -0
- data/lib/git/parsers/remote.rb +162 -0
- data/lib/git/parsers/stash.rb +292 -0
- data/lib/git/parsers/status.rb +251 -0
- data/lib/git/parsers/tag.rb +341 -0
- data/lib/git/parsers/worktree.rb +185 -0
- data/lib/git/path_resolver.rb +206 -0
- data/lib/git/remote.rb +165 -12
- data/lib/git/remote_info.rb +203 -0
- data/lib/git/repository/branching.rb +964 -0
- data/lib/git/repository/committing.rb +246 -0
- data/lib/git/repository/context_helpers.rb +293 -0
- data/lib/git/repository/diffing.rb +785 -0
- data/lib/git/repository/inspecting.rb +252 -0
- data/lib/git/repository/logging.rb +410 -0
- data/lib/git/repository/maintenance.rb +65 -0
- data/lib/git/repository/merging.rb +451 -0
- data/lib/git/repository/object_operations.rb +1551 -0
- data/lib/git/repository/remote_operations.rb +984 -0
- data/lib/git/repository/shared_private.rb +120 -0
- data/lib/git/repository/staging.rb +587 -0
- data/lib/git/repository/stashing.rb +623 -0
- data/lib/git/repository/status_operations.rb +249 -0
- data/lib/git/repository/worktree_operations.rb +339 -0
- data/lib/git/repository.rb +484 -2
- data/lib/git/stash.rb +109 -12
- data/lib/git/stash_info.rb +102 -0
- data/lib/git/stashes.rb +169 -26
- data/lib/git/status.rb +308 -122
- data/lib/git/status_file_info.rb +258 -0
- data/lib/git/status_info.rb +189 -0
- data/lib/git/tag_delete_failure.rb +34 -0
- data/lib/git/tag_delete_result.rb +66 -0
- data/lib/git/tag_info.rb +99 -0
- data/lib/git/url.rb +15 -8
- data/lib/git/version.rb +113 -2
- data/lib/git/version_constraint.rb +85 -0
- data/lib/git/worktree.rb +150 -8
- data/lib/git/worktree_info.rb +128 -0
- data/lib/git/worktrees.rb +118 -13
- data/lib/git.rb +632 -234
- metadata +369 -54
- data/.github/stale.yml +0 -25
- data/.github/workflows/continuous_integration.yml +0 -49
- data/.gitignore +0 -10
- data/Dockerfile.changelog-rs +0 -12
- data/Gemfile +0 -5
- data/ISSUE_TEMPLATE.md +0 -15
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- data/RELEASING.md +0 -70
- data/Rakefile +0 -60
- data/lib/git/base/factory.rb +0 -99
- data/lib/git/base.rb +0 -711
- data/lib/git/command_line_result.rb +0 -86
- data/lib/git/failed_error.rb +0 -53
- data/lib/git/git_execute_error.rb +0 -7
- data/lib/git/index.rb +0 -5
- data/lib/git/lib.rb +0 -1328
- data/lib/git/path.rb +0 -31
- data/lib/git/signaled_error.rb +0 -50
- data/lib/git/working_directory.rb +0 -4
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/command_line/base'
|
|
4
|
+
require 'stringio'
|
|
5
|
+
|
|
6
|
+
module Git
|
|
7
|
+
module CommandLine
|
|
8
|
+
# Executes a git command in streaming mode without buffering stdout in memory
|
|
9
|
+
#
|
|
10
|
+
# {Git::CommandLine::Streaming} is the non-buffering strategy: it calls
|
|
11
|
+
# `ProcessExecuter.run` and streams stdout directly to the caller-supplied `out:`
|
|
12
|
+
# IO object. Stderr is always captured internally in a `StringIO` for error
|
|
13
|
+
# diagnostics and is available as `result.stderr`.
|
|
14
|
+
#
|
|
15
|
+
# Use this class (via {Git::ExecutionContext#command_streaming}) for commands such as
|
|
16
|
+
# `cat-file -p <blob>` whose stdout may be too large to buffer in memory.
|
|
17
|
+
#
|
|
18
|
+
# {Git::CommandLine::Capturing} is the complementary strategy for the common case
|
|
19
|
+
# where buffering stdout is acceptable.
|
|
20
|
+
#
|
|
21
|
+
# @example Stream a blob to a file
|
|
22
|
+
# streaming = Git::CommandLine::Streaming.new(
|
|
23
|
+
# {}, '/usr/bin/git', %w[--git-dir /repo/.git], Logger.new($stdout)
|
|
24
|
+
# )
|
|
25
|
+
# File.open('/tmp/blob', 'wb') do |f|
|
|
26
|
+
# streaming.run('cat-file', 'blob', sha, out: f)
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# @see Git::ExecutionContext#command_streaming
|
|
30
|
+
#
|
|
31
|
+
# @see Git::CommandLine::Capturing
|
|
32
|
+
#
|
|
33
|
+
# @api private
|
|
34
|
+
#
|
|
35
|
+
class Streaming < Git::CommandLine::Base
|
|
36
|
+
# Default options accepted by {#run}
|
|
37
|
+
#
|
|
38
|
+
# @api private
|
|
39
|
+
RUN_OPTION_DEFAULTS = {
|
|
40
|
+
in: nil,
|
|
41
|
+
out: nil,
|
|
42
|
+
err: nil,
|
|
43
|
+
chdir: nil,
|
|
44
|
+
timeout: nil,
|
|
45
|
+
raise_on_failure: true,
|
|
46
|
+
env: {}
|
|
47
|
+
}.freeze
|
|
48
|
+
|
|
49
|
+
# Execute a git command in streaming mode and return the result
|
|
50
|
+
#
|
|
51
|
+
# Unlike {Git::CommandLine::Capturing#run}, this method does **not** buffer
|
|
52
|
+
# stdout in memory. Stdout is written only to the IO object provided via the
|
|
53
|
+
# `out:` option. Stderr is captured internally via a `StringIO` for error
|
|
54
|
+
# diagnostics.
|
|
55
|
+
#
|
|
56
|
+
# Use this entry point for commands that stream large content (e.g. blobs)
|
|
57
|
+
# where capturing stdout in memory would be unacceptable.
|
|
58
|
+
#
|
|
59
|
+
# @example Stream a blob to a file
|
|
60
|
+
# file = File.open('/tmp/blob', 'wb')
|
|
61
|
+
# streaming.run('cat-file', 'blob', sha, out: file)
|
|
62
|
+
#
|
|
63
|
+
# @param options_hash [Hash] the options to pass to the command
|
|
64
|
+
#
|
|
65
|
+
# @option options_hash [IO, nil] :in the IO object to use as stdin for the
|
|
66
|
+
# command, or nil to inherit the parent process stdin. Must be a real IO
|
|
67
|
+
# object with a file descriptor (not StringIO).
|
|
68
|
+
#
|
|
69
|
+
# @option options_hash [#write, nil] :out the IO/object to stream stdout into.
|
|
70
|
+
# Stdout is NOT buffered in the returned result; this is the only way to
|
|
71
|
+
# read it.
|
|
72
|
+
#
|
|
73
|
+
# @option options_hash [#write, nil] :err an optional additional destination to
|
|
74
|
+
# receive stderr output in real time (e.g. `$stderr` or a `File`). Stderr is
|
|
75
|
+
# always captured internally in a `StringIO` for error diagnostics. When
|
|
76
|
+
# `err:` is provided, writes are teed to both the internal buffer and this
|
|
77
|
+
# destination. `result.stderr` always reflects what was captured in the
|
|
78
|
+
# internal buffer, regardless of whether `err:` is supplied.
|
|
79
|
+
#
|
|
80
|
+
# @option options_hash [String, nil] :chdir the directory to run the command in
|
|
81
|
+
#
|
|
82
|
+
# @option options_hash [Numeric, nil] :timeout the maximum seconds to wait for
|
|
83
|
+
# the command to complete. Zero means no timeout. A timeout kills the
|
|
84
|
+
# process via `SIGKILL` and raises {Git::TimeoutError}.
|
|
85
|
+
#
|
|
86
|
+
# @option options_hash [Boolean] :raise_on_failure (true) whether to raise
|
|
87
|
+
# {Git::FailedError} on non-zero exit status.
|
|
88
|
+
# {Git::TimeoutError} and {Git::SignaledError} are always raised regardless.
|
|
89
|
+
#
|
|
90
|
+
# @option options_hash [Hash] :env ({}) additional environment variable
|
|
91
|
+
# overrides for this command. String keys map to String values (to set) or
|
|
92
|
+
# `nil` (to unset).
|
|
93
|
+
#
|
|
94
|
+
# @return [Git::CommandLine::Result] the result of the command
|
|
95
|
+
#
|
|
96
|
+
# `result.stdout` will always be `''` (empty) — stdout was streamed to `out:`.
|
|
97
|
+
# `result.stderr` contains any stderr output captured for diagnostics.
|
|
98
|
+
#
|
|
99
|
+
# @raise [ArgumentError] if `args` contains an array or an unknown option is
|
|
100
|
+
# passed
|
|
101
|
+
#
|
|
102
|
+
# @raise [Git::SignaledError] if the command was terminated by an uncaught signal
|
|
103
|
+
#
|
|
104
|
+
# @raise [Git::FailedError] if the command returned a non-zero exit status
|
|
105
|
+
#
|
|
106
|
+
# @raise [Git::ProcessIOError] if an exception was raised while collecting
|
|
107
|
+
# subprocess output, or (Ruby 4.0+) if a timeout-handling race causes
|
|
108
|
+
# `Errno::ESRCH` when the spawned process exits between the timeout
|
|
109
|
+
# firing and the kill signal being delivered
|
|
110
|
+
#
|
|
111
|
+
# @raise [Git::TimeoutError] if the command times out
|
|
112
|
+
#
|
|
113
|
+
def run(*, **options_hash)
|
|
114
|
+
options = merge_and_validate_options(RUN_OPTION_DEFAULTS, options_hash)
|
|
115
|
+
|
|
116
|
+
internal_err = StringIO.new
|
|
117
|
+
# Tee stderr to the caller-provided destination (if any) AND the internal
|
|
118
|
+
# StringIO. This ensures result.stderr is always available even when err:
|
|
119
|
+
# is a non-StringIO IO object.
|
|
120
|
+
err_dest = options[:err] ? build_stderr_tee(internal_err, options[:err]) : internal_err
|
|
121
|
+
result = execute(*, err_io: err_dest, **options)
|
|
122
|
+
process_result(result, internal_err, options)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
# Execute the git command in streaming mode
|
|
128
|
+
#
|
|
129
|
+
# @param args [Array<String>] the git command arguments
|
|
130
|
+
#
|
|
131
|
+
# @param err_io [StringIO, #write] the internal stderr destination
|
|
132
|
+
#
|
|
133
|
+
# @param options_hash [Hash] the merged run options forwarded from {#run}
|
|
134
|
+
#
|
|
135
|
+
# Only the keys consumed by this method are listed below; `:err` and
|
|
136
|
+
# `:raise_on_failure` are present in the hash but not used here (`:err`
|
|
137
|
+
# is handled via the separate `err_io:` argument).
|
|
138
|
+
#
|
|
139
|
+
# @option options_hash [IO, nil] :in stdin IO object for the subprocess
|
|
140
|
+
#
|
|
141
|
+
# @option options_hash [#write, nil] :out stdout streaming destination
|
|
142
|
+
#
|
|
143
|
+
# @option options_hash [String, nil] :chdir working directory for the subprocess
|
|
144
|
+
#
|
|
145
|
+
# @option options_hash [Numeric, nil] :timeout execution timeout in seconds
|
|
146
|
+
#
|
|
147
|
+
# @option options_hash [Hash] :env ({}) environment variable overrides
|
|
148
|
+
#
|
|
149
|
+
# @return [ProcessExecuter::Result] the result of running the command (non-capturing)
|
|
150
|
+
#
|
|
151
|
+
# @api private
|
|
152
|
+
def execute(*args, err_io:, **options_hash)
|
|
153
|
+
git_cmd = build_git_cmd(args)
|
|
154
|
+
options = execute_options(err_io:, **options_hash)
|
|
155
|
+
run_process_executer do
|
|
156
|
+
ProcessExecuter.run(merged_env(options_hash), *git_cmd, **options)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Build the ProcessExecuter options hash for a streaming run
|
|
161
|
+
#
|
|
162
|
+
# @param err_io [StringIO, #write] the stderr destination (internal buffer or tee)
|
|
163
|
+
#
|
|
164
|
+
# @param options_hash [Hash] the merged run options forwarded from {#run}
|
|
165
|
+
#
|
|
166
|
+
# @option options_hash [IO, nil] :in stdin IO object for the subprocess
|
|
167
|
+
#
|
|
168
|
+
# @option options_hash [#write, nil] :out stdout streaming destination
|
|
169
|
+
#
|
|
170
|
+
# @option options_hash [String, nil] :chdir working directory for the subprocess
|
|
171
|
+
#
|
|
172
|
+
# @option options_hash [Numeric, nil] :timeout execution timeout in seconds
|
|
173
|
+
#
|
|
174
|
+
# @return [Hash]
|
|
175
|
+
#
|
|
176
|
+
# @api private
|
|
177
|
+
def execute_options(err_io:, **options_hash)
|
|
178
|
+
chdir = options_hash[:chdir] || :not_set
|
|
179
|
+
timeout_after = options_hash[:timeout]
|
|
180
|
+
|
|
181
|
+
{ chdir:, timeout_after:, raise_errors: false, err: err_io }.tap do |options|
|
|
182
|
+
options[:in] = options_hash[:in] unless options_hash[:in].nil?
|
|
183
|
+
options[:out] = options_hash[:out] unless options_hash[:out].nil?
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Build a tee writer that forwards #write calls to two destinations simultaneously.
|
|
188
|
+
#
|
|
189
|
+
# Used to capture stderr in an internal StringIO while also streaming to a
|
|
190
|
+
# caller-provided destination.
|
|
191
|
+
#
|
|
192
|
+
# @param primary [StringIO] the internal capture buffer
|
|
193
|
+
#
|
|
194
|
+
# @param secondary [#write] the caller-supplied destination
|
|
195
|
+
#
|
|
196
|
+
# @return [#write] an object whose #write method delegates to both destinations
|
|
197
|
+
#
|
|
198
|
+
# @api private
|
|
199
|
+
def build_stderr_tee(primary, secondary)
|
|
200
|
+
::Object.new.tap do |tee|
|
|
201
|
+
tee.define_singleton_method(:write) do |data|
|
|
202
|
+
primary.write(data)
|
|
203
|
+
secondary.write(data)
|
|
204
|
+
data.bytesize
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Process the result of a streaming command and return a Git::CommandLine::Result
|
|
210
|
+
#
|
|
211
|
+
# Constructs stdout as `''` (not captured) and stderr from the internal StringIO.
|
|
212
|
+
#
|
|
213
|
+
# @param result [ProcessExecuter::Result] the raw process result
|
|
214
|
+
#
|
|
215
|
+
# @param err_io [StringIO] the internal StringIO that captured stderr
|
|
216
|
+
#
|
|
217
|
+
# @param options [Hash] the merged run options forwarded from {#run}
|
|
218
|
+
#
|
|
219
|
+
# @option options [Numeric, nil] :timeout execution timeout used to construct the result
|
|
220
|
+
#
|
|
221
|
+
# @option options [Boolean] :raise_on_failure (true) raise {Git::FailedError} on non-zero exit
|
|
222
|
+
#
|
|
223
|
+
# @return [Git::CommandLine::Result]
|
|
224
|
+
#
|
|
225
|
+
# @api private
|
|
226
|
+
def process_result(result, err_io, options)
|
|
227
|
+
command = result.command
|
|
228
|
+
stderr = err_io.string
|
|
229
|
+
log_result(result, command, '', stderr)
|
|
230
|
+
command_line_result(
|
|
231
|
+
command, result, '', stderr, options[:timeout], options[:raise_on_failure]
|
|
232
|
+
)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Namespace module for git command-line execution strategies
|
|
5
|
+
#
|
|
6
|
+
# This module groups the classes responsible for invoking git subprocesses
|
|
7
|
+
# and handling their output. Choose a concrete class based on your buffering
|
|
8
|
+
# needs:
|
|
9
|
+
#
|
|
10
|
+
# * {Git::CommandLine::Capturing} — buffers stdout and stderr in memory.
|
|
11
|
+
# Use this for the vast majority of git commands whose output fits in memory.
|
|
12
|
+
#
|
|
13
|
+
# * {Git::CommandLine::Streaming} — streams stdout to a caller-supplied IO.
|
|
14
|
+
# Use this for commands (e.g. `cat-file -p <blob>`) whose output may be
|
|
15
|
+
# too large to buffer.
|
|
16
|
+
#
|
|
17
|
+
# Both classes inherit from {Git::CommandLine::Base} and are used internally
|
|
18
|
+
# by {Git::ExecutionContext#command_capturing} and
|
|
19
|
+
# {Git::ExecutionContext#command_streaming}.
|
|
20
|
+
#
|
|
21
|
+
# Results are returned as {Git::CommandLine::Result} objects (also accessible
|
|
22
|
+
# as {Git::CommandLine::Result} for backward compatibility).
|
|
23
|
+
#
|
|
24
|
+
# @example Buffered command via Git::CommandLine::Capturing
|
|
25
|
+
# cli = Git::CommandLine::Capturing.new(
|
|
26
|
+
# {}, '/usr/bin/git', [], Logger.new(nil)
|
|
27
|
+
# )
|
|
28
|
+
# result = cli.run('version')
|
|
29
|
+
# result.stdout #=> "git version 2.39.1\n"
|
|
30
|
+
#
|
|
31
|
+
# @example Streaming command via Git::CommandLine::Streaming
|
|
32
|
+
# cli = Git::CommandLine::Streaming.new(
|
|
33
|
+
# {}, '/usr/bin/git', [], Logger.new(nil)
|
|
34
|
+
# )
|
|
35
|
+
# File.open('/tmp/blob', 'wb') do |f|
|
|
36
|
+
# cli.run('cat-file', 'blob', sha, out: f)
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# @see Git::CommandLine::Base
|
|
40
|
+
#
|
|
41
|
+
# @see Git::CommandLine::Result
|
|
42
|
+
#
|
|
43
|
+
# @api private
|
|
44
|
+
#
|
|
45
|
+
module CommandLine
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
require 'git/command_line/result'
|
|
50
|
+
require 'git/command_line/base'
|
|
51
|
+
require 'git/command_line/capturing'
|
|
52
|
+
require 'git/command_line/streaming'
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/commands/base'
|
|
4
|
+
|
|
5
|
+
module Git
|
|
6
|
+
module Commands
|
|
7
|
+
# Implements the `git add` command
|
|
8
|
+
#
|
|
9
|
+
# This command updates the index using the current content found in the working tree,
|
|
10
|
+
# to prepare the content staged for the next commit.
|
|
11
|
+
#
|
|
12
|
+
# @example Basic usage
|
|
13
|
+
# add = Git::Commands::Add.new(execution_context)
|
|
14
|
+
# add.call('path/to/file')
|
|
15
|
+
# add.call('file1.rb', 'file2.rb')
|
|
16
|
+
# add.call(all: true)
|
|
17
|
+
#
|
|
18
|
+
# @note `arguments` block audited against https://git-scm.com/docs/git-add/2.53.0
|
|
19
|
+
#
|
|
20
|
+
# @see https://git-scm.com/docs/git-add git-add
|
|
21
|
+
#
|
|
22
|
+
# @see Git::Commands
|
|
23
|
+
#
|
|
24
|
+
# @api private
|
|
25
|
+
#
|
|
26
|
+
class Add < Git::Commands::Base
|
|
27
|
+
arguments do
|
|
28
|
+
literal 'add'
|
|
29
|
+
flag_option %i[verbose v]
|
|
30
|
+
flag_option %i[dry_run n]
|
|
31
|
+
flag_option %i[force f]
|
|
32
|
+
flag_option %i[all A], negatable: true
|
|
33
|
+
flag_option :ignore_removal, negatable: true
|
|
34
|
+
flag_option %i[update u]
|
|
35
|
+
flag_option :sparse
|
|
36
|
+
flag_option %i[intent_to_add N]
|
|
37
|
+
flag_option :refresh
|
|
38
|
+
flag_option :ignore_errors
|
|
39
|
+
flag_option :ignore_missing
|
|
40
|
+
flag_option :renormalize
|
|
41
|
+
flag_option :no_warn_embedded_repo
|
|
42
|
+
value_option :chmod, inline: true
|
|
43
|
+
value_option :pathspec_from_file, inline: true
|
|
44
|
+
flag_option :pathspec_file_nul
|
|
45
|
+
end_of_options
|
|
46
|
+
operand :pathspec, repeatable: true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @overload call(*pathspec, **options)
|
|
50
|
+
#
|
|
51
|
+
# Execute the `git add` command
|
|
52
|
+
#
|
|
53
|
+
# @param pathspec [Array<String>] files to be added to the repository
|
|
54
|
+
# (relative to the worktree root)
|
|
55
|
+
#
|
|
56
|
+
# @param options [Hash] command options
|
|
57
|
+
#
|
|
58
|
+
# @option options [Boolean, nil] :verbose (nil) be verbose
|
|
59
|
+
#
|
|
60
|
+
# Alias: :v
|
|
61
|
+
#
|
|
62
|
+
# @option options [Boolean, nil] :dry_run (nil) don't actually add files;
|
|
63
|
+
# show what would be added
|
|
64
|
+
#
|
|
65
|
+
# Alias: :n
|
|
66
|
+
#
|
|
67
|
+
# @option options [Boolean, nil] :force (nil) allow adding otherwise ignored
|
|
68
|
+
# files
|
|
69
|
+
#
|
|
70
|
+
# Alias: :f
|
|
71
|
+
#
|
|
72
|
+
# @option options [Boolean, nil] :all (nil) add, modify, and remove index
|
|
73
|
+
# entries to match the worktree (--all)
|
|
74
|
+
#
|
|
75
|
+
# Alias: :A
|
|
76
|
+
#
|
|
77
|
+
# @option options [Boolean, nil] :no_all (nil) add and modify index entries
|
|
78
|
+
# without staging removals (--no-all)
|
|
79
|
+
#
|
|
80
|
+
# @option options [Boolean, nil] :ignore_removal (nil) add and modify files;
|
|
81
|
+
# ignore removals (--ignore-removal)
|
|
82
|
+
#
|
|
83
|
+
# @option options [Boolean, nil] :no_ignore_removal (nil) include file removals
|
|
84
|
+
# (--no-ignore-removal)
|
|
85
|
+
#
|
|
86
|
+
# @option options [Boolean, nil] :update (nil) update tracked files only; does
|
|
87
|
+
# not add new files
|
|
88
|
+
#
|
|
89
|
+
# Alias: :u
|
|
90
|
+
#
|
|
91
|
+
# @option options [Boolean, nil] :sparse (nil) allow updating index entries
|
|
92
|
+
# outside the sparse-checkout cone
|
|
93
|
+
#
|
|
94
|
+
# @option options [Boolean, nil] :intent_to_add (nil) record that the path
|
|
95
|
+
# will be added later, placing an empty entry in the index
|
|
96
|
+
#
|
|
97
|
+
# Alias: :N
|
|
98
|
+
#
|
|
99
|
+
# @option options [Boolean, nil] :refresh (nil) refresh stat() information in
|
|
100
|
+
# the index without adding files
|
|
101
|
+
#
|
|
102
|
+
# @option options [Boolean, nil] :ignore_errors (nil) continue adding other
|
|
103
|
+
# files if some files cannot be added due to indexing errors
|
|
104
|
+
#
|
|
105
|
+
# @option options [Boolean, nil] :ignore_missing (nil) check whether any given
|
|
106
|
+
# files would be ignored
|
|
107
|
+
#
|
|
108
|
+
# @option options [Boolean, nil] :renormalize (nil) apply the "clean" process
|
|
109
|
+
# freshly to all tracked files to forcibly re-add them with correct line
|
|
110
|
+
# endings
|
|
111
|
+
#
|
|
112
|
+
# @option options [Boolean, nil] :no_warn_embedded_repo (nil) suppress warning
|
|
113
|
+
# when adding an embedded repository without using `git submodule add`
|
|
114
|
+
#
|
|
115
|
+
# @option options [String] :chmod (nil) override the executable bit of added
|
|
116
|
+
# files in the index
|
|
117
|
+
#
|
|
118
|
+
# Value must be `'+x'` or `'-x'`
|
|
119
|
+
#
|
|
120
|
+
# @option options [String] :pathspec_from_file (nil) read pathspec from the
|
|
121
|
+
# given file (use `'-'` for stdin)
|
|
122
|
+
#
|
|
123
|
+
# @option options [Boolean, nil] :pathspec_file_nul (nil) separate pathspec
|
|
124
|
+
# elements with NUL when reading from a file
|
|
125
|
+
#
|
|
126
|
+
# @return [Git::CommandLine::Result] the result of calling `git add`
|
|
127
|
+
#
|
|
128
|
+
# @raise [ArgumentError] if unsupported options are provided
|
|
129
|
+
#
|
|
130
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
131
|
+
#
|
|
132
|
+
# @api public
|
|
133
|
+
#
|
|
134
|
+
def call(*, **)
|
|
135
|
+
super
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/commands/base'
|
|
4
|
+
|
|
5
|
+
module Git
|
|
6
|
+
module Commands
|
|
7
|
+
module Am
|
|
8
|
+
# Implements `git am --abort` to abort an in-progress am session
|
|
9
|
+
#
|
|
10
|
+
# Aborts the in-progress patch application and restores the branch to
|
|
11
|
+
# the state it was in before the `git am` session started.
|
|
12
|
+
#
|
|
13
|
+
# @example Abort an am session
|
|
14
|
+
# abort_cmd = Git::Commands::Am::Abort.new(execution_context)
|
|
15
|
+
# abort_cmd.call
|
|
16
|
+
#
|
|
17
|
+
# @note `arguments` block audited against https://git-scm.com/docs/git-am/2.53.0
|
|
18
|
+
#
|
|
19
|
+
# @see Git::Commands::Am
|
|
20
|
+
#
|
|
21
|
+
# @see https://git-scm.com/docs/git-am git-am
|
|
22
|
+
#
|
|
23
|
+
# @api private
|
|
24
|
+
#
|
|
25
|
+
class Abort < Git::Commands::Base
|
|
26
|
+
arguments do
|
|
27
|
+
literal 'am'
|
|
28
|
+
literal '--abort'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @!method call()
|
|
32
|
+
#
|
|
33
|
+
# @overload call()
|
|
34
|
+
#
|
|
35
|
+
# Abort the in-progress am session and restore the branch
|
|
36
|
+
#
|
|
37
|
+
# @return [Git::CommandLine::Result] the result of calling `git am --abort`
|
|
38
|
+
#
|
|
39
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|