git 1.19.1 → 4.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.commitlintrc.yml +38 -0
  3. data/.github/copilot-instructions.md +2733 -0
  4. data/.github/pull_request_template.md +17 -0
  5. data/.github/workflows/continuous_integration.yml +92 -21
  6. data/.github/workflows/enforce_conventional_commits.yml +29 -0
  7. data/.github/workflows/experimental_continuous_integration.yml +59 -0
  8. data/.github/workflows/release.yml +53 -0
  9. data/.gitignore +5 -0
  10. data/.husky/commit-msg +1 -0
  11. data/.release-please-manifest.json +3 -0
  12. data/.rubocop.yml +55 -0
  13. data/.rubocop_todo.yml +12 -0
  14. data/.yardopts +4 -1
  15. data/AI_POLICY.md +24 -0
  16. data/CHANGELOG.md +501 -0
  17. data/CODE_OF_CONDUCT.md +25 -0
  18. data/CONTRIBUTING.md +323 -102
  19. data/GOVERNANCE.md +106 -0
  20. data/LICENSE +1 -1
  21. data/MAINTAINERS.md +17 -4
  22. data/README.md +575 -246
  23. data/Rakefile +13 -55
  24. data/git.gemspec +36 -30
  25. data/lib/git/args_builder.rb +111 -0
  26. data/lib/git/author.rb +9 -7
  27. data/lib/git/base.rb +602 -173
  28. data/lib/git/branch.rb +318 -38
  29. data/lib/git/branches.rb +21 -24
  30. data/lib/git/command_line.rb +330 -0
  31. data/lib/git/command_line_result.rb +9 -3
  32. data/lib/git/config.rb +10 -6
  33. data/lib/git/diff.rb +149 -81
  34. data/lib/git/diff_path_status.rb +46 -0
  35. data/lib/git/diff_stats.rb +59 -0
  36. data/lib/git/errors.rb +212 -0
  37. data/lib/git/escaped_path.rb +2 -2
  38. data/lib/git/fsck_object.rb +48 -0
  39. data/lib/git/fsck_result.rb +121 -0
  40. data/lib/git/index.rb +2 -1
  41. data/lib/git/lib.rb +1648 -643
  42. data/lib/git/log.rb +143 -106
  43. data/lib/git/object.rb +151 -125
  44. data/lib/git/path.rb +23 -16
  45. data/lib/git/remote.rb +5 -4
  46. data/lib/git/repository.rb +2 -2
  47. data/lib/git/stash.rb +11 -12
  48. data/lib/git/stashes.rb +16 -15
  49. data/lib/git/status.rb +104 -143
  50. data/lib/git/url.rb +3 -3
  51. data/lib/git/version.rb +3 -1
  52. data/lib/git/working_directory.rb +2 -0
  53. data/lib/git/worktree.rb +6 -5
  54. data/lib/git/worktrees.rb +6 -6
  55. data/lib/git.rb +131 -28
  56. data/package.json +10 -0
  57. data/redesign/1_architecture_existing.md +66 -0
  58. data/redesign/2_architecture_redesign.md +130 -0
  59. data/redesign/3_architecture_implementation.md +138 -0
  60. data/redesign/index.md +34 -0
  61. data/release-please-config.json +36 -0
  62. data/tasks/gem_tasks.rake +10 -0
  63. data/tasks/rubocop.rake +12 -0
  64. data/tasks/test.rake +13 -0
  65. data/tasks/test_gem.rake +12 -0
  66. data/tasks/yard.rake +23 -0
  67. metadata +114 -37
  68. data/.github/stale.yml +0 -25
  69. data/Dockerfile.changelog-rs +0 -12
  70. data/PULL_REQUEST_TEMPLATE.md +0 -9
  71. data/RELEASING.md +0 -70
  72. data/lib/git/base/factory.rb +0 -99
  73. data/lib/git/failed_error.rb +0 -53
  74. data/lib/git/git_execute_error.rb +0 -7
  75. data/lib/git/signaled_error.rb +0 -50
  76. /data/{ISSUE_TEMPLATE.md → .github/issue_template.md} +0 -0
data/lib/git/log.rb CHANGED
@@ -1,131 +1,168 @@
1
- module Git
1
+ # frozen_string_literal: true
2
2
 
