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.
- checksums.yaml +4 -4
- data/.commitlintrc.yml +38 -0
- data/.github/copilot-instructions.md +2733 -0
- data/.github/pull_request_template.md +17 -0
- data/.github/workflows/continuous_integration.yml +92 -21
- data/.github/workflows/enforce_conventional_commits.yml +29 -0
- data/.github/workflows/experimental_continuous_integration.yml +59 -0
- data/.github/workflows/release.yml +53 -0
- data/.gitignore +5 -0
- data/.husky/commit-msg +1 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +55 -0
- data/.rubocop_todo.yml +12 -0
- data/.yardopts +4 -1
- data/AI_POLICY.md +24 -0
- data/CHANGELOG.md +501 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +323 -102
- data/GOVERNANCE.md +106 -0
- data/LICENSE +1 -1
- data/MAINTAINERS.md +17 -4
- data/README.md +575 -246
- data/Rakefile +13 -55
- data/git.gemspec +36 -30
- data/lib/git/args_builder.rb +111 -0
- data/lib/git/author.rb +9 -7
- data/lib/git/base.rb +602 -173
- data/lib/git/branch.rb +318 -38
- data/lib/git/branches.rb +21 -24
- data/lib/git/command_line.rb +330 -0
- data/lib/git/command_line_result.rb +9 -3
- data/lib/git/config.rb +10 -6
- data/lib/git/diff.rb +149 -81
- data/lib/git/diff_path_status.rb +46 -0
- data/lib/git/diff_stats.rb +59 -0
- data/lib/git/errors.rb +212 -0
- data/lib/git/escaped_path.rb +2 -2
- data/lib/git/fsck_object.rb +48 -0
- data/lib/git/fsck_result.rb +121 -0
- data/lib/git/index.rb +2 -1
- data/lib/git/lib.rb +1648 -643
- data/lib/git/log.rb +143 -106
- data/lib/git/object.rb +151 -125
- data/lib/git/path.rb +23 -16
- data/lib/git/remote.rb +5 -4
- data/lib/git/repository.rb +2 -2
- data/lib/git/stash.rb +11 -12
- data/lib/git/stashes.rb +16 -15
- data/lib/git/status.rb +104 -143
- data/lib/git/url.rb +3 -3
- data/lib/git/version.rb +3 -1
- data/lib/git/working_directory.rb +2 -0
- data/lib/git/worktree.rb +6 -5
- data/lib/git/worktrees.rb +6 -6
- data/lib/git.rb +131 -28
- data/package.json +10 -0
- data/redesign/1_architecture_existing.md +66 -0
- data/redesign/2_architecture_redesign.md +130 -0
- data/redesign/3_architecture_implementation.md +138 -0
- data/redesign/index.md +34 -0
- data/release-please-config.json +36 -0
- data/tasks/gem_tasks.rake +10 -0
- data/tasks/rubocop.rake +12 -0
- data/tasks/test.rake +13 -0
- data/tasks/test_gem.rake +12 -0
- data/tasks/yard.rake +23 -0
- metadata +114 -37
- data/.github/stale.yml +0 -25
- data/Dockerfile.changelog-rs +0 -12
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- data/RELEASING.md +0 -70
- data/lib/git/base/factory.rb +0 -99
- data/lib/git/failed_error.rb +0 -53
- data/lib/git/git_execute_error.rb +0 -7
- data/lib/git/signaled_error.rb +0 -50
- /data/{ISSUE_TEMPLATE.md → .github/issue_template.md} +0 -0
data/lib/git/object.rb
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'git/author'
|
|
4
|
+
require 'git/diff'
|
|
5
|
+
require 'git/errors'
|
|
6
|
+
require 'git/log'
|
|
7
|
+
|
|
1
8
|
module Git
|
|
2
|
-
|
|
3
|
-
class GitTagNameDoesNotExist< StandardError
|
|
4
|
-
end
|
|
5
|
-
|
|
6
9
|
# represents a git object
|
|
7
10
|
class Object
|
|
8
|
-
|
|
11
|
+
# A base class for all Git objects
|
|
9
12
|
class AbstractObject
|
|
10
13
|
attr_accessor :objectish, :type, :mode
|
|
11
14
|
|
|
12
15
|
attr_writer :size
|
|
13
|
-
|
|
16
|
+
|
|
14
17
|
def initialize(base, objectish)
|
|
15
18
|
@base = base
|
|
16
19
|
@objectish = objectish.to_s
|
|
@@ -21,140 +24,133 @@ module Git
|
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def sha
|
|
24
|
-
@sha ||= @base.lib.
|
|
27
|
+
@sha ||= @base.lib.rev_parse(@objectish)
|
|
25
28
|
end
|
|
26
|
-
|
|
29
|
+
|
|
27
30
|
def size
|
|
28
|
-
@size ||= @base.lib.
|
|
31
|
+
@size ||= @base.lib.cat_file_size(@objectish)
|
|
29
32
|
end
|
|
30
|
-
|
|
33
|
+
|
|
31
34
|
# Get the object's contents.
|
|
32
35
|
# If no block is given, the contents are cached in memory and returned as a string.
|
|
33
36
|
# If a block is given, it yields an IO object (via IO::popen) which could be used to
|
|
34
37
|
# read a large file in chunks.
|
|
35
38
|
#
|
|
36
39
|
# Use this for large files so that they are not held in memory.
|
|
37
|
-
def contents(&
|
|
40
|
+
def contents(&)
|
|
38
41
|
if block_given?
|
|
39
|
-
@base.lib.
|
|
42
|
+
@base.lib.cat_file_contents(@objectish, &)
|
|
40
43
|
else
|
|
41
|
-
@contents ||= @base.lib.
|
|
44
|
+
@contents ||= @base.lib.cat_file_contents(@objectish)
|
|
42
45
|
end
|
|
43
46
|
end
|
|
44
|
-
|
|
47
|
+
|
|
45
48
|
def contents_array
|
|
46
|
-
|
|
49
|
+
contents.split("\n")
|
|
47
50
|
end
|
|
48
|
-
|
|
51
|
+
|
|
49
52
|
def to_s
|
|
50
53
|
@objectish
|
|
51
54
|
end
|
|
52
|
-
|
|
55
|
+
|
|
53
56
|
def grep(string, path_limiter = nil, opts = {})
|
|
54
|
-
opts = {:
|
|
57
|
+
opts = { object: sha, path_limiter: path_limiter }.merge(opts)
|
|
55
58
|
@base.lib.grep(string, opts)
|
|
56
59
|
end
|
|
57
|
-
|
|
60
|
+
|
|
58
61
|
def diff(objectish)
|
|
59
62
|
Git::Diff.new(@base, @objectish, objectish)
|
|
60
63
|
end
|
|
61
|
-
|
|
64
|
+
|
|
62
65
|
def log(count = 30)
|
|
63
66
|
Git::Log.new(@base, count).object(@objectish)
|
|
64
67
|
end
|
|
65
|
-
|
|
68
|
+
|
|
66
69
|
# creates an archive of this object (tree)
|
|
67
70
|
def archive(file = nil, opts = {})
|
|
68
71
|
@base.lib.archive(@objectish, file, opts)
|
|
69
72
|
end
|
|
70
|
-
|
|
71
|
-
def tree?; false; end
|
|
72
|
-
|
|
73
|
-
def blob?; false; end
|
|
74
|
-
|
|
75
|
-
def commit?; false; end
|
|
76
73
|
|
|
77
|
-
def
|
|
78
|
-
|
|
74
|
+
def tree? = false
|
|
75
|
+
|
|
76
|
+
def blob? = false
|
|
77
|
+
|
|
78
|
+
def commit? = false
|
|
79
|
+
|
|
80
|
+
def tag? = false
|
|
79
81
|
end
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
|
|
83
|
+
# A Git blob object
|
|
82
84
|
class Blob < AbstractObject
|
|
83
|
-
|
|
84
85
|
def initialize(base, sha, mode = nil)
|
|
85
86
|
super(base, sha)
|
|
86
87
|
@mode = mode
|
|
87
88
|
end
|
|
88
|
-
|
|
89
|
+
|
|
89
90
|
def blob?
|
|
90
91
|
true
|
|
91
92
|
end
|
|
92
|
-
|
|
93
93
|
end
|
|
94
|
-
|
|
94
|
+
|
|
95
|
+
# A Git tree object
|
|
95
96
|
class Tree < AbstractObject
|
|
96
|
-
|
|
97
97
|
def initialize(base, sha, mode = nil)
|
|
98
98
|
super(base, sha)
|
|
99
99
|
@mode = mode
|
|
100
100
|
@trees = nil
|
|
101
101
|
@blobs = nil
|
|
102
102
|
end
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
def children
|
|
105
105
|
blobs.merge(subtrees)
|
|
106
106
|
end
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
def blobs
|
|
109
109
|
@blobs ||= check_tree[:blobs]
|
|
110
110
|
end
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
alias files blobs
|
|
112
|
+
|
|
113
113
|
def trees
|
|
114
114
|
@trees ||= check_tree[:trees]
|
|
115
115
|
end
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
alias subtrees trees
|
|
117
|
+
alias subdirectories trees
|
|
118
|
+
|
|
119
119
|
def full_tree
|
|
120
120
|
@base.lib.full_tree(@objectish)
|
|
121
121
|
end
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
def depth
|
|
124
124
|
@base.lib.tree_depth(@objectish)
|
|
125
125
|
end
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
def tree?
|
|
128
128
|
true
|
|
129
129
|
end
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
private
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
{
|
|
149
|
-
:trees => @trees,
|
|
150
|
-
:blobs => @blobs
|
|
151
|
-
}
|
|
133
|
+
# actually run the git command
|
|
134
|
+
def check_tree
|
|
135
|
+
@trees = {}
|
|
136
|
+
@blobs = {}
|
|
137
|
+
|
|
138
|
+
data = @base.lib.ls_tree(@objectish)
|
|
139
|
+
|
|
140
|
+
data['tree'].each do |key, tree|
|
|
141
|
+
@trees[key] = Git::Object::Tree.new(@base, tree[:sha], tree[:mode])
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
data['blob'].each do |key, blob|
|
|
145
|
+
@blobs[key] = Git::Object::Blob.new(@base, blob[:sha], blob[:mode])
|
|
152
146
|
end
|
|
153
|
-
|
|
147
|
+
|
|
148
|
+
{ trees: @trees, blobs: @blobs }
|
|
149
|
+
end
|
|
154
150
|
end
|
|
155
|
-
|
|
151
|
+
|
|
152
|
+
# A Git commit object
|
|
156
153
|
class Commit < AbstractObject
|
|
157
|
-
|
|
158
154
|
def initialize(base, sha, init = nil)
|
|
159
155
|
super(base, sha)
|
|
160
156
|
@tree = nil
|
|
@@ -162,111 +158,143 @@ module Git
|
|
|
162
158
|
@author = nil
|
|
163
159
|
@committer = nil
|
|
164
160
|
@message = nil
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
161
|
+
return unless init
|
|
162
|
+
|
|
163
|
+
from_data(init)
|
|
168
164
|
end
|
|
169
|
-
|
|
165
|
+
|
|
170
166
|
def message
|
|
171
167
|
check_commit
|
|
172
168
|
@message
|
|
173
169
|
end
|
|
174
|
-
|
|
170
|
+
|
|
175
171
|
def name
|
|
176
|
-
@base.lib.
|
|
172
|
+
@base.lib.name_rev(sha)
|
|
177
173
|
end
|
|
178
|
-
|
|
174
|
+
|
|
179
175
|
def gtree
|
|
180
176
|
check_commit
|
|
181
177
|
Tree.new(@base, @tree)
|
|
182
178
|
end
|
|
183
|
-
|
|
179
|
+
|
|
184
180
|
def parent
|
|
185
181
|
parents.first
|
|
186
182
|
end
|
|
187
|
-
|
|
183
|
+
|
|
188
184
|
# array of all parent commits
|
|
189
185
|
def parents
|
|
190
186
|
check_commit
|
|
191
|
-
@parents
|
|
187
|
+
@parents
|
|
192
188
|
end
|
|
193
|
-
|
|
189
|
+
|
|
194
190
|
# git author
|
|
195
|
-
def author
|
|
191
|
+
def author
|
|
196
192
|
check_commit
|
|
197
193
|
@author
|
|
198
194
|
end
|
|
199
|
-
|
|
195
|
+
|
|
200
196
|
def author_date
|
|
201
197
|
author.date
|
|
202
198
|
end
|
|
203
|
-
|
|
199
|
+
|
|
204
200
|
# git author
|
|
205
201
|
def committer
|
|
206
202
|
check_commit
|
|
207
203
|
@committer
|
|
208
204
|
end
|
|
209
|
-
|
|
210
|
-
def committer_date
|
|
205
|
+
|
|
206
|
+
def committer_date
|
|
211
207
|
committer.date
|
|
212
208
|
end
|
|
213
|
-
|
|
209
|
+
alias date committer_date
|
|
214
210
|
|
|
215
211
|
def diff_parent
|
|
216
212
|
diff(parent)
|
|
217
213
|
end
|
|
218
|
-
|
|
219
|
-
def set_commit(data)
|
|
214
|
+
|
|
215
|
+
def set_commit(data) # rubocop:disable Naming/AccessorMethodName
|
|
216
|
+
Git::Deprecation.warn(
|
|
217
|
+
'Git::Object::Commit#set_commit is deprecated and will be removed in a future version. ' \
|
|
218
|
+
'Use #from_data instead.'
|
|
219
|
+
)
|
|
220
|
+
from_data(data)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def from_data(data)
|
|
220
224
|
@sha ||= data['sha']
|
|
221
225
|
@committer = Git::Author.new(data['committer'])
|
|
222
226
|
@author = Git::Author.new(data['author'])
|
|
223
227
|
@tree = Git::Object::Tree.new(@base, data['tree'])
|
|
224
|
-
@parents = data['parent'].map{ |sha| Git::Object::Commit.new(@base, sha) }
|
|
228
|
+
@parents = data['parent'].map { |sha| Git::Object::Commit.new(@base, sha) }
|
|
225
229
|
@message = data['message'].chomp
|
|
226
230
|
end
|
|
227
|
-
|
|
231
|
+
|
|
228
232
|
def commit?
|
|
229
233
|
true
|
|
230
234
|
end
|
|
231
235
|
|
|
232
236
|
private
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
237
|
+
|
|
238
|
+
# see if this object has been initialized and do so if not
|
|
239
|
+
def check_commit
|
|
240
|
+
return if @tree
|
|
241
|
+
|
|
242
|
+
data = @base.lib.cat_file_commit(@objectish)
|
|
243
|
+
from_data(data)
|
|
244
|
+
end
|
|
242
245
|
end
|
|
243
|
-
|
|
246
|
+
|
|
247
|
+
# A Git tag object
|
|
248
|
+
#
|
|
249
|
+
# This class represents a tag in Git, which can be either annotated or lightweight.
|
|
250
|
+
#
|
|
251
|
+
# Annotated tags contain additional metadata such as the tagger's name, email, and
|
|
252
|
+
# the date when the tag was created, along with a message.
|
|
253
|
+
#
|
|
254
|
+
# TODO: Annotated tags are not objects
|
|
255
|
+
#
|
|
244
256
|
class Tag < AbstractObject
|
|
245
257
|
attr_accessor :name
|
|
246
|
-
|
|
247
|
-
|
|
258
|
+
|
|
259
|
+
# @overload initialize(base, name)
|
|
260
|
+
# @param base [Git::Base] The Git base object
|
|
261
|
+
# @param name [String] The name of the tag
|
|
262
|
+
#
|
|
263
|
+
# @overload initialize(base, sha, name)
|
|
264
|
+
# @param base [Git::Base] The Git base object
|
|
265
|
+
# @param sha [String] The SHA of the tag object
|
|
266
|
+
# @param name [String] The name of the tag
|
|
267
|
+
#
|
|
268
|
+
def initialize(base, sha, name = nil)
|
|
269
|
+
if name.nil?
|
|
270
|
+
name = sha
|
|
271
|
+
sha = base.lib.tag_sha(name)
|
|
272
|
+
raise Git::UnexpectedResultError, "Tag '#{name}' does not exist." if sha == ''
|
|
273
|
+
end
|
|
274
|
+
|
|
248
275
|
super(base, sha)
|
|
276
|
+
|
|
249
277
|
@name = name
|
|
250
278
|
@annotated = nil
|
|
251
279
|
@loaded = false
|
|
252
280
|
end
|
|
253
281
|
|
|
254
282
|
def annotated?
|
|
255
|
-
@annotated
|
|
283
|
+
@annotated = @annotated.nil? ? (@base.lib.cat_file_type(name) == 'tag') : @annotated
|
|
256
284
|
end
|
|
257
285
|
|
|
258
286
|
def message
|
|
259
|
-
check_tag
|
|
260
|
-
|
|
287
|
+
check_tag
|
|
288
|
+
@message
|
|
261
289
|
end
|
|
262
|
-
|
|
290
|
+
|
|
263
291
|
def tag?
|
|
264
292
|
true
|
|
265
293
|
end
|
|
266
294
|
|
|
267
295
|
def tagger
|
|
268
|
-
check_tag
|
|
269
|
-
|
|
296
|
+
check_tag
|
|
297
|
+
@tagger
|
|
270
298
|
end
|
|
271
299
|
|
|
272
300
|
private
|
|
@@ -274,39 +302,37 @@ module Git
|
|
|
274
302
|
def check_tag
|
|
275
303
|
return if @loaded
|
|
276
304
|
|
|
277
|
-
if
|
|
278
|
-
|
|
279
|
-
else
|
|
280
|
-
tdata = @base.lib.tag_data(@name)
|
|
305
|
+
if annotated?
|
|
306
|
+
tdata = @base.lib.cat_file_tag(@name)
|
|
281
307
|
@message = tdata['message'].chomp
|
|
282
308
|
@tagger = Git::Author.new(tdata['tagger'])
|
|
309
|
+
else
|
|
310
|
+
@message = @tagger = nil
|
|
283
311
|
end
|
|
284
312
|
|
|
285
313
|
@loaded = true
|
|
286
314
|
end
|
|
287
|
-
|
|
288
315
|
end
|
|
289
|
-
|
|
316
|
+
|
|
290
317
|
# if we're calling this, we don't know what type it is yet
|
|
291
318
|
# so this is our little factory method
|
|
292
|
-
def self.new(base, objectish, type = nil, is_tag = false)
|
|
293
|
-
if is_tag
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
end
|
|
298
|
-
return Git::Object::Tag.new(base, sha, objectish)
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
type ||= base.lib.object_type(objectish)
|
|
319
|
+
def self.new(base, objectish, type = nil, is_tag = false) # rubocop:disable Style/OptionalBooleanParameter
|
|
320
|
+
return new_tag(base, objectish) if is_tag
|
|
321
|
+
|
|
322
|
+
type ||= base.lib.cat_file_type(objectish)
|
|
323
|
+
# TODO: why not handle tag case here too?
|
|
302
324
|
klass =
|
|
303
325
|
case type
|
|
304
|
-
when /blob/ then Blob
|
|
326
|
+
when /blob/ then Blob
|
|
305
327
|
when /commit/ then Commit
|
|
306
328
|
when /tree/ then Tree
|
|
307
329
|
end
|
|
308
330
|
klass.new(base, objectish)
|
|
309
331
|
end
|
|
310
|
-
|
|
332
|
+
|
|
333
|
+
private_class_method def self.new_tag(base, objectish)
|
|
334
|
+
Git::Deprecation.warn('Git::Object.new with is_tag argument is deprecated. Use Git::Object::Tag.new instead.')
|
|
335
|
+
Git::Object::Tag.new(base, objectish)
|
|
336
|
+
end
|
|
311
337
|
end
|
|
312
338
|
end
|
data/lib/git/path.rb
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Git
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
# A base class that represents and validates a filesystem path
|
|
5
|
+
#
|
|
6
|
+
# Use for tracking things relevant to a Git repository, such as the working
|
|
7
|
+
# directory or index file.
|
|
8
|
+
#
|
|
9
|
+
class Path
|
|
10
|
+
def path
|
|
11
|
+
Git::Deprecation.warn(
|
|
12
|
+
'The .path accessor is deprecated and will be removed in v5.0. ' \
|
|
13
|
+
'Use .to_s instead.'
|
|
14
|
+
)
|
|
15
|
+
@path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(path, must_exist: true)
|
|
8
19
|
path = File.expand_path(path)
|
|
9
|
-
|
|
10
|
-
if
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
|
|
20
|
+
|
|
21
|
+
raise ArgumentError, 'path does not exist', [path] if must_exist && !File.exist?(path)
|
|
22
|
+
|
|
14
23
|
@path = path
|
|
15
24
|
end
|
|
16
|
-
|
|
25
|
+
|
|
17
26
|
def readable?
|
|
18
27
|
File.readable?(@path)
|
|
19
28
|
end
|
|
@@ -21,11 +30,9 @@ module Git
|
|
|
21
30
|
def writable?
|
|
22
31
|
File.writable?(@path)
|
|
23
32
|
end
|
|
24
|
-
|
|
33
|
+
|
|
25
34
|
def to_s
|
|
26
35
|
@path
|
|
27
36
|
end
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
|
|
37
|
+
end
|
|
31
38
|
end
|
data/lib/git/remote.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
class Remote < Path
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
3
|
+
module Git
|
|
4
|
+
# A remote in a Git repository
|
|
5
|
+
class Remote
|
|
4
6
|
attr_accessor :name, :url, :fetch_opts
|
|
5
7
|
|
|
6
8
|
def initialize(base, name)
|
|
@@ -11,7 +13,7 @@ module Git
|
|
|
11
13
|
@fetch_opts = config['fetch']
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
def fetch(opts={})
|
|
16
|
+
def fetch(opts = {})
|
|
15
17
|
@base.fetch(@name, opts)
|
|
16
18
|
end
|
|
17
19
|
|
|
@@ -33,6 +35,5 @@ module Git
|
|
|
33
35
|
def to_s
|
|
34
36
|
@name
|
|
35
37
|
end
|
|
36
|
-
|
|
37
38
|
end
|
|
38
39
|
end
|
data/lib/git/repository.rb
CHANGED
data/lib/git/stash.rb
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Git
|
|
4
|
+
# A stash in a Git repository
|
|
2
5
|
class Stash
|
|
3
|
-
|
|
4
|
-
def initialize(base, message, existing=false)
|
|
6
|
+
def initialize(base, message, save: false)
|
|
5
7
|
@base = base
|
|
6
8
|
@message = message
|
|
7
|
-
save unless
|
|
9
|
+
self.save unless save
|
|
8
10
|
end
|
|
9
|
-
|
|
11
|
+
|
|
10
12
|
def save
|
|
11
13
|
@saved = @base.lib.stash_save(@message)
|
|
12
14
|
end
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
def saved?
|
|
15
17
|
@saved
|
|
16
18
|
end
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
|
|
19
|
+
|
|
20
|
+
attr_reader :message
|
|
21
|
+
|
|
22
22
|
def to_s
|
|
23
23
|
message
|
|
24
24
|
end
|
|
25
|
-
|
|
26
25
|
end
|
|
27
|
-
end
|
|
26
|
+
end
|
data/lib/git/stashes.rb
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Git
|
|
2
|
-
|
|
3
4
|
# object that holds all the available stashes
|
|
4
5
|
class Stashes
|
|
5
6
|
include Enumerable
|
|
6
|
-
|
|
7
|
+
|
|
7
8
|
def initialize(base)
|
|
8
9
|
@stashes = []
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
@base = base
|
|
11
|
-
|
|
12
|
-
@base.lib.stashes_all.each do |
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
@base.lib.stashes_all.each do |indexed_message|
|
|
14
|
+
_index, message = indexed_message
|
|
15
|
+
@stashes.unshift(Git::Stash.new(@base, message, save: true))
|
|
14
16
|
end
|
|
15
17
|
end
|
|
16
18
|
|
|
@@ -24,16 +26,16 @@ module Git
|
|
|
24
26
|
def all
|
|
25
27
|
@base.lib.stashes_all
|
|
26
28
|
end
|
|
27
|
-
|
|
29
|
+
|
|
28
30
|
def save(message)
|
|
29
31
|
s = Git::Stash.new(@base, message)
|
|
30
32
|
@stashes.unshift(s) if s.saved?
|
|
31
33
|
end
|
|
32
|
-
|
|
33
|
-
def apply(index=nil)
|
|
34
|
+
|
|
35
|
+
def apply(index = nil)
|
|
34
36
|
@base.lib.stash_apply(index)
|
|
35
37
|
end
|
|
36
|
-
|
|
38
|
+
|
|
37
39
|
def clear
|
|
38
40
|
@base.lib.stash_clear
|
|
39
41
|
@stashes = []
|
|
@@ -42,14 +44,13 @@ module Git
|
|
|
42
44
|
def size
|
|
43
45
|
@stashes.size
|
|
44
46
|
end
|
|
45
|
-
|
|
46
|
-
def each(&
|
|
47
|
-
@stashes.each(&
|
|
47
|
+
|
|
48
|
+
def each(&)
|
|
49
|
+
@stashes.each(&)
|
|
48
50
|
end
|
|
49
|
-
|
|
51
|
+
|
|
50
52
|
def [](index)
|
|
51
53
|
@stashes[index.to_i]
|
|
52
54
|
end
|
|
53
|
-
|
|
54
55
|
end
|
|
55
56
|
end
|