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,252 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/commands/describe'
|
|
4
|
+
require 'git/commands/fsck'
|
|
5
|
+
require 'git/commands/show'
|
|
6
|
+
require 'git/parsers/fsck'
|
|
7
|
+
require 'git/repository/shared_private'
|
|
8
|
+
|
|
9
|
+
module Git
|
|
10
|
+
class Repository
|
|
11
|
+
# Facade methods for read-only repository inspection operations
|
|
12
|
+
#
|
|
13
|
+
# These methods report on the contents and integrity of the repository.
|
|
14
|
+
#
|
|
15
|
+
# Included by {Git::Repository}.
|
|
16
|
+
#
|
|
17
|
+
# @api private
|
|
18
|
+
#
|
|
19
|
+
module Inspecting
|
|
20
|
+
# Give a human-readable name to a commit based on the most recent reachable tag
|
|
21
|
+
#
|
|
22
|
+
# Runs `git describe` to find the nearest tag reachable from `committish` and
|
|
23
|
+
# formats a version string. When the tag points directly at the commit, only the
|
|
24
|
+
# tag name is shown. Otherwise, the tag name is suffixed with the number of
|
|
25
|
+
# additional commits and the abbreviated commit SHA (e.g. `v1.0.0-3-gabcdef1`).
|
|
26
|
+
#
|
|
27
|
+
# @example Describe HEAD
|
|
28
|
+
# repo.describe #=> "v1.0.0"
|
|
29
|
+
#
|
|
30
|
+
# @example Describe a specific commit
|
|
31
|
+
# repo.describe('abc123') #=> "v1.0.0-3-gabcdef1"
|
|
32
|
+
#
|
|
33
|
+
# @example Describe using any tag (not just annotated tags)
|
|
34
|
+
# repo.describe(nil, tags: true) #=> "v1.0.0-lightweight"
|
|
35
|
+
#
|
|
36
|
+
# @example Require an exact tag match
|
|
37
|
+
# repo.describe(nil, exact_match: true)
|
|
38
|
+
#
|
|
39
|
+
# @example Use the legacy hyphenated key (still accepted)
|
|
40
|
+
# repo.describe(nil, :'exact-match' => true)
|
|
41
|
+
#
|
|
42
|
+
# @param committish [String, nil] the commit-ish to describe; defaults to HEAD
|
|
43
|
+
# when `nil`
|
|
44
|
+
#
|
|
45
|
+
# @param opts [Hash] options forwarded to `git describe`
|
|
46
|
+
#
|
|
47
|
+
# @option opts [Boolean, nil] :all (nil) use any ref in `refs/`, not just tags
|
|
48
|
+
#
|
|
49
|
+
# @option opts [Boolean, nil] :tags (nil) use lightweight tags as well as
|
|
50
|
+
# annotated ones
|
|
51
|
+
#
|
|
52
|
+
# @option opts [Boolean, nil] :contains (nil) describe the tag that contains the
|
|
53
|
+
# commit, rather than the nearest reachable one
|
|
54
|
+
#
|
|
55
|
+
# @option opts [Boolean, String, nil] :abbrev (nil) number of hex digits for the
|
|
56
|
+
# abbreviated object name; `true` uses git's default length
|
|
57
|
+
#
|
|
58
|
+
# @option opts [Boolean, String, nil] :dirty (nil) append a dirty-state mark to
|
|
59
|
+
# the description; `true` appends `-dirty`, a String appends that string
|
|
60
|
+
#
|
|
61
|
+
# @option opts [Boolean, String, nil] :broken (nil) like `:dirty` but treats
|
|
62
|
+
# broken repository links as dirty
|
|
63
|
+
#
|
|
64
|
+
# @option opts [Integer, String, nil] :candidates (nil) number of candidate tags
|
|
65
|
+
# to consider; increasing above 10 may yield a more accurate result
|
|
66
|
+
#
|
|
67
|
+
# @option opts [Boolean, nil] :exact_match (nil) only succeed when the commit is
|
|
68
|
+
# pointed to by a tag directly (no suffix)
|
|
69
|
+
#
|
|
70
|
+
# The legacy hyphenated key `:"exact-match"` is also accepted and is
|
|
71
|
+
# automatically translated to `:exact_match`.
|
|
72
|
+
#
|
|
73
|
+
# @option opts [Boolean, nil] :debug (nil) verbosely display the search strategy
|
|
74
|
+
#
|
|
75
|
+
# @option opts [Boolean, nil] :long (nil) always output the long format even when
|
|
76
|
+
# the commit matches a tag exactly
|
|
77
|
+
#
|
|
78
|
+
# @option opts [String, Array<String>, nil] :match (nil) only consider tags
|
|
79
|
+
# matching the given `glob(7)` pattern; pass an array for multiple patterns
|
|
80
|
+
#
|
|
81
|
+
# @option opts [String, Array<String>, nil] :exclude (nil) do not consider tags
|
|
82
|
+
# matching the given `glob(7)` pattern; pass an array for multiple patterns
|
|
83
|
+
#
|
|
84
|
+
# @option opts [Boolean, nil] :always (nil) show the abbreviated commit SHA as
|
|
85
|
+
# fallback when the commit cannot be described
|
|
86
|
+
#
|
|
87
|
+
# @option opts [Boolean, nil] :first_parent (nil) follow only the first parent of
|
|
88
|
+
# merge commits when searching for the nearest tag
|
|
89
|
+
#
|
|
90
|
+
# @return [String] the human-readable description of the commit, with trailing
|
|
91
|
+
# newlines preserved
|
|
92
|
+
#
|
|
93
|
+
# @raise [Git::FailedError] when git exits with a non-zero exit status
|
|
94
|
+
#
|
|
95
|
+
# @raise [ArgumentError] when `committish` looks like a command-line flag (starts
|
|
96
|
+
# with `-`), or when `opts` contains any key not in the documented option list
|
|
97
|
+
#
|
|
98
|
+
def describe(committish = nil, opts = {})
|
|
99
|
+
raise ArgumentError, "Invalid commit-ish object: '#{committish}'" if committish&.start_with?('-')
|
|
100
|
+
|
|
101
|
+
opts = opts.dup
|
|
102
|
+
if opts.key?(:'exact-match')
|
|
103
|
+
opts[:exact_match] ||= opts[:'exact-match']
|
|
104
|
+
opts.delete(:'exact-match')
|
|
105
|
+
end
|
|
106
|
+
SharedPrivate.assert_valid_opts!(DESCRIBE_ALLOWED_OPTS, **opts)
|
|
107
|
+
commit_ishes = Array(committish).compact
|
|
108
|
+
Git::Commands::Describe.new(@execution_context).call(*commit_ishes, **opts).stdout
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Show a single git object (a commit, tag, tree, or blob)
|
|
112
|
+
#
|
|
113
|
+
# @example Show the HEAD commit
|
|
114
|
+
# repo.show
|
|
115
|
+
#
|
|
116
|
+
# @example Show a specific commit
|
|
117
|
+
# repo.show('HEAD~1')
|
|
118
|
+
#
|
|
119
|
+
# @example Show the contents of a file at a revision
|
|
120
|
+
# repo.show('HEAD', 'README.md')
|
|
121
|
+
#
|
|
122
|
+
# @param objectish [String, nil] the object to show; a ref, SHA, or
|
|
123
|
+
# `objectish:path` expression
|
|
124
|
+
#
|
|
125
|
+
# Defaults to `HEAD` when `nil`.
|
|
126
|
+
#
|
|
127
|
+
# @param path [String, nil] the file whose contents to show at `objectish`,
|
|
128
|
+
# when given
|
|
129
|
+
#
|
|
130
|
+
# Combined with `objectish` as `objectish:path`. When `objectish` is `nil`
|
|
131
|
+
# and `path` is given, `HEAD` is used as the objectish, so
|
|
132
|
+
# `show(nil, 'README.md')` resolves to `HEAD:README.md`.
|
|
133
|
+
#
|
|
134
|
+
# @return [String] git's stdout from the show, with trailing newlines
|
|
135
|
+
# preserved
|
|
136
|
+
#
|
|
137
|
+
# @raise [Git::FailedError] when git exits with a non-zero exit status
|
|
138
|
+
#
|
|
139
|
+
def show(objectish = nil, path = nil)
|
|
140
|
+
object = path ? "#{objectish || 'HEAD'}:#{path}" : objectish
|
|
141
|
+
Git::Commands::Show.new(@execution_context).call(*[object].compact).stdout
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Option keys accepted by {#describe}
|
|
145
|
+
DESCRIBE_ALLOWED_OPTS = %i[
|
|
146
|
+
all tags contains abbrev dirty broken candidates
|
|
147
|
+
exact_match debug long match exclude always first_parent
|
|
148
|
+
].freeze
|
|
149
|
+
private_constant :DESCRIBE_ALLOWED_OPTS
|
|
150
|
+
|
|
151
|
+
# Option keys accepted by {#fsck}
|
|
152
|
+
#
|
|
153
|
+
# `:progress`/`:no_progress` are intentionally excluded: progress output is
|
|
154
|
+
# always suppressed (see {#fsck}), so callers may not toggle it.
|
|
155
|
+
FSCK_ALLOWED_OPTS = %i[
|
|
156
|
+
tags root unreachable cache no_reflogs
|
|
157
|
+
full no_full strict verbose lost_found dangling no_dangling
|
|
158
|
+
connectivity_only name_objects no_name_objects references no_references
|
|
159
|
+
].freeze
|
|
160
|
+
private_constant :FSCK_ALLOWED_OPTS
|
|
161
|
+
|
|
162
|
+
# Verify the connectivity and validity of the objects in the database
|
|
163
|
+
#
|
|
164
|
+
# Runs `git fsck` and returns the categorized objects it flags. Progress
|
|
165
|
+
# output is always suppressed (`--no-progress`) so that stdout contains only
|
|
166
|
+
# the machine-parsable findings.
|
|
167
|
+
#
|
|
168
|
+
# @overload fsck(*objects, **options)
|
|
169
|
+
#
|
|
170
|
+
# @example Check repository integrity
|
|
171
|
+
# result = repo.fsck
|
|
172
|
+
# result.dangling.each { |obj| puts "#{obj.type}: #{obj.oid}" }
|
|
173
|
+
#
|
|
174
|
+
# @example Check if the repository is clean
|
|
175
|
+
# repo.fsck.empty? #=> true
|
|
176
|
+
#
|
|
177
|
+
# @example List root commits
|
|
178
|
+
# repo.fsck(root: true).root.each { |obj| puts obj.oid }
|
|
179
|
+
#
|
|
180
|
+
# @example Check specific objects
|
|
181
|
+
# repo.fsck('abc1234', 'def5678')
|
|
182
|
+
#
|
|
183
|
+
# @param objects [Array<String>] specific objects to treat as heads for the
|
|
184
|
+
# unreachability trace
|
|
185
|
+
#
|
|
186
|
+
# When none are given, git fsck defaults to the index file, all refs, and
|
|
187
|
+
# all reflogs.
|
|
188
|
+
#
|
|
189
|
+
# @param options [Hash] options for the fsck command
|
|
190
|
+
#
|
|
191
|
+
# @option options [Boolean, nil] :tags (nil) report tags
|
|
192
|
+
#
|
|
193
|
+
# @option options [Boolean, nil] :root (nil) report root nodes
|
|
194
|
+
#
|
|
195
|
+
# @option options [Boolean, nil] :unreachable (nil) print objects that exist
|
|
196
|
+
# but are not reachable from any reference node
|
|
197
|
+
#
|
|
198
|
+
# @option options [Boolean, nil] :cache (nil) consider objects recorded in the
|
|
199
|
+
# index as head nodes for reachability
|
|
200
|
+
#
|
|
201
|
+
# @option options [Boolean, nil] :no_reflogs (nil) do not consider commits
|
|
202
|
+
# referenced only by reflogs to be reachable
|
|
203
|
+
#
|
|
204
|
+
# @option options [Boolean, nil] :full (nil) also check alternate object
|
|
205
|
+
# pools and packed archives, not just the local store
|
|
206
|
+
#
|
|
207
|
+
# @option options [Boolean, nil] :no_full (nil) skip alternate object pools and
|
|
208
|
+
# packed archives
|
|
209
|
+
#
|
|
210
|
+
# @option options [Boolean, nil] :strict (nil) enable stricter checking
|
|
211
|
+
#
|
|
212
|
+
# @option options [Boolean, nil] :verbose (nil) be chatty
|
|
213
|
+
#
|
|
214
|
+
# @option options [Boolean, nil] :lost_found (nil) write dangling objects
|
|
215
|
+
# into `.git/lost-found`
|
|
216
|
+
#
|
|
217
|
+
# This modifies the repository by creating files.
|
|
218
|
+
#
|
|
219
|
+
# @option options [Boolean, nil] :dangling (nil) print dangling objects
|
|
220
|
+
#
|
|
221
|
+
# @option options [Boolean, nil] :no_dangling (nil) suppress dangling object
|
|
222
|
+
# reporting
|
|
223
|
+
#
|
|
224
|
+
# @option options [Boolean, nil] :connectivity_only (nil) check only
|
|
225
|
+
# connectivity; faster but does not validate blob content
|
|
226
|
+
#
|
|
227
|
+
# @option options [Boolean, nil] :name_objects (nil) show the name of each
|
|
228
|
+
# reachable object alongside its identifier
|
|
229
|
+
#
|
|
230
|
+
# @option options [Boolean, nil] :no_name_objects (nil) suppress object name
|
|
231
|
+
# display
|
|
232
|
+
#
|
|
233
|
+
# @option options [Boolean, nil] :references (nil) check reference database
|
|
234
|
+
# consistency
|
|
235
|
+
#
|
|
236
|
+
# @option options [Boolean, nil] :no_references (nil) skip reference checking
|
|
237
|
+
#
|
|
238
|
+
# @return [Git::FsckResult] the objects flagged by fsck, categorized by status
|
|
239
|
+
#
|
|
240
|
+
# @raise [ArgumentError] when unsupported options are provided
|
|
241
|
+
#
|
|
242
|
+
# @raise [Git::FailedError] when git exits outside the allowed range (exit
|
|
243
|
+
# code > 7)
|
|
244
|
+
#
|
|
245
|
+
def fsck(*objects, **)
|
|
246
|
+
SharedPrivate.assert_valid_opts!(FSCK_ALLOWED_OPTS, **)
|
|
247
|
+
result = Git::Commands::Fsck.new(@execution_context).call(*objects, **, no_progress: true)
|
|
248
|
+
Git::Parsers::Fsck.parse(result.stdout)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/commands/log'
|
|
4
|
+
require 'git/log'
|
|
5
|
+
require 'git/repository/shared_private'
|
|
6
|
+
|
|
7
|
+
module Git
|
|
8
|
+
class Repository
|
|
9
|
+
# Facade methods for querying commit history
|
|
10
|
+
#
|
|
11
|
+
# Included by {Git::Repository}.
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
14
|
+
#
|
|
15
|
+
module Logging
|
|
16
|
+
# Allowed option keys for {#full_log_commits}
|
|
17
|
+
#
|
|
18
|
+
# @return [Array<Symbol>] the supported option keys
|
|
19
|
+
#
|
|
20
|
+
FULL_LOG_COMMITS_ALLOWED_OPTS = %i[
|
|
21
|
+
count all cherry since until grep author between object path_limiter skip merges perl_regexp
|
|
22
|
+
].freeze
|
|
23
|
+
private_constant :FULL_LOG_COMMITS_ALLOWED_OPTS
|
|
24
|
+
|
|
25
|
+
# Returns commits within the given revision range
|
|
26
|
+
#
|
|
27
|
+
# @example Return commits from all refs
|
|
28
|
+
# repo.full_log_commits(all: true).first['sha']
|
|
29
|
+
# #=> "a1b2c3d4..."
|
|
30
|
+
#
|
|
31
|
+
# @example Return commits between two revisions
|
|
32
|
+
# repo.full_log_commits(between: ['v1.0.0', 'HEAD']).map { |c| c['sha'] }
|
|
33
|
+
# #=> ["d4e5f6...", "a1b2c3..."]
|
|
34
|
+
#
|
|
35
|
+
# @param opts [Hash] options for the log query
|
|
36
|
+
#
|
|
37
|
+
# @option opts [Integer, nil] :count (nil) maximum number of commits to return
|
|
38
|
+
#
|
|
39
|
+
# @option opts [Boolean, nil] :all (nil) include commits reachable from any ref
|
|
40
|
+
#
|
|
41
|
+
# @option opts [Boolean, nil] :cherry (nil) omit commits equivalent to
|
|
42
|
+
# cherry-picked commits
|
|
43
|
+
#
|
|
44
|
+
# @option opts [String] :since (nil) include commits newer than this date expression
|
|
45
|
+
#
|
|
46
|
+
# @option opts [String] :until (nil) include commits older than this date expression
|
|
47
|
+
#
|
|
48
|
+
# @option opts [String] :grep (nil) only include commits whose message matches
|
|
49
|
+
# this pattern
|
|
50
|
+
#
|
|
51
|
+
# @option opts [String] :author (nil) only include commits whose author matches
|
|
52
|
+
# this pattern
|
|
53
|
+
#
|
|
54
|
+
# @option opts [Array(String, String), nil] :between (nil) revision range as
|
|
55
|
+
# two commit-ish values
|
|
56
|
+
#
|
|
57
|
+
# When both `:between` and `:object` are provided, `:between` takes precedence.
|
|
58
|
+
#
|
|
59
|
+
# @option opts [String] :object (nil) single revision range expression for
|
|
60
|
+
# `git log`
|
|
61
|
+
#
|
|
62
|
+
# Ignored when `:between` is provided.
|
|
63
|
+
#
|
|
64
|
+
# @option opts [String, Pathname, Array<String, Pathname>, nil] :path_limiter (nil)
|
|
65
|
+
# only include commits that impact files from the specified path(s)
|
|
66
|
+
#
|
|
67
|
+
# @option opts [Integer, nil] :skip (nil) skip this many commits before output
|
|
68
|
+
#
|
|
69
|
+
# @option opts [Boolean, nil] :merges (nil) include only merge commits
|
|
70
|
+
#
|
|
71
|
+
# @option opts [Boolean, nil] :perl_regexp (nil) interpret the `:grep` and
|
|
72
|
+
# `:author` patterns as Perl-compatible regular expressions (PCRE) instead of
|
|
73
|
+
# git's default POSIX basic regular expressions
|
|
74
|
+
#
|
|
75
|
+
# Requires a git built with PCRE support; git otherwise fails with
|
|
76
|
+
# "cannot use Perl-compatible regexes...".
|
|
77
|
+
#
|
|
78
|
+
# @return [Array<Hash>] the parsed raw log output for each commit
|
|
79
|
+
#
|
|
80
|
+
# @raise [ArgumentError] if unsupported options are provided
|
|
81
|
+
#
|
|
82
|
+
# @raise [ArgumentError] if `:count` is not an Integer
|
|
83
|
+
#
|
|
84
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
85
|
+
#
|
|
86
|
+
# @note On Git for Windows, git's default regex engine matches *bytes* rather
|
|
87
|
+
# than characters, so a metacharacter such as `.` or a POSIX class such as
|
|
88
|
+
# `[[:alpha:]]` never matches a whole multi-byte character in a `:grep` or
|
|
89
|
+
# `:author` pattern. The match fails silently: git exits zero and the result
|
|
90
|
+
# is empty. Pass `perl_regexp: true` to select PCRE, which does match
|
|
91
|
+
# characters. PCRE is a different dialect than git's default, so this is a
|
|
92
|
+
# deliberate choice by the caller rather than a transparent substitution.
|
|
93
|
+
#
|
|
94
|
+
# @see https://git-scm.com/docs/git-log git-log
|
|
95
|
+
#
|
|
96
|
+
def full_log_commits(opts = {})
|
|
97
|
+
SharedPrivate.assert_valid_opts!(FULL_LOG_COMMITS_ALLOWED_OPTS, **opts)
|
|
98
|
+
Private.validate_log_count_option!(opts)
|
|
99
|
+
Private.validate_log_between_option!(opts)
|
|
100
|
+
|
|
101
|
+
call_opts = Private.log_base_call_options(opts, skip: opts[:skip], merges: opts[:merges])
|
|
102
|
+
revision_range_args = Private.log_revision_range_args(opts)
|
|
103
|
+
Private.run_log_command(@execution_context, revision_range_args, call_opts)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Returns a new {Git::Log} query builder scoped to this repository
|
|
107
|
+
#
|
|
108
|
+
# @example Build a log query and execute it
|
|
109
|
+
# results = repo.log(50).author('Alice').since('2 weeks ago').execute
|
|
110
|
+
# results.each { |commit| puts commit.sha }
|
|
111
|
+
#
|
|
112
|
+
# @param count [Integer, Symbol, nil] the maximum number of commits to return,
|
|
113
|
+
# or `:all` / `nil` to return all commits; passed directly to {Git::Log#initialize}
|
|
114
|
+
#
|
|
115
|
+
# @return [Git::Log] a new log query builder
|
|
116
|
+
#
|
|
117
|
+
# @see Git::Log
|
|
118
|
+
#
|
|
119
|
+
def log(count = 30)
|
|
120
|
+
Git::Log.new(self, count)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Internal helpers for {Logging} that should not be mixed into
|
|
124
|
+
# {Git::Repository} instances
|
|
125
|
+
#
|
|
126
|
+
# @api private
|
|
127
|
+
#
|
|
128
|
+
module Private
|
|
129
|
+
module_function
|
|
130
|
+
|
|
131
|
+
# Log option keys forwarded to {Git::Commands::Log#call} under the same name
|
|
132
|
+
#
|
|
133
|
+
# The remaining options are renamed or reshaped by {#log_base_call_options}.
|
|
134
|
+
#
|
|
135
|
+
# @return [Array<Symbol>] the pass-through option keys
|
|
136
|
+
#
|
|
137
|
+
PASSTHROUGH_LOG_OPTS = %i[all cherry since until grep author perl_regexp].freeze
|
|
138
|
+
|
|
139
|
+
# Validates the :count log option
|
|
140
|
+
#
|
|
141
|
+
# @param opts [Hash] the log options
|
|
142
|
+
#
|
|
143
|
+
# @option opts [Integer, nil] :count (nil) the maximum number of commits to
|
|
144
|
+
# return
|
|
145
|
+
#
|
|
146
|
+
# @return [void]
|
|
147
|
+
#
|
|
148
|
+
# @raise [ArgumentError] if the log count option is not an Integer
|
|
149
|
+
#
|
|
150
|
+
def validate_log_count_option!(opts)
|
|
151
|
+
return if opts[:count].nil? || opts[:count].is_a?(Integer)
|
|
152
|
+
|
|
153
|
+
raise ArgumentError, "The log count option must be an Integer but was #{opts[:count].inspect}"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Validates the :between log option
|
|
157
|
+
#
|
|
158
|
+
# @param opts [Hash] the log options
|
|
159
|
+
#
|
|
160
|
+
# @option opts [Array(String, String), nil] :between (nil) the two-commit
|
|
161
|
+
# revision range to validate
|
|
162
|
+
#
|
|
163
|
+
# @return [void]
|
|
164
|
+
#
|
|
165
|
+
# @raise [ArgumentError] if the :between option is not an Array with exactly
|
|
166
|
+
# two non-nil values
|
|
167
|
+
#
|
|
168
|
+
def validate_log_between_option!(opts)
|
|
169
|
+
between = opts[:between]
|
|
170
|
+
return if between.nil?
|
|
171
|
+
return if between.is_a?(Array) && between.length == 2 && between.none?(&:nil?)
|
|
172
|
+
|
|
173
|
+
raise ArgumentError,
|
|
174
|
+
"The log between option must be an Array with exactly two non-nil values but was #{between.inspect}"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Builds positional revision arguments for `git log`
|
|
178
|
+
#
|
|
179
|
+
# @param opts [Hash] the log options
|
|
180
|
+
#
|
|
181
|
+
# @option opts [Array(String, String), nil] :between (nil) a two-revision
|
|
182
|
+
# range where index `0` is the start and index `1` is the end
|
|
183
|
+
#
|
|
184
|
+
# @option opts [String, nil] :object (nil) a single revision range expression
|
|
185
|
+
#
|
|
186
|
+
# @return [Array<String>] zero or one positional revision arguments
|
|
187
|
+
#
|
|
188
|
+
def log_revision_range_args(opts)
|
|
189
|
+
if opts[:between]
|
|
190
|
+
["#{opts[:between][0]}..#{opts[:between][1]}"]
|
|
191
|
+
elsif opts[:object].is_a?(String)
|
|
192
|
+
[opts[:object]]
|
|
193
|
+
else
|
|
194
|
+
[]
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Builds keyword options passed to {Git::Commands::Log#call}
|
|
199
|
+
#
|
|
200
|
+
# @param opts [Hash] the log options
|
|
201
|
+
#
|
|
202
|
+
# @param extra [Hash] additional keyword options merged into the call options
|
|
203
|
+
#
|
|
204
|
+
# @option opts [Boolean, nil] :all (nil) include commits reachable from any ref
|
|
205
|
+
#
|
|
206
|
+
# @option opts [Boolean, nil] :cherry (nil) omit commits equivalent to
|
|
207
|
+
# cherry-picked commits
|
|
208
|
+
#
|
|
209
|
+
# @option opts [String, nil] :since (nil) include commits newer than this date
|
|
210
|
+
# expression
|
|
211
|
+
#
|
|
212
|
+
# @option opts [String, nil] :until (nil) include commits older than this date
|
|
213
|
+
# expression
|
|
214
|
+
#
|
|
215
|
+
# @option opts [String, nil] :grep (nil) only include commits whose message
|
|
216
|
+
# matches this pattern
|
|
217
|
+
#
|
|
218
|
+
# @option opts [String, nil] :author (nil) only include commits whose author
|
|
219
|
+
# matches this pattern
|
|
220
|
+
#
|
|
221
|
+
# @option opts [Boolean, nil] :perl_regexp (nil) interpret the `:grep` and
|
|
222
|
+
# `:author` patterns as Perl-compatible regular expressions
|
|
223
|
+
#
|
|
224
|
+
# @option opts [Integer, nil] :count (nil) maximum number of commits to return
|
|
225
|
+
#
|
|
226
|
+
# @option opts [String, Pathname, Array<String, Pathname>, nil] :path_limiter (nil)
|
|
227
|
+
# only include commits that impact files from the specified path(s)
|
|
228
|
+
#
|
|
229
|
+
# @option extra [Integer, nil] :skip (nil) skip this many commits before output
|
|
230
|
+
#
|
|
231
|
+
# @option extra [Boolean, nil] :merges (nil) include only merge commits
|
|
232
|
+
#
|
|
233
|
+
# @return [Hash] keyword options for {Git::Commands::Log#call}
|
|
234
|
+
#
|
|
235
|
+
def log_base_call_options(opts, extra = {})
|
|
236
|
+
opts
|
|
237
|
+
.slice(*PASSTHROUGH_LOG_OPTS)
|
|
238
|
+
.merge(
|
|
239
|
+
max_count: opts[:count],
|
|
240
|
+
path: opts[:path_limiter] ? Array(opts[:path_limiter]) : nil
|
|
241
|
+
)
|
|
242
|
+
.merge(extra)
|
|
243
|
+
.compact
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Executes git log and parses the raw output
|
|
247
|
+
#
|
|
248
|
+
# @param execution_context [Git::ExecutionContext] the execution context
|
|
249
|
+
#
|
|
250
|
+
# @param revision_range_args [Array<String>] positional revision range arguments
|
|
251
|
+
#
|
|
252
|
+
# @param call_opts [Hash] keyword options for {Git::Commands::Log#call}
|
|
253
|
+
#
|
|
254
|
+
# @return [Array<Hash>] parsed commits from the command output
|
|
255
|
+
#
|
|
256
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
257
|
+
#
|
|
258
|
+
def run_log_command(execution_context, revision_range_args, call_opts)
|
|
259
|
+
log_or_empty_on_unborn do
|
|
260
|
+
result = Git::Commands::Log.new(execution_context).call(
|
|
261
|
+
*revision_range_args,
|
|
262
|
+
no_color: true,
|
|
263
|
+
pretty: 'raw',
|
|
264
|
+
**call_opts
|
|
265
|
+
)
|
|
266
|
+
RawLogParser.new(result.stdout.split("\n")).parse
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Returns an empty result when the repository has no commits yet
|
|
271
|
+
#
|
|
272
|
+
# @return [Array<Hash>] parsed commits or an empty array for unborn repositories
|
|
273
|
+
#
|
|
274
|
+
# @raise [Git::FailedError] if git fails for a reason other than unborn history
|
|
275
|
+
#
|
|
276
|
+
# @yield [] runs the wrapped log command
|
|
277
|
+
#
|
|
278
|
+
# @yieldreturn [Array<Hash>] the parsed commits from the wrapped command
|
|
279
|
+
#
|
|
280
|
+
def log_or_empty_on_unborn
|
|
281
|
+
yield
|
|
282
|
+
rescue Git::FailedError => e
|
|
283
|
+
raise unless e.result.status.exitstatus == 128 &&
|
|
284
|
+
e.result.stderr =~ /does not have any commits yet/
|
|
285
|
+
|
|
286
|
+
[]
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Parser for `git log --pretty=raw` output into commit hashes
|
|
290
|
+
#
|
|
291
|
+
# @api private
|
|
292
|
+
#
|
|
293
|
+
class RawLogParser
|
|
294
|
+
# Initializes a parser for raw git log output lines
|
|
295
|
+
#
|
|
296
|
+
# @param lines [Array<String>] raw output lines from `git log --pretty=raw`
|
|
297
|
+
#
|
|
298
|
+
# @return [void]
|
|
299
|
+
#
|
|
300
|
+
def initialize(lines)
|
|
301
|
+
@lines = lines
|
|
302
|
+
@commits = []
|
|
303
|
+
@current_commit = nil
|
|
304
|
+
@in_message = false
|
|
305
|
+
@last_metadata_key = nil
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Parse raw `git log --pretty=raw` lines into commit hashes
|
|
309
|
+
#
|
|
310
|
+
# @return [Array<Hash>] the parsed commits in command output order
|
|
311
|
+
#
|
|
312
|
+
def parse
|
|
313
|
+
@lines.each { |line| process_line(line.chomp) }
|
|
314
|
+
finalize_commit
|
|
315
|
+
@commits
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
private
|
|
319
|
+
|
|
320
|
+
# Routes a raw line to message or metadata parsing
|
|
321
|
+
#
|
|
322
|
+
# @param line [String] the current raw log output line
|
|
323
|
+
#
|
|
324
|
+
# @return [void]
|
|
325
|
+
#
|
|
326
|
+
def process_line(line)
|
|
327
|
+
if line.empty?
|
|
328
|
+
@in_message = !@in_message
|
|
329
|
+
return
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
@in_message = false if @in_message && !line.start_with?(' ')
|
|
333
|
+
|
|
334
|
+
@in_message ? process_message_line(line) : process_metadata_line(line)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Appends a commit message line to the current commit buffer
|
|
338
|
+
#
|
|
339
|
+
# @param line [String] an indented message line from raw output
|
|
340
|
+
#
|
|
341
|
+
# @return [void]
|
|
342
|
+
#
|
|
343
|
+
def process_message_line(line)
|
|
344
|
+
@current_commit['message'] << "#{line[4..]}\n"
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# Parses metadata lines and multi-line metadata continuations
|
|
348
|
+
#
|
|
349
|
+
# @param line [String] a metadata line from raw output
|
|
350
|
+
#
|
|
351
|
+
# @return [void]
|
|
352
|
+
#
|
|
353
|
+
def process_metadata_line(line)
|
|
354
|
+
if line.start_with?(' ') && @last_metadata_key
|
|
355
|
+
@current_commit[@last_metadata_key] << "\n#{line[1..]}"
|
|
356
|
+
return
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
key, *value = line.split
|
|
360
|
+
value = value.join(' ')
|
|
361
|
+
@last_metadata_key = nil
|
|
362
|
+
dispatch_metadata_key(key, value)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Applies a metadata key/value pair to the current commit
|
|
366
|
+
#
|
|
367
|
+
# @param key [String] the metadata key from the raw log line
|
|
368
|
+
#
|
|
369
|
+
# @param value [String] the parsed metadata value
|
|
370
|
+
#
|
|
371
|
+
# @return [void]
|
|
372
|
+
#
|
|
373
|
+
def dispatch_metadata_key(key, value)
|
|
374
|
+
case key
|
|
375
|
+
when 'commit'
|
|
376
|
+
start_new_commit(value)
|
|
377
|
+
when 'parent'
|
|
378
|
+
@current_commit['parent'] << value
|
|
379
|
+
else
|
|
380
|
+
@current_commit[key] = value
|
|
381
|
+
@last_metadata_key = key
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Starts a new commit record in the parser state
|
|
386
|
+
#
|
|
387
|
+
# @param sha [String] the commit SHA for the new record
|
|
388
|
+
#
|
|
389
|
+
# @return [void]
|
|
390
|
+
#
|
|
391
|
+
def start_new_commit(sha)
|
|
392
|
+
finalize_commit
|
|
393
|
+
@current_commit = { 'sha' => sha, 'message' => +'', 'parent' => [] }
|
|
394
|
+
@last_metadata_key = nil
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Appends the current commit to the parsed results when present
|
|
398
|
+
#
|
|
399
|
+
# @return [void]
|
|
400
|
+
#
|
|
401
|
+
def finalize_commit
|
|
402
|
+
@commits << @current_commit if @current_commit
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
private_constant :RawLogParser
|
|
406
|
+
end
|
|
407
|
+
private_constant :Private
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
end
|