3
- # object that holds the last X commits on given branch
3
+ module Git
4
+ # Builds and executes a `git log` query
5
+ #
6
+ # This class provides a fluent interface for building complex `git log` queries.
7
+ #
8
+ # Queries default to returning 30 commits; call {#max_count} with `:all` to
9
+ # return every matching commit. Calling {#all} adds the `--all` flag to include
10
+ # all refs in the search but does not change the number of commits returned.
11
+ #
12
+ # The query is lazily executed when results are requested either via the modern
13
+ # `#execute` method or the deprecated Enumerable methods.
14
+ #
15
+ # @example Using the modern `execute` API
16
+ # log = git.log.max_count(50).between('v1.0', 'v1.1').author('Scott')
17
+ # results = log.execute
18
+ # puts "Found #{results.size} commits."
19
+ # results.each { |commit| puts commit.sha }
20
+ #
21
+ # @api public
22
+ #
4
23
  class Log
5
24
  include Enumerable
6
25
 
7
- def initialize(base, count = 30)
8
- dirty_log
26
+ # An immutable, Enumerable collection of `Git::Object::Commit` objects.
27
+ # Returned by `Git::Log#execute`.
28
+ # @api public
29
+ Result = Data.define(:commits) do
30
+ include Enumerable
31
+
32
+ def each(&block) = commits.each(&block)
33
+ def last = commits.last
34
+ def [](index) = commits[index]
35
+ def to_s = commits.join("\n")
36
+ def size = commits.size
37
+ end
38
+
39
+ # Create a new Git::Log object
40
+ #
41
+ # @example
42
+ # git = Git.open('.')
43
+ # Git::Log.new(git)
44
+ #
45
+ # @param base [Git::Base] the git repository object
46
+ # @param max_count [Integer, Symbol, nil] the number of commits to return, or
47
+ # `:all` or `nil` to return all
48
+ #
49
+ # Passing max_count to {#initialize} is equivalent to calling {#max_count} on the object.
50
+ #
51
+ def initialize(base, max_count = 30)
9
52
  @base = base
10
- @count = count
11
- end
12
-
13
- def all
14
- dirty_log
15
- @all = true
16
- self
17
- end
18
-
19
- def object(objectish)
20
- dirty_log
21
- @object = objectish
22
- return self
23
- end
24
-
25
- def author(regex)
26
- dirty_log
27
- @author = regex
28
- return self
29
- end
30
-
31
- def grep(regex)
32
- dirty_log
33
- @grep = regex
34
- return self
35
- end
36
-
37
- def path(path)
38
- dirty_log
39
- @path = path
40
- return self
41
- end
42
-
43
- def skip(num)
44
- dirty_log
45
- @skip = num
46
- return self
47
- end
48
-
49
- def since(date)
50
- dirty_log
51
- @since = date
52
- return self
53
- end
54
-
55
- def until(date)
56
- dirty_log
57
- @until = date
58
- return self
59
- end
60
-
61
- def between(sha1, sha2 = nil)
62
- dirty_log
63
- @between = [sha1, sha2]
64
- return self
65
- end
66
-
67
- def cherry
68
- dirty_log
69
- @cherry = true
70
- return self
71
- end
72
-
73
- def to_s
74
- self.map { |c| c.to_s }.join("\n")
75
- end
76
-
77
-
78
- # forces git log to run
79
-
53
+ @options = {}
54
+ @dirty = true
55
+ self.max_count(max_count)
56
+ end
57
+
58
+ # Set query options using a fluent interface.
59
+ # Each method returns `self` to allow for chaining.
60
+ #
61
+ def max_count(num) = set_option(:count, num == :all ? nil : num)
62
+ def all = set_option(:all, true)
63
+ def object(objectish) = set_option(:object, objectish)
64
+ def author(regex) = set_option(:author, regex)
65
+ def grep(regex) = set_option(:grep, regex)
66
+ def path(path) = set_option(:path_limiter, path)
67
+ def skip(num) = set_option(:skip, num)
68
+ def since(date) = set_option(:since, date)
69
+ def until(date) = set_option(:until, date)
70
+ def between(val1, val2 = nil) = set_option(:between, [val1, val2])
71
+ def cherry = set_option(:cherry, true)
72
+ def merges = set_option(:merges, true)
73
+
74
+ # Executes the git log command and returns an immutable result object
75
+ #
76
+ # This is the preferred way to get log data. It separates the query
77
+ # building from the execution, making the API more predictable.
78
+ #
79
+ # @example
80
+ # query = g.log.since('2 weeks ago').author('Scott')
81
+ # results = query.execute
82
+ # puts "Found #{results.size} commits"
83
+ # results.each do |commit|
84
+ # # ...
85
+ # end
86
+ #
87
+ # @return [Git::Log::Result] an object containing the log results
88
+ #
89
+ def execute
90
+ run_log_if_dirty
91
+ Result.new(@commits)
92
+ end
93
+
94
+ # @!group Deprecated Enumerable Interface
95
+
96
+ # @deprecated Use {#execute} and call `each` on the result.
97
+ def each(&)
98
+ Git::Deprecation.warn(
99
+ 'Calling Git::Log#each is deprecated. Call #execute and then #each on the result object.'
100
+ )
101
+ run_log_if_dirty
102
+ @commits.each(&)
103
+ end
104
+
105
+ # @deprecated Use {#execute} and call `size` on the result.
80
106
  def size
