git 4.3.2 → 5.0.0.beta.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.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +67 -2705
- data/.github/pull_request_template.md +3 -1
- data/.github/skills/breaking-change-analysis/SKILL.md +102 -0
- data/.github/skills/ci-cd-troubleshooting/SKILL.md +264 -0
- data/.github/skills/command-implementation/REFERENCE.md +993 -0
- data/.github/skills/command-implementation/SKILL.md +229 -0
- data/.github/skills/command-test-conventions/SKILL.md +660 -0
- data/.github/skills/command-yard-documentation/SKILL.md +426 -0
- data/.github/skills/dependency-management/SKILL.md +72 -0
- data/.github/skills/development-workflow/SKILL.md +506 -0
- data/.github/skills/extract-command-from-lib/SKILL.md +487 -0
- data/.github/skills/extract-facade-from-base-lib/SKILL.md +586 -0
- data/.github/skills/facade-implementation/REFERENCE.md +840 -0
- data/.github/skills/facade-implementation/SKILL.md +260 -0
- data/.github/skills/facade-test-conventions/SKILL.md +380 -0
- data/.github/skills/facade-yard-documentation/SKILL.md +429 -0
- data/.github/skills/make-skill-template/SKILL.md +176 -0
- data/.github/skills/pr-readiness-review/SKILL.md +185 -0
- data/.github/skills/project-context/SKILL.md +313 -0
- data/.github/skills/pull-request-review/SKILL.md +168 -0
- data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +131 -0
- data/.github/skills/release-management/SKILL.md +125 -0
- data/.github/skills/review-arguments-dsl/CHECKLIST.md +788 -0
- data/.github/skills/review-arguments-dsl/SKILL.md +214 -0
- data/.github/skills/review-backward-compatibility/SKILL.md +275 -0
- data/.github/skills/review-cross-command-consistency/SKILL.md +139 -0
- data/.github/skills/reviewing-skills/SKILL.md +189 -0
- data/.github/skills/rspec-unit-testing-standards/SKILL.md +639 -0
- data/.github/skills/tdd-refactor-step/SKILL.md +236 -0
- data/.github/skills/test-debugging/SKILL.md +160 -0
- data/.github/skills/yard-documentation/SKILL.md +793 -0
- data/.github/workflows/continuous_integration.yml +3 -2
- data/.github/workflows/enforce_conventional_commits.yml +1 -1
- data/.github/workflows/experimental_continuous_integration.yml +2 -2
- data/.github/workflows/release.yml +3 -4
- data/.gitignore +8 -0
- data/.husky/pre-commit +13 -0
- data/.release-please-manifest.json +1 -1
- data/.rspec +3 -0
- data/.rubocop.yml +7 -3
- data/.rubocop_todo.yml +23 -5
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -40
- data/CONTRIBUTING.md +694 -53
- data/README.md +17 -5
- data/Rakefile +61 -9
- data/commitlint.test +4 -0
- data/git.gemspec +14 -8
- data/lib/git/args_builder.rb +0 -8
- data/lib/git/base.rb +486 -410
- data/lib/git/branch.rb +380 -43
- data/lib/git/branch_delete_failure.rb +31 -0
- data/lib/git/branch_delete_result.rb +63 -0
- data/lib/git/branch_info.rb +178 -0
- data/lib/git/branches.rb +130 -24
- data/lib/git/command_line/base.rb +245 -0
- data/lib/git/command_line/capturing.rb +249 -0
- data/lib/git/command_line/result.rb +96 -0
- data/lib/git/command_line/streaming.rb +194 -0
- data/lib/git/command_line.rb +43 -322
- data/lib/git/command_line_result.rb +4 -88
- data/lib/git/commands/add.rb +131 -0
- data/lib/git/commands/am/abort.rb +43 -0
- data/lib/git/commands/am/apply.rb +252 -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 +47 -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 +237 -0
- data/lib/git/commands/archive/list_formats.rb +46 -0
- data/lib/git/commands/archive.rb +140 -0
- data/lib/git/commands/arguments.rb +3510 -0
- data/lib/git/commands/base.rb +403 -0
- data/lib/git/commands/branch/copy.rb +94 -0
- data/lib/git/commands/branch/create.rb +173 -0
- data/lib/git/commands/branch/delete.rb +80 -0
- data/lib/git/commands/branch/list.rb +162 -0
- data/lib/git/commands/branch/move.rb +94 -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 +57 -0
- data/lib/git/commands/branch.rb +34 -0
- data/lib/git/commands/cat_file/batch.rb +364 -0
- data/lib/git/commands/cat_file/filtered.rb +105 -0
- data/lib/git/commands/cat_file/raw.rb +210 -0
- data/lib/git/commands/cat_file.rb +49 -0
- data/lib/git/commands/checkout/branch.rb +151 -0
- data/lib/git/commands/checkout/files.rb +115 -0
- data/lib/git/commands/checkout.rb +38 -0
- data/lib/git/commands/checkout_index.rb +105 -0
- data/lib/git/commands/clean.rb +100 -0
- data/lib/git/commands/clone.rb +240 -0
- data/lib/git/commands/commit.rb +272 -0
- data/lib/git/commands/commit_tree.rb +100 -0
- data/lib/git/commands/config_option_syntax/add.rb +83 -0
- data/lib/git/commands/config_option_syntax/get.rb +117 -0
- data/lib/git/commands/config_option_syntax/get_all.rb +115 -0
- data/lib/git/commands/config_option_syntax/get_color.rb +91 -0
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +93 -0
- data/lib/git/commands/config_option_syntax/get_regexp.rb +115 -0
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +102 -0
- data/lib/git/commands/config_option_syntax/list.rb +107 -0
- data/lib/git/commands/config_option_syntax/remove_section.rb +74 -0
- data/lib/git/commands/config_option_syntax/rename_section.rb +78 -0
- data/lib/git/commands/config_option_syntax/replace_all.rb +104 -0
- data/lib/git/commands/config_option_syntax/set.rb +114 -0
- data/lib/git/commands/config_option_syntax/unset.rb +89 -0
- data/lib/git/commands/config_option_syntax/unset_all.rb +89 -0
- data/lib/git/commands/config_option_syntax.rb +56 -0
- data/lib/git/commands/describe.rb +155 -0
- data/lib/git/commands/diff.rb +656 -0
- data/lib/git/commands/diff_files.rb +518 -0
- data/lib/git/commands/diff_index.rb +496 -0
- data/lib/git/commands/fetch.rb +352 -0
- data/lib/git/commands/fsck.rb +136 -0
- data/lib/git/commands/gc.rb +132 -0
- data/lib/git/commands/grep.rb +338 -0
- data/lib/git/commands/init.rb +99 -0
- data/lib/git/commands/log.rb +632 -0
- data/lib/git/commands/ls_files.rb +191 -0
- data/lib/git/commands/ls_remote.rb +155 -0
- data/lib/git/commands/ls_tree.rb +131 -0
- data/lib/git/commands/maintenance/register.rb +75 -0
- data/lib/git/commands/maintenance/run.rb +104 -0
- data/lib/git/commands/maintenance/start.rb +66 -0
- data/lib/git/commands/maintenance/stop.rb +55 -0
- data/lib/git/commands/maintenance/unregister.rb +79 -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 +245 -0
- data/lib/git/commands/merge.rb +28 -0
- data/lib/git/commands/merge_base.rb +86 -0
- data/lib/git/commands/mv.rb +77 -0
- data/lib/git/commands/name_rev.rb +114 -0
- data/lib/git/commands/pull.rb +377 -0
- data/lib/git/commands/push.rb +246 -0
- data/lib/git/commands/read_tree.rb +149 -0
- data/lib/git/commands/remote/add.rb +91 -0
- data/lib/git/commands/remote/get_url.rb +66 -0
- data/lib/git/commands/remote/list.rb +54 -0
- data/lib/git/commands/remote/prune.rb +61 -0
- data/lib/git/commands/remote/remove.rb +52 -0
- data/lib/git/commands/remote/rename.rb +69 -0
- data/lib/git/commands/remote/set_branches.rb +63 -0
- data/lib/git/commands/remote/set_head.rb +82 -0
- data/lib/git/commands/remote/set_url.rb +71 -0
- data/lib/git/commands/remote/set_url_add.rb +61 -0
- data/lib/git/commands/remote/set_url_delete.rb +64 -0
- data/lib/git/commands/remote/show.rb +71 -0
- data/lib/git/commands/remote/update.rb +72 -0
- data/lib/git/commands/remote.rb +42 -0
- data/lib/git/commands/repack.rb +277 -0
- data/lib/git/commands/reset.rb +147 -0
- data/lib/git/commands/rev_parse.rb +297 -0
- data/lib/git/commands/revert/abort.rb +45 -0
- data/lib/git/commands/revert/continue.rb +57 -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 +153 -0
- data/lib/git/commands/revert.rb +29 -0
- data/lib/git/commands/rm.rb +114 -0
- data/lib/git/commands/show.rb +632 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +120 -0
- data/lib/git/commands/show_ref/exists.rb +78 -0
- data/lib/git/commands/show_ref/list.rb +145 -0
- data/lib/git/commands/show_ref/verify.rb +120 -0
- data/lib/git/commands/show_ref.rb +42 -0
- data/lib/git/commands/stash/apply.rb +75 -0
- data/lib/git/commands/stash/branch.rb +65 -0
- data/lib/git/commands/stash/clear.rb +41 -0
- data/lib/git/commands/stash/create.rb +58 -0
- data/lib/git/commands/stash/drop.rb +67 -0
- data/lib/git/commands/stash/list.rb +39 -0
- data/lib/git/commands/stash/pop.rb +78 -0
- data/lib/git/commands/stash/push.rb +103 -0
- data/lib/git/commands/stash/show.rb +149 -0
- data/lib/git/commands/stash/store.rb +63 -0
- data/lib/git/commands/stash.rb +38 -0
- data/lib/git/commands/status.rb +169 -0
- data/lib/git/commands/symbolic_ref/delete.rb +68 -0
- data/lib/git/commands/symbolic_ref/read.rb +95 -0
- data/lib/git/commands/symbolic_ref/update.rb +76 -0
- data/lib/git/commands/symbolic_ref.rb +38 -0
- data/lib/git/commands/tag/create.rb +139 -0
- data/lib/git/commands/tag/delete.rb +55 -0
- data/lib/git/commands/tag/list.rb +143 -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 +140 -0
- data/lib/git/commands/update_ref/delete.rb +92 -0
- data/lib/git/commands/update_ref/update.rb +106 -0
- data/lib/git/commands/update_ref.rb +42 -0
- data/lib/git/commands/version.rb +52 -0
- data/lib/git/commands/worktree/add.rb +140 -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 +89 -0
- data/lib/git/detached_head_info.rb +54 -0
- data/lib/git/diff.rb +297 -7
- data/lib/git/diff_file_numstat_info.rb +29 -0
- data/lib/git/diff_file_patch_info.rb +134 -0
- data/lib/git/diff_file_raw_info.rb +127 -0
- data/lib/git/diff_info.rb +169 -0
- data/lib/git/diff_path_status.rb +78 -19
- data/lib/git/diff_result.rb +32 -0
- data/lib/git/diff_stats.rb +59 -14
- data/lib/git/dirstat_info.rb +86 -0
- data/lib/git/errors.rb +65 -2
- data/lib/git/execution_context/global.rb +56 -0
- data/lib/git/execution_context/repository.rb +147 -0
- data/lib/git/execution_context.rb +482 -0
- data/lib/git/file_ref.rb +74 -0
- data/lib/git/fsck_object.rb +9 -9
- data/lib/git/fsck_result.rb +1 -1
- data/lib/git/lib.rb +1606 -1028
- data/lib/git/log.rb +15 -2
- data/lib/git/object.rb +92 -22
- data/lib/git/parsers/branch.rb +224 -0
- data/lib/git/parsers/cat_file.rb +111 -0
- data/lib/git/parsers/diff.rb +585 -0
- data/lib/git/parsers/fsck.rb +133 -0
- data/lib/git/parsers/grep.rb +42 -0
- data/lib/git/parsers/ls_tree.rb +58 -0
- data/lib/git/parsers/stash.rb +208 -0
- data/lib/git/parsers/tag.rb +257 -0
- data/lib/git/remote.rb +133 -9
- data/lib/git/repository/branching.rb +572 -0
- data/lib/git/repository/committing.rb +191 -0
- data/lib/git/repository/configuring.rb +156 -0
- data/lib/git/repository/diffing.rb +775 -0
- data/lib/git/repository/inspecting.rb +153 -0
- data/lib/git/repository/logging.rb +247 -0
- data/lib/git/repository/merging.rb +295 -0
- data/lib/git/repository/object_operations.rb +1101 -0
- data/lib/git/repository/path_resolver.rb +207 -0
- data/lib/git/repository/remote_operations.rb +753 -0
- data/lib/git/repository/shared_private.rb +51 -0
- data/lib/git/repository/staging.rb +390 -0
- data/lib/git/repository/stashing.rb +107 -0
- data/lib/git/repository/status_operations.rb +180 -0
- data/lib/git/repository/worktree_operations.rb +159 -0
- data/lib/git/repository.rb +264 -1
- data/lib/git/stash.rb +85 -4
- data/lib/git/stash_info.rb +104 -0
- data/lib/git/stashes.rb +130 -13
- data/lib/git/status.rb +224 -18
- data/lib/git/tag_delete_failure.rb +31 -0
- data/lib/git/tag_delete_result.rb +63 -0
- data/lib/git/tag_info.rb +105 -0
- data/lib/git/version.rb +109 -2
- data/lib/git/version_constraint.rb +81 -0
- data/lib/git/worktree.rb +120 -5
- data/lib/git/worktrees.rb +107 -7
- data/lib/git.rb +114 -18
- data/redesign/1_architecture_existing.md +54 -18
- data/redesign/2_architecture_redesign.md +365 -46
- data/redesign/3_architecture_implementation.md +1451 -54
- data/tasks/gem_tasks.rake +4 -0
- data/tasks/npm_tasks.rake +7 -0
- data/tasks/rspec.rake +48 -0
- data/tasks/test.rake +13 -1
- data/tasks/yard.rake +34 -7
- metadata +349 -20
- data/lib/git/index.rb +0 -6
- data/lib/git/path.rb +0 -38
- data/lib/git/working_directory.rb +0 -6
- /data/{release-please-config.json → .release-please-config.json} +0 -0
data/lib/git/diff_stats.rb
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Git
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# Lazy diff statistics for a comparison between two trees
|
|
5
|
+
#
|
|
6
|
+
# Supports comparing (1) two commits, (2) a commit against the working tree,
|
|
7
|
+
# or (3) the index against the working tree.
|
|
8
|
+
#
|
|
9
|
+
# @example Get the insertion and deletion counts
|
|
10
|
+
# stats = repo.diff_stats
|
|
11
|
+
# stats.insertions #=> 3
|
|
12
|
+
# stats.deletions #=> 1
|
|
13
|
+
#
|
|
14
|
+
# @api public
|
|
6
15
|
class DiffStats
|
|
7
16
|
# @private
|
|
8
17
|
def initialize(base, from, to, path_limiter = nil)
|
|
@@ -15,45 +24,81 @@ module Git
|
|
|
15
24
|
@from = from
|
|
16
25
|
@to = to
|
|
17
26
|
@path_limiter = path_limiter
|
|
18
|
-
@
|
|
27
|
+
@fetch_stats = nil
|
|
19
28
|
end
|
|
20
29
|
|
|
21
|
-
# Returns the total number of lines deleted
|
|
30
|
+
# Returns the total number of lines deleted
|
|
31
|
+
#
|
|
32
|
+
# @example Get the deletion count
|
|
33
|
+
# stats = repo.diff_stats
|
|
34
|
+
# stats.deletions #=> 5
|
|
35
|
+
#
|
|
36
|
+
# @return [Integer] the total deletion count
|
|
22
37
|
def deletions
|
|
23
38
|
fetch_stats[:total][:deletions]
|
|
24
39
|
end
|
|
25
40
|
|
|
26
|
-
# Returns the total number of lines inserted
|
|
41
|
+
# Returns the total number of lines inserted
|
|
42
|
+
#
|
|
43
|
+
# @example Get the insertion count
|
|
44
|
+
# stats = repo.diff_stats
|
|
45
|
+
# stats.insertions #=> 3
|
|
46
|
+
#
|
|
47
|
+
# @return [Integer] the total insertion count
|
|
27
48
|
def insertions
|
|
28
49
|
fetch_stats[:total][:insertions]
|
|
29
50
|
end
|
|
30
51
|
|
|
31
|
-
# Returns the total number of lines changed (insertions + deletions)
|
|
52
|
+
# Returns the total number of lines changed (insertions + deletions)
|
|
53
|
+
#
|
|
54
|
+
# @example Get the total changed-line count
|
|
55
|
+
# stats = repo.diff_stats
|
|
56
|
+
# stats.lines #=> 8
|
|
57
|
+
#
|
|
58
|
+
# @return [Integer] the total changed-line count
|
|
32
59
|
def lines
|
|
33
60
|
fetch_stats[:total][:lines]
|
|
34
61
|
end
|
|
35
62
|
|
|
36
|
-
# Returns a hash of statistics for each file in the diff
|
|
63
|
+
# Returns a hash of statistics for each file in the diff
|
|
64
|
+
#
|
|
65
|
+
# @example Get per-file statistics
|
|
66
|
+
# stats = repo.diff_stats
|
|
67
|
+
# stats.files #=> { "lib/foo.rb" => { insertions: 3, deletions: 1 } }
|
|
37
68
|
#
|
|
38
|
-
# @return [Hash
|
|
69
|
+
# @return [Hash{String=>Hash{Symbol=>Integer}}]
|
|
70
|
+
# per-file statistics keyed by file path
|
|
39
71
|
def files
|
|
40
72
|
fetch_stats[:files]
|
|
41
73
|
end
|
|
42
74
|
|
|
43
|
-
# Returns a hash of the total statistics for the diff
|
|
75
|
+
# Returns a hash of the total statistics for the diff
|
|
76
|
+
#
|
|
77
|
+
# @example Get total statistics
|
|
78
|
+
# stats = repo.diff_stats
|
|
79
|
+
# stats.total #=> { insertions: 3, deletions: 1, lines: 4, files: 1 }
|
|
44
80
|
#
|
|
45
|
-
# @return [{
|
|
81
|
+
# @return [Hash{Symbol=>Integer}]
|
|
82
|
+
# aggregate statistics for the entire diff
|
|
46
83
|
def total
|
|
47
84
|
fetch_stats[:total]
|
|
48
85
|
end
|
|
49
86
|
|
|
50
87
|
private
|
|
51
88
|
|
|
52
|
-
# Lazily fetches and caches the stats from the git lib
|
|
89
|
+
# Lazily fetches and caches the stats from the git lib
|
|
90
|
+
#
|
|
91
|
+
# When `@base` implements `#diff_numstat`, delegates directly to that
|
|
92
|
+
# method. Otherwise falls back to the legacy `@base.lib.diff_stats` call
|
|
93
|
+
# so that existing `Git::Base`-backed callers continue to work unchanged.
|
|
94
|
+
#
|
|
95
|
+
# @return [Hash] the fetched stats hash
|
|
53
96
|
def fetch_stats
|
|
54
|
-
@fetch_stats ||= @base.
|
|
55
|
-
|
|
56
|
-
|
|
97
|
+
@fetch_stats ||= if @base.respond_to?(:diff_numstat)
|
|
98
|
+
@base.diff_numstat(@from, @to, path_limiter: @path_limiter)
|
|
99
|
+
else
|
|
100
|
+
@base.lib.diff_stats(@from, @to, { path_limiter: @path_limiter })
|
|
101
|
+
end
|
|
57
102
|
end
|
|
58
103
|
end
|
|
59
104
|
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Immutable value object representing a single directory's contribution to a diff
|
|
5
|
+
#
|
|
6
|
+
# @api public
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# info = Git::DirstatEntry.new(directory: 'lib/commands/', percentage: 45.2)
|
|
10
|
+
# info.directory #=> "lib/commands/"
|
|
11
|
+
# info.percentage #=> 45.2
|
|
12
|
+
#
|
|
13
|
+
# @!attribute [r] directory
|
|
14
|
+
# @return [String] the directory path (always ends with '/')
|
|
15
|
+
#
|
|
16
|
+
# @!attribute [r] percentage
|
|
17
|
+
# @return [Float] the percentage of changes in this directory (0.0-100.0)
|
|
18
|
+
#
|
|
19
|
+
DirstatEntry = Data.define(:directory, :percentage)
|
|
20
|
+
|
|
21
|
+
# Immutable result object from git --dirstat output
|
|
22
|
+
#
|
|
23
|
+
# Contains the list of directories and their contribution percentages to the diff.
|
|
24
|
+
#
|
|
25
|
+
# @api public
|
|
26
|
+
#
|
|
27
|
+
# @example
|
|
28
|
+
# dirstat = Git::DirstatInfo.new(
|
|
29
|
+
# entries: [
|
|
30
|
+
# Git::DirstatEntry.new(directory: 'lib/commands/', percentage: 45.2),
|
|
31
|
+
# Git::DirstatEntry.new(directory: 'spec/unit/', percentage: 30.1)
|
|
32
|
+
# ]
|
|
33
|
+
# )
|
|
34
|
+
# dirstat.entries.first.directory #=> "lib/commands/"
|
|
35
|
+
# dirstat['lib/commands/'] #=> 45.2
|
|
36
|
+
# dirstat.to_h #=> { "lib/commands/" => 45.2, "spec/unit/" => 30.1 }
|
|
37
|
+
#
|
|
38
|
+
# @!attribute [r] entries
|
|
39
|
+
# @return [Array<DirstatEntry>] directory statistics in order from git output
|
|
40
|
+
#
|
|
41
|
+
DirstatInfo = Data.define(:entries) do
|
|
42
|
+
# Look up percentage by directory path
|
|
43
|
+
#
|
|
44
|
+
# @param directory [String] the directory path
|
|
45
|
+
# @return [Float, nil] the percentage or nil if not found
|
|
46
|
+
#
|
|
47
|
+
def [](directory)
|
|
48
|
+
entries.find { |e| e.directory == directory }&.percentage
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Convert to a Hash mapping directory to percentage
|
|
52
|
+
#
|
|
53
|
+
# @return [Hash<String, Float>]
|
|
54
|
+
#
|
|
55
|
+
def to_h
|
|
56
|
+
entries.to_h { |e| [e.directory, e.percentage] }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Number of directories in the dirstat
|
|
60
|
+
#
|
|
61
|
+
# @return [Integer]
|
|
62
|
+
#
|
|
63
|
+
def size
|
|
64
|
+
entries.size
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Check if dirstat is empty
|
|
68
|
+
#
|
|
69
|
+
# @return [Boolean]
|
|
70
|
+
#
|
|
71
|
+
def empty?
|
|
72
|
+
entries.empty?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Iterate over entries
|
|
76
|
+
#
|
|
77
|
+
# @yield [DirstatEntry] each entry
|
|
78
|
+
# @return [Enumerator] if no block given
|
|
79
|
+
#
|
|
80
|
+
def each(&block)
|
|
81
|
+
entries.each(&block)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
include Enumerable
|
|
85
|
+
end
|
|
86
|
+
end
|
data/lib/git/errors.rb
CHANGED
|
@@ -21,7 +21,8 @@ module Git
|
|
|
21
21
|
# │ └─> Git::SignaledError
|
|
22
22
|
# │ └─> Git::TimeoutError
|
|
23
23
|
# ├─> Git::ProcessIOError
|
|
24
|
-
#
|
|
24
|
+
# ├─> Git::UnexpectedResultError
|
|
25
|
+
# └─> Git::VersionError
|
|
25
26
|
# ```
|
|
26
27
|
#
|
|
27
28
|
# | Error Class | Description |
|
|
@@ -33,6 +34,7 @@ module Git
|
|
|
33
34
|
# | `TimeoutError` | This is a specific type of `SignaledError` that is raised when the git command line operation times out and is killed via the SIGKILL signal. This happens if the operation takes longer than the timeout duration configured in `Git.config.timeout` or via the `:timeout` parameter given in git methods that support timeouts. |
|
|
34
35
|
# | `ProcessIOError` | An error was encountered reading or writing to a subprocess. |
|
|
35
36
|
# | `UnexpectedResultError` | The command line ran without error but did not return the expected results. |
|
|
37
|
+
# | `VersionError` | The installed git version does not meet the requirements of the git gem or a specific command. |
|
|
36
38
|
#
|
|
37
39
|
# @example Rescuing a generic error
|
|
38
40
|
# begin
|
|
@@ -57,6 +59,7 @@ module Git
|
|
|
57
59
|
# @see Git::TimeoutError
|
|
58
60
|
# @see Git::ProcessIOError
|
|
59
61
|
# @see Git::UnexpectedResultError
|
|
62
|
+
# @see Git::VersionError
|
|
60
63
|
#
|
|
61
64
|
# @api public
|
|
62
65
|
#
|
|
@@ -146,7 +149,7 @@ module Git
|
|
|
146
149
|
# The git command executed, status, stdout, and stderr, and the timeout duration
|
|
147
150
|
# are available from this object.
|
|
148
151
|
#
|
|
149
|
-
# result.status.
|
|
152
|
+
# result.status.timed_out? will be `true`
|
|
150
153
|
#
|
|
151
154
|
# @api public
|
|
152
155
|
#
|
|
@@ -209,4 +212,64 @@ module Git
|
|
|
209
212
|
# @api public
|
|
210
213
|
#
|
|
211
214
|
class UnexpectedResultError < Git::Error; end
|
|
215
|
+
|
|
216
|
+
# Raised when the installed git version does not meet requirements
|
|
217
|
+
#
|
|
218
|
+
# This error is raised when:
|
|
219
|
+
# - The installed git version is below `Git::MINIMUM_GIT_VERSION`
|
|
220
|
+
# - A command requires a minimum git version that isn't met
|
|
221
|
+
# - A command was removed in a git version older than the installed version
|
|
222
|
+
#
|
|
223
|
+
# @example Rescuing a version error
|
|
224
|
+
# begin
|
|
225
|
+
# git.some_command
|
|
226
|
+
# rescue Git::VersionError => e
|
|
227
|
+
# puts "Git version #{e.actual_version} does not meet requirements"
|
|
228
|
+
# puts " #{e.subject}: requires #{e.constraint}"
|
|
229
|
+
# end
|
|
230
|
+
#
|
|
231
|
+
# @api public
|
|
232
|
+
#
|
|
233
|
+
class VersionError < Git::Error
|
|
234
|
+
# Create a VersionError
|
|
235
|
+
#
|
|
236
|
+
# @param subject [#to_s] the entity with the version requirement (e.g., "The git gem", a Class)
|
|
237
|
+
# @param constraint [Git::VersionConstraint] the version constraint that was violated
|
|
238
|
+
# @param actual_version [Git::Version] the installed git version
|
|
239
|
+
#
|
|
240
|
+
def initialize(subject:, constraint:, actual_version:)
|
|
241
|
+
@subject = subject
|
|
242
|
+
@constraint = constraint
|
|
243
|
+
@actual_version = actual_version
|
|
244
|
+
super(build_message)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# The entity that has the version requirement
|
|
248
|
+
#
|
|
249
|
+
# @return [#to_s]
|
|
250
|
+
#
|
|
251
|
+
attr_reader :subject
|
|
252
|
+
|
|
253
|
+
# The version constraint that was violated
|
|
254
|
+
#
|
|
255
|
+
# @return [Git::VersionConstraint]
|
|
256
|
+
#
|
|
257
|
+
attr_reader :constraint
|
|
258
|
+
|
|
259
|
+
# The installed git version that caused the error
|
|
260
|
+
#
|
|
261
|
+
# @return [Git::Version]
|
|
262
|
+
#
|
|
263
|
+
attr_reader :actual_version
|
|
264
|
+
|
|
265
|
+
private
|
|
266
|
+
|
|
267
|
+
def build_message
|
|
268
|
+
if constraint.too_new?(actual_version)
|
|
269
|
+
"#{subject} requires git < #{constraint.before} (found #{actual_version})"
|
|
270
|
+
else
|
|
271
|
+
"#{subject} requires git >= #{constraint.min} (found #{actual_version})"
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
212
275
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/execution_context'
|
|
4
|
+
|
|
5
|
+
module Git
|
|
6
|
+
class ExecutionContext
|
|
7
|
+
# Execution context for global git commands (no repository required)
|
|
8
|
+
#
|
|
9
|
+
# Used for commands that do not require an existing repository — such as
|
|
10
|
+
# `git init`, `git clone`, and `git version`. Unlike
|
|
11
|
+
# {Git::ExecutionContext::Repository}, this class leaves `GIT_DIR`,
|
|
12
|
+
# `GIT_WORK_TREE`, and `GIT_INDEX_FILE` as `nil` (which unsets them), so
|
|
13
|
+
# that the parent environment cannot leak an unintended repository context.
|
|
14
|
+
# `GIT_SSH` is still supported to allow SSH-based remote operations
|
|
15
|
+
# (e.g. `git clone git@github.com:...`).
|
|
16
|
+
#
|
|
17
|
+
# @example Create a context using the default git binary
|
|
18
|
+
# context = Git::ExecutionContext::Global.new
|
|
19
|
+
#
|
|
20
|
+
# @example Create a context targeting a specific binary
|
|
21
|
+
# context = Git::ExecutionContext::Global.new(binary_path: '/usr/local/bin/git2')
|
|
22
|
+
#
|
|
23
|
+
# @api private
|
|
24
|
+
#
|
|
25
|
+
class Global < ExecutionContext
|
|
26
|
+
# Creates a new global execution context
|
|
27
|
+
#
|
|
28
|
+
# @example Create with default settings
|
|
29
|
+
# Git::ExecutionContext::Global.new
|
|
30
|
+
#
|
|
31
|
+
# @example Create with an explicit binary path
|
|
32
|
+
# Git::ExecutionContext::Global.new(binary_path: '/usr/local/bin/git2')
|
|
33
|
+
#
|
|
34
|
+
# @param binary_path [String, :use_global_config] path to the git binary
|
|
35
|
+
#
|
|
36
|
+
# Give `:use_global_config` (the default) to use `Git::Base.config.binary_path`.
|
|
37
|
+
#
|
|
38
|
+
# Passing `nil` raises `ArgumentError` — there is no "unset the
|
|
39
|
+
# binary" semantic.
|
|
40
|
+
#
|
|
41
|
+
# @param git_ssh [String, nil, :use_global_config] the SSH wrapper path
|
|
42
|
+
#
|
|
43
|
+
# Give `nil` to unset `GIT_SSH`, or `:use_global_config` (default) to use `Git::Base.config.git_ssh`.
|
|
44
|
+
#
|
|
45
|
+
# @param logger [Logger, nil] the logger to use in the CommandLine layer
|
|
46
|
+
#
|
|
47
|
+
# Give `nil` to use a null logger (`Logger.new(nil)`).
|
|
48
|
+
#
|
|
49
|
+
# @raise [ArgumentError] if `binary_path` is `nil`
|
|
50
|
+
#
|
|
51
|
+
def initialize(binary_path: :use_global_config, git_ssh: :use_global_config, logger: nil)
|
|
52
|
+
super
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/execution_context'
|
|
4
|
+
|
|
5
|
+
module Git
|
|
6
|
+
class ExecutionContext
|
|
7
|
+
# Execution context for repository-bound git commands
|
|
8
|
+
#
|
|
9
|
+
# Manages the git environment for commands that operate within an existing
|
|
10
|
+
# repository — setting `GIT_DIR`, `GIT_WORK_TREE`, `GIT_INDEX_FILE`, and
|
|
11
|
+
# `GIT_SSH` — and prepending `--git-dir` / `--work-tree` to every git
|
|
12
|
+
# invocation via {#global_opts}.
|
|
13
|
+
#
|
|
14
|
+
# ### Construction
|
|
15
|
+
#
|
|
16
|
+
# Prefer the factory class methods over `new` when building from a
|
|
17
|
+
# {Git::Base} object or a hash:
|
|
18
|
+
#
|
|
19
|
+
# context = Git::ExecutionContext::Repository.from_base(base)
|
|
20
|
+
# context = Git::ExecutionContext::Repository.from_hash(repository: '/repo/.git', ...)
|
|
21
|
+
#
|
|
22
|
+
# @example Build from a Git::Base object
|
|
23
|
+
# context = Git::ExecutionContext::Repository.from_base(git)
|
|
24
|
+
#
|
|
25
|
+
# @example Build from a configuration hash
|
|
26
|
+
# context = Git::ExecutionContext::Repository.from_hash(
|
|
27
|
+
# repository: '/path/to/.git',
|
|
28
|
+
# working_directory: '/path/to'
|
|
29
|
+
# )
|
|
30
|
+
#
|
|
31
|
+
# @api private
|
|
32
|
+
#
|
|
33
|
+
class Repository < ExecutionContext
|
|
34
|
+
# Creates a Repository context from a {Git::Base} instance
|
|
35
|
+
#
|
|
36
|
+
# @example Build from a base object
|
|
37
|
+
# git = Git.open('/path/to/repo')
|
|
38
|
+
# context = Git::ExecutionContext::Repository.from_base(git)
|
|
39
|
+
#
|
|
40
|
+
# @param base_object [Git::Base] the base Git object to derive context from
|
|
41
|
+
#
|
|
42
|
+
# @param logger [Logger, nil] logger forwarded to the CommandLine layer;
|
|
43
|
+
# `nil` uses a null logger (see {Git::ExecutionContext#initialize})
|
|
44
|
+
#
|
|
45
|
+
# @return [Git::ExecutionContext::Repository] the new repository context
|
|
46
|
+
#
|
|
47
|
+
def self.from_base(base_object, logger: nil)
|
|
48
|
+
new(
|
|
49
|
+
git_dir: base_object.repo.to_s,
|
|
50
|
+
git_index_file: base_object.index&.to_s,
|
|
51
|
+
git_work_dir: base_object.dir&.to_s,
|
|
52
|
+
base_object: base_object,
|
|
53
|
+
git_ssh: base_object.git_ssh,
|
|
54
|
+
binary_path: base_object.binary_path,
|
|
55
|
+
logger: logger
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Creates a Repository context from a Hash
|
|
60
|
+
#
|
|
61
|
+
# Expected keys: `:repository`, `:working_directory`, `:index`, `:git_ssh`,
|
|
62
|
+
# `:binary_path`
|
|
63
|
+
#
|
|
64
|
+
# @example Build from a configuration hash
|
|
65
|
+
# context = Git::ExecutionContext::Repository.from_hash(
|
|
66
|
+
# repository: '/path/to/.git',
|
|
67
|
+
# working_directory: '/path/to'
|
|
68
|
+
# )
|
|
69
|
+
#
|
|
70
|
+
# @param base_hash [Hash] the hash of repository configuration values
|
|
71
|
+
#
|
|
72
|
+
# @param logger [Logger, nil] logger forwarded to the CommandLine layer;
|
|
73
|
+
# `nil` uses a null logger (see {Git::ExecutionContext#initialize})
|
|
74
|
+
#
|
|
75
|
+
# @return [Git::ExecutionContext::Repository] the new repository context
|
|
76
|
+
#
|
|
77
|
+
def self.from_hash(base_hash, logger: nil)
|
|
78
|
+
new(
|
|
79
|
+
git_dir: base_hash[:repository],
|
|
80
|
+
git_index_file: base_hash[:index],
|
|
81
|
+
git_work_dir: base_hash[:working_directory],
|
|
82
|
+
git_ssh: base_hash.key?(:git_ssh) ? base_hash[:git_ssh] : :use_global_config,
|
|
83
|
+
binary_path: base_hash.key?(:binary_path) ? base_hash[:binary_path] : :use_global_config,
|
|
84
|
+
logger: logger
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Creates a new repository execution context
|
|
89
|
+
#
|
|
90
|
+
# @example Create with required git_dir
|
|
91
|
+
# Git::ExecutionContext::Repository.new(git_dir: '/path/to/.git')
|
|
92
|
+
#
|
|
93
|
+
# @param git_dir [String, nil] path to the `.git` directory
|
|
94
|
+
#
|
|
95
|
+
# @param git_work_dir [String, nil] path to the working tree
|
|
96
|
+
#
|
|
97
|
+
# @param git_index_file [String, nil] path to the index file
|
|
98
|
+
#
|
|
99
|
+
# @param base_object [Git::Base, nil] originating base object
|
|
100
|
+
#
|
|
101
|
+
# @param binary_path [String, :use_global_config] path to the git binary
|
|
102
|
+
#
|
|
103
|
+
# Give `:use_global_config` (the default) to use `Git::Base.config.binary_path`.
|
|
104
|
+
#
|
|
105
|
+
# Passing `nil` raises `ArgumentError` — there is no "unset the
|
|
106
|
+
# binary" semantic.
|
|
107
|
+
#
|
|
108
|
+
# @param git_ssh [String, nil, :use_global_config] the SSH wrapper path
|
|
109
|
+
#
|
|
110
|
+
# Give `nil` to unset `GIT_SSH`, or `:use_global_config` (default) to use `Git::Base.config.git_ssh`.
|
|
111
|
+
#
|
|
112
|
+
# @param logger [Logger, nil] the logger to use in the CommandLine layer
|
|
113
|
+
#
|
|
114
|
+
# Give `nil` to use a null logger (`Logger.new(nil)`).
|
|
115
|
+
#
|
|
116
|
+
# @raise [ArgumentError] if `binary_path` is `nil`
|
|
117
|
+
#
|
|
118
|
+
def initialize( # rubocop:disable Metrics/ParameterLists
|
|
119
|
+
git_dir:,
|
|
120
|
+
git_work_dir: nil,
|
|
121
|
+
git_index_file: nil,
|
|
122
|
+
base_object: nil,
|
|
123
|
+
binary_path: :use_global_config,
|
|
124
|
+
git_ssh: :use_global_config,
|
|
125
|
+
logger: nil
|
|
126
|
+
)
|
|
127
|
+
super(binary_path: binary_path, git_ssh: git_ssh, logger: logger)
|
|
128
|
+
@git_dir = git_dir
|
|
129
|
+
@git_work_dir = git_work_dir
|
|
130
|
+
@git_index_file = git_index_file
|
|
131
|
+
@base_object = base_object
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @return [String, nil] path to the `.git` directory
|
|
135
|
+
attr_reader :git_dir
|
|
136
|
+
|
|
137
|
+
# @return [String, nil] path to the working tree
|
|
138
|
+
attr_reader :git_work_dir
|
|
139
|
+
|
|
140
|
+
# @return [String, nil] path to the index file
|
|
141
|
+
attr_reader :git_index_file
|
|
142
|
+
|
|
143
|
+
# @return [Git::Base, nil] originating base object
|
|
144
|
+
attr_reader :base_object
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|