81
- check_log
82
- @commits.size rescue nil
107
+ Git::Deprecation.warn(
108
+ 'Calling Git::Log#size is deprecated. Call #execute and then #size on the result object.'
109
+ )
110
+ run_log_if_dirty
111
+ @commits&.size
83
112
  end
84
113
 
85
- def each(&block)
86
- check_log
87
- @commits.each(&block)
114
+ # @deprecated Use {#execute} and call `to_s` on the result.
115
+ def to_s
116
+ Git::Deprecation.warn(
117
+ 'Calling Git::Log#to_s is deprecated. Call #execute and then #to_s on the result object.'
118
+ )
119
+ run_log_if_dirty
120
+ @commits&.join("\n")
88
121
  end
89
122
 
123
+ # @deprecated Use {#execute} and call the method on the result.
90
124
  def first
91
- check_log
92
- @commits.first rescue nil
125
+ Git::Deprecation.warn(
126
+ 'Calling Git::Log#first is deprecated. Call #execute and then #first on the result object.'
127
+ )
128
+ run_log_if_dirty
129
+ @commits&.first
93
130
  end
94
131
 
132
+ # @deprecated Use {#execute} and call the method on the result.
95
133
  def last
96
- check_log
97
- @commits.last rescue nil
134
+ Git::Deprecation.warn(
135
+ 'Calling Git::Log#last is deprecated. Call #execute and then #last on the result object.'
136
+ )
137
+ run_log_if_dirty
138
+ @commits&.last
98
139
  end
99
140
 
141
+ # @deprecated Use {#execute} and call the method on the result.
100
142
  def [](index)
101
- check_log
102
- @commits[index] rescue nil
143
+ Git::Deprecation.warn(
144
+ 'Calling Git::Log#[] is deprecated. Call #execute and then #[] on the result object.'
145
+ )
146
+ run_log_if_dirty
147
+ @commits&.[](index)
103
148
  end
104
149
 
150
+ # @!endgroup
105
151
 
106
152
  private
107
153
 
108
- def dirty_log
109
- @dirty_flag = true
110
- end
111
-
112
- def check_log
113
- if @dirty_flag
114
- run_log
115
- @dirty_flag = false
116
- end
117
- end
118
-
119
- # actually run the 'git log' command
120
- def run_log
121
- log = @base.lib.full_log_commits(
122
- count: @count, all: @all, object: @object, path_limiter: @path, since: @since,
123
- author: @author, grep: @grep, skip: @skip, until: @until, between: @between,
124
- cherry: @cherry
125
- )
126
- @commits = log.map { |c| Git::Object::Commit.new(@base, c['sha'], c) }
127
- end
154
+ def set_option(key, value)
155
+ @dirty = true
156
+ @options[key] = value
157
+ self
158
+ end
128
159
 
129
- end
160
+ def run_log_if_dirty
161
+ return unless @dirty
130
162
 
163
+ log_data = @base.lib.full_log_commits(@options)
164
+ @commits = log_data.map { |c| Git::Object::Commit.new(@base, c['sha'], c) }
165
+ @dirty = false
166
+ end
167
+ end
131
168
  end