git 1.19.1 → 2.1.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/pull_request_template.md +8 -0
- data/.github/workflows/continuous_integration.yml +14 -20
- data/.github/workflows/experimental_continuous_integration.yml +43 -0
- data/CHANGELOG.md +88 -0
- data/CONTRIBUTING.md +22 -67
- data/README.md +166 -52
- data/RELEASING.md +49 -34
- data/git.gemspec +8 -8
- data/lib/git/base.rb +173 -47
- data/lib/git/command_line.rb +377 -0
- data/lib/git/config.rb +5 -1
- data/lib/git/errors.rb +206 -0
- data/lib/git/escaped_path.rb +1 -1
- data/lib/git/lib.rb +244 -177
- data/lib/git/log.rb +65 -4
- data/lib/git/object.rb +69 -67
- data/lib/git/status.rb +132 -24
- data/lib/git/version.rb +1 -1
- data/lib/git.rb +8 -7
- metadata +41 -30
- data/.github/stale.yml +0 -25
- data/Dockerfile.changelog-rs +0 -12
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- 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/log.rb
CHANGED
@@ -1,15 +1,76 @@
|
|
1
1
|
module Git
|
2
2
|
|
3
|
-
#
|
3
|
+
# Return the last n commits that match the specified criteria
|
4
|
+
#
|
5
|
+
# @example The last (default number) of commits
|
6
|
+
# git = Git.open('.')
|
7
|
+
# Git::Log.new(git) #=> Enumerable of the last 30 commits
|
8
|
+
#
|
9
|
+
# @example The last n commits
|
10
|
+
# Git::Log.new(git).max_commits(50) #=> Enumerable of last 50 commits
|
11
|
+
#
|
12
|
+
# @example All commits returned by `git log`
|
13
|
+
# Git::Log.new(git).max_count(:all) #=> Enumerable of all commits
|
14
|
+
#
|
15
|
+
# @example All commits that match complex criteria
|
16
|
+
# Git::Log.new(git)
|
17
|
+
# .max_count(:all)
|
18
|
+
# .object('README.md')
|
19
|
+
# .since('10 years ago')
|
20
|
+
# .between('v1.0.7', 'HEAD')
|
21
|
+
#
|
22
|
+
# @api public
|
23
|
+
#
|
4
24
|
class Log
|
5
25
|
include Enumerable
|
6
26
|
|
7
|
-
|
27
|
+
# Create a new Git::Log object
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# git = Git.open('.')
|
31
|
+
# Git::Log.new(git)
|
32
|
+
#
|
33
|
+
# @param base [Git::Base] the git repository object
|
34
|
+
# @param max_count [Integer, Symbol, nil] the number of commits to return, or
|
35
|
+
# `:all` or `nil` to return all
|
36
|
+
#
|
37
|
+
# Passing max_count to {#initialize} is equivalent to calling {#max_count} on the object.
|
38
|
+
#
|
39
|
+
def initialize(base, max_count = 30)
|
8
40
|
dirty_log
|
9
41
|
@base = base
|
10
|
-
|
42
|
+
max_count(max_count)
|
43
|
+
end
|
44
|
+
|
45
|
+
# The maximum number of commits to return
|
46
|
+
#
|
47
|
+
# @example All commits returned by `git log`
|
48
|
+
# git = Git.open('.')
|
49
|
+
# Git::Log.new(git).max_count(:all)
|
50
|
+
#
|
51
|
+
# @param num_or_all [Integer, Symbol, nil] the number of commits to return, or
|
52
|
+
# `:all` or `nil` to return all
|
53
|
+
#
|
54
|
+
# @return [self]
|
55
|
+
#
|
56
|
+
def max_count(num_or_all)
|
57
|
+
dirty_log
|
58
|
+
@max_count = (num_or_all == :all) ? nil : num_or_all
|
59
|
+
self
|
11
60
|
end
|
12
61
|
|
62
|
+
# Adds the --all flag to the git log command
|
63
|
+
#
|
64
|
+
# This asks for the logs of all refs (basically all commits reachable by HEAD,
|
65
|
+
# branches, and tags). This does not control the maximum number of commits
|
66
|
+
# returned. To control how many commits are returned, call {#max_count}.
|
67
|
+
#
|
68
|
+
# @example Return the last 50 commits reachable by all refs
|
69
|
+
# git = Git.open('.')
|
70
|
+
# Git::Log.new(git).max_count(50).all
|
71
|
+
#
|
72
|
+
# @return [self]
|
73
|
+
#
|
13
74
|
def all
|
14
75
|
dirty_log
|
15
76
|
@all = true
|
@@ -119,7 +180,7 @@ module Git
|
|
119
180
|
# actually run the 'git log' command
|
120
181
|
def run_log
|
121
182
|
log = @base.lib.full_log_commits(
|
122
|
-
count: @
|
183
|
+
count: @max_count, all: @all, object: @object, path_limiter: @path, since: @since,
|
123
184
|
author: @author, grep: @grep, skip: @skip, until: @until, between: @between,
|
124
185
|
cherry: @cherry
|
125
186
|
)
|
data/lib/git/object.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
+
require 'git/author'
|
2
|
+
require 'git/diff'
|
3
|
+
require 'git/errors'
|
4
|
+
require 'git/log'
|
5
|
+
|
1
6
|
module Git
|
2
|
-
|
3
|
-
class GitTagNameDoesNotExist< StandardError
|
4
|
-
end
|
5
|
-
|
7
|
+
|
6
8
|
# represents a git object
|
7
9
|
class Object
|
8
|
-
|
10
|
+
|
9
11
|
class AbstractObject
|
10
12
|
attr_accessor :objectish, :type, :mode
|
11
13
|
|
12
14
|
attr_writer :size
|
13
|
-
|
15
|
+
|
14
16
|
def initialize(base, objectish)
|
15
17
|
@base = base
|
16
18
|
@objectish = objectish.to_s
|
@@ -23,11 +25,11 @@ module Git
|
|
23
25
|
def sha
|
24
26
|
@sha ||= @base.lib.revparse(@objectish)
|
25
27
|
end
|
26
|
-
|
28
|
+
|
27
29
|
def size
|
28
30
|
@size ||= @base.lib.object_size(@objectish)
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
# Get the object's contents.
|
32
34
|
# If no block is given, the contents are cached in memory and returned as a string.
|
33
35
|
# If a block is given, it yields an IO object (via IO::popen) which could be used to
|
@@ -41,108 +43,108 @@ module Git
|
|
41
43
|
@contents ||= @base.lib.object_contents(@objectish)
|
42
44
|
end
|
43
45
|
end
|
44
|
-
|
46
|
+
|
45
47
|
def contents_array
|
46
48
|
self.contents.split("\n")
|
47
49
|
end
|
48
|
-
|
50
|
+
|
49
51
|
def to_s
|
50
52
|
@objectish
|
51
53
|
end
|
52
|
-
|
54
|
+
|
53
55
|
def grep(string, path_limiter = nil, opts = {})
|
54
56
|
opts = {:object => sha, :path_limiter => path_limiter}.merge(opts)
|
55
57
|
@base.lib.grep(string, opts)
|
56
58
|
end
|
57
|
-
|
59
|
+
|
58
60
|
def diff(objectish)
|
59
61
|
Git::Diff.new(@base, @objectish, objectish)
|
60
62
|
end
|
61
|
-
|
63
|
+
|
62
64
|
def log(count = 30)
|
63
65
|
Git::Log.new(@base, count).object(@objectish)
|
64
66
|
end
|
65
|
-
|
67
|
+
|
66
68
|
# creates an archive of this object (tree)
|
67
69
|
def archive(file = nil, opts = {})
|
68
70
|
@base.lib.archive(@objectish, file, opts)
|
69
71
|
end
|
70
|
-
|
72
|
+
|
71
73
|
def tree?; false; end
|
72
|
-
|
74
|
+
|
73
75
|
def blob?; false; end
|
74
|
-
|
76
|
+
|
75
77
|
def commit?; false; end
|
76
78
|
|
77
79
|
def tag?; false; end
|
78
|
-
|
80
|
+
|
79
81
|
end
|
80
|
-
|
81
|
-
|
82
|
+
|
83
|
+
|
82
84
|
class Blob < AbstractObject
|
83
|
-
|
85
|
+
|
84
86
|
def initialize(base, sha, mode = nil)
|
85
87
|
super(base, sha)
|
86
88
|
@mode = mode
|
87
89
|
end
|
88
|
-
|
90
|
+
|
89
91
|
def blob?
|
90
92
|
true
|
91
93
|
end
|
92
94
|
|
93
95
|
end
|
94
|
-
|
96
|
+
|
95
97
|
class Tree < AbstractObject
|
96
|
-
|
98
|
+
|
97
99
|
def initialize(base, sha, mode = nil)
|
98
100
|
super(base, sha)
|
99
101
|
@mode = mode
|
100
102
|
@trees = nil
|
101
103
|
@blobs = nil
|
102
104
|
end
|
103
|
-
|
105
|
+
|
104
106
|
def children
|
105
107
|
blobs.merge(subtrees)
|
106
108
|
end
|
107
|
-
|
109
|
+
|
108
110
|
def blobs
|
109
111
|
@blobs ||= check_tree[:blobs]
|
110
112
|
end
|
111
113
|
alias_method :files, :blobs
|
112
|
-
|
114
|
+
|
113
115
|
def trees
|
114
116
|
@trees ||= check_tree[:trees]
|
115
117
|
end
|
116
118
|
alias_method :subtrees, :trees
|
117
119
|
alias_method :subdirectories, :trees
|
118
|
-
|
120
|
+
|
119
121
|
def full_tree
|
120
122
|
@base.lib.full_tree(@objectish)
|
121
123
|
end
|
122
|
-
|
124
|
+
|
123
125
|
def depth
|
124
126
|
@base.lib.tree_depth(@objectish)
|
125
127
|
end
|
126
|
-
|
128
|
+
|
127
129
|
def tree?
|
128
130
|
true
|
129
131
|
end
|
130
|
-
|
132
|
+
|
131
133
|
private
|
132
134
|
|
133
135
|
# actually run the git command
|
134
136
|
def check_tree
|
135
137
|
@trees = {}
|
136
138
|
@blobs = {}
|
137
|
-
|
139
|
+
|
138
140
|
data = @base.lib.ls_tree(@objectish)
|
139
141
|
|
140
|
-
data['tree'].each do |key, tree|
|
141
|
-
@trees[key] = Git::Object::Tree.new(@base, tree[:sha], tree[:mode])
|
142
|
+
data['tree'].each do |key, tree|
|
143
|
+
@trees[key] = Git::Object::Tree.new(@base, tree[:sha], tree[:mode])
|
142
144
|
end
|
143
|
-
|
144
|
-
data['blob'].each do |key, blob|
|
145
|
-
@blobs[key] = Git::Object::Blob.new(@base, blob[:sha], blob[:mode])
|
145
|
+
|
146
|
+
data['blob'].each do |key, blob|
|
147
|
+
@blobs[key] = Git::Object::Blob.new(@base, blob[:sha], blob[:mode])
|
146
148
|
end
|
147
149
|
|
148
150
|
{
|
@@ -150,11 +152,11 @@ module Git
|
|
150
152
|
:blobs => @blobs
|
151
153
|
}
|
152
154
|
end
|
153
|
-
|
155
|
+
|
154
156
|
end
|
155
|
-
|
157
|
+
|
156
158
|
class Commit < AbstractObject
|
157
|
-
|
159
|
+
|
158
160
|
def initialize(base, sha, init = nil)
|
159
161
|
super(base, sha)
|
160
162
|
@tree = nil
|
@@ -166,48 +168,48 @@ module Git
|
|
166
168
|
set_commit(init)
|
167
169
|
end
|
168
170
|
end
|
169
|
-
|
171
|
+
|
170
172
|
def message
|
171
173
|
check_commit
|
172
174
|
@message
|
173
175
|
end
|
174
|
-
|
176
|
+
|
175
177
|
def name
|
176
178
|
@base.lib.namerev(sha)
|
177
179
|
end
|
178
|
-
|
180
|
+
|
179
181
|
def gtree
|
180
182
|
check_commit
|
181
183
|
Tree.new(@base, @tree)
|
182
184
|
end
|
183
|
-
|
185
|
+
|
184
186
|
def parent
|
185
187
|
parents.first
|
186
188
|
end
|
187
|
-
|
189
|
+
|
188
190
|
# array of all parent commits
|
189
191
|
def parents
|
190
192
|
check_commit
|
191
|
-
@parents
|
193
|
+
@parents
|
192
194
|
end
|
193
|
-
|
195
|
+
|
194
196
|
# git author
|
195
|
-
def author
|
197
|
+
def author
|
196
198
|
check_commit
|
197
199
|
@author
|
198
200
|
end
|
199
|
-
|
201
|
+
|
200
202
|
def author_date
|
201
203
|
author.date
|
202
204
|
end
|
203
|
-
|
205
|
+
|
204
206
|
# git author
|
205
207
|
def committer
|
206
208
|
check_commit
|
207
209
|
@committer
|
208
210
|
end
|
209
|
-
|
210
|
-
def committer_date
|
211
|
+
|
212
|
+
def committer_date
|
211
213
|
committer.date
|
212
214
|
end
|
213
215
|
alias_method :date, :committer_date
|
@@ -215,7 +217,7 @@ module Git
|
|
215
217
|
def diff_parent
|
216
218
|
diff(parent)
|
217
219
|
end
|
218
|
-
|
220
|
+
|
219
221
|
def set_commit(data)
|
220
222
|
@sha ||= data['sha']
|
221
223
|
@committer = Git::Author.new(data['committer'])
|
@@ -224,26 +226,26 @@ module Git
|
|
224
226
|
@parents = data['parent'].map{ |sha| Git::Object::Commit.new(@base, sha) }
|
225
227
|
@message = data['message'].chomp
|
226
228
|
end
|
227
|
-
|
229
|
+
|
228
230
|
def commit?
|
229
231
|
true
|
230
232
|
end
|
231
233
|
|
232
234
|
private
|
233
|
-
|
235
|
+
|
234
236
|
# see if this object has been initialized and do so if not
|
235
237
|
def check_commit
|
236
238
|
return if @tree
|
237
|
-
|
239
|
+
|
238
240
|
data = @base.lib.commit_data(@objectish)
|
239
241
|
set_commit(data)
|
240
242
|
end
|
241
|
-
|
243
|
+
|
242
244
|
end
|
243
|
-
|
245
|
+
|
244
246
|
class Tag < AbstractObject
|
245
247
|
attr_accessor :name
|
246
|
-
|
248
|
+
|
247
249
|
def initialize(base, sha, name)
|
248
250
|
super(base, sha)
|
249
251
|
@name = name
|
@@ -259,7 +261,7 @@ module Git
|
|
259
261
|
check_tag()
|
260
262
|
return @message
|
261
263
|
end
|
262
|
-
|
264
|
+
|
263
265
|
def tag?
|
264
266
|
true
|
265
267
|
end
|
@@ -274,7 +276,7 @@ module Git
|
|
274
276
|
def check_tag
|
275
277
|
return if @loaded
|
276
278
|
|
277
|
-
if !self.annotated?
|
279
|
+
if !self.annotated?
|
278
280
|
@message = @tagger = nil
|
279
281
|
else
|
280
282
|
tdata = @base.lib.tag_data(@name)
|
@@ -284,29 +286,29 @@ module Git
|
|
284
286
|
|
285
287
|
@loaded = true
|
286
288
|
end
|
287
|
-
|
289
|
+
|
288
290
|
end
|
289
|
-
|
291
|
+
|
290
292
|
# if we're calling this, we don't know what type it is yet
|
291
293
|
# so this is our little factory method
|
292
294
|
def self.new(base, objectish, type = nil, is_tag = false)
|
293
295
|
if is_tag
|
294
296
|
sha = base.lib.tag_sha(objectish)
|
295
297
|
if sha == ''
|
296
|
-
raise Git::
|
298
|
+
raise Git::UnexpectedResultError.new("Tag '#{objectish}' does not exist.")
|
297
299
|
end
|
298
300
|
return Git::Object::Tag.new(base, sha, objectish)
|
299
301
|
end
|
300
|
-
|
302
|
+
|
301
303
|
type ||= base.lib.object_type(objectish)
|
302
304
|
klass =
|
303
305
|
case type
|
304
|
-
when /blob/ then Blob
|
306
|
+
when /blob/ then Blob
|
305
307
|
when /commit/ then Commit
|
306
308
|
when /tree/ then Tree
|
307
309
|
end
|
308
310
|
klass.new(base, objectish)
|
309
311
|
end
|
310
|
-
|
312
|
+
|
311
313
|
end
|
312
314
|
end
|
data/lib/git/status.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
module Git
|
2
|
+
# The status class gets the status of a git repository
|
2
3
|
#
|
3
|
-
#
|
4
|
+
# This identifies which files have been modified, added, or deleted from the
|
5
|
+
# worktree. Untracked files are also identified.
|
6
|
+
#
|
7
|
+
# The Status object is an Enumerable that contains StatusFile objects.
|
8
|
+
#
|
9
|
+
# @api public
|
4
10
|
#
|
5
11
|
class Status
|
6
12
|
include Enumerable
|
@@ -16,7 +22,7 @@ module Git
|
|
16
22
|
#
|
17
23
|
# @return [Enumerable]
|
18
24
|
def changed
|
19
|
-
@files.select { |_k, f| f.type == 'M' }
|
25
|
+
@_changed ||= @files.select { |_k, f| f.type == 'M' }
|
20
26
|
end
|
21
27
|
|
22
28
|
#
|
@@ -28,20 +34,19 @@ module Git
|
|
28
34
|
# changed?('lib/git.rb')
|
29
35
|
# @return [Boolean]
|
30
36
|
def changed?(file)
|
31
|
-
|
37
|
+
case_aware_include?(:changed, :lc_changed, file)
|
32
38
|
end
|
33
39
|
|
34
|
-
#
|
35
40
|
# Returns an Enumerable containing files that have been added.
|
36
41
|
# File path starts at git base directory
|
37
42
|
#
|
38
43
|
# @return [Enumerable]
|
39
44
|
def added
|
40
|
-
@files.select { |_k, f| f.type == 'A' }
|
45
|
+
@_added ||= @files.select { |_k, f| f.type == 'A' }
|
41
46
|
end
|
42
47
|
|
43
|
-
#
|
44
48
|
# Determines whether the given file has been added to the repository
|
49
|
+
#
|
45
50
|
# File path starts at git base directory
|
46
51
|
#
|
47
52
|
# @param file [String] The name of the file.
|
@@ -49,7 +54,7 @@ module Git
|
|
49
54
|
# added?('lib/git.rb')
|
50
55
|
# @return [Boolean]
|
51
56
|
def added?(file)
|
52
|
-
|
57
|
+
case_aware_include?(:added, :lc_added, file)
|
53
58
|
end
|
54
59
|
|
55
60
|
#
|
@@ -58,7 +63,7 @@ module Git
|
|
58
63
|
#
|
59
64
|
# @return [Enumerable]
|
60
65
|
def deleted
|
61
|
-
@files.select { |_k, f| f.type == 'D' }
|
66
|
+
@_deleted ||= @files.select { |_k, f| f.type == 'D' }
|
62
67
|
end
|
63
68
|
|
64
69
|
#
|
@@ -70,7 +75,7 @@ module Git
|
|
70
75
|
# deleted?('lib/git.rb')
|
71
76
|
# @return [Boolean]
|
72
77
|
def deleted?(file)
|
73
|
-
|
78
|
+
case_aware_include?(:deleted, :lc_deleted, file)
|
74
79
|
end
|
75
80
|
|
76
81
|
#
|
@@ -79,7 +84,7 @@ module Git
|
|
79
84
|
#
|
80
85
|
# @return [Enumerable]
|
81
86
|
def untracked
|
82
|
-
@files.select { |_k, f| f.untracked }
|
87
|
+
@_untracked ||= @files.select { |_k, f| f.untracked }
|
83
88
|
end
|
84
89
|
|
85
90
|
#
|
@@ -91,7 +96,7 @@ module Git
|
|
91
96
|
# untracked?('lib/git.rb')
|
92
97
|
# @return [Boolean]
|
93
98
|
def untracked?(file)
|
94
|
-
|
99
|
+
case_aware_include?(:untracked, :lc_untracked, file)
|
95
100
|
end
|
96
101
|
|
97
102
|
def pretty
|
@@ -126,9 +131,63 @@ module Git
|
|
126
131
|
|
127
132
|
# subclass that does heavy lifting
|
128
133
|
class StatusFile
|
129
|
-
|
130
|
-
|
131
|
-
|
134
|
+
# @!attribute [r] path
|
135
|
+
# The path of the file relative to the project root directory
|
136
|
+
# @return [String]
|
137
|
+
attr_accessor :path
|
138
|
+
|
139
|
+
# @!attribute [r] type
|
140
|
+
# The type of change
|
141
|
+
#
|
142
|
+
# * 'M': modified
|
143
|
+
# * 'A': added
|
144
|
+
# * 'D': deleted
|
145
|
+
# * nil: ???
|
146
|
+
#
|
147
|
+
# @return [String]
|
148
|
+
attr_accessor :type
|
149
|
+
|
150
|
+
# @!attribute [r] mode_index
|
151
|
+
# The mode of the file in the index
|
152
|
+
# @return [String]
|
153
|
+
# @example 100644
|
154
|
+
#
|
155
|
+
attr_accessor :mode_index
|
156
|
+
|
157
|
+
# @!attribute [r] mode_repo
|
158
|
+
# The mode of the file in the repo
|
159
|
+
# @return [String]
|
160
|
+
# @example 100644
|
161
|
+
#
|
162
|
+
attr_accessor :mode_repo
|
163
|
+
|
164
|
+
# @!attribute [r] sha_index
|
165
|
+
# The sha of the file in the index
|
166
|
+
# @return [String]
|
167
|
+
# @example 123456
|
168
|
+
#
|
169
|
+
attr_accessor :sha_index
|
170
|
+
|
171
|
+
# @!attribute [r] sha_repo
|
172
|
+
# The sha of the file in the repo
|
173
|
+
# @return [String]
|
174
|
+
# @example 123456
|
175
|
+
attr_accessor :sha_repo
|
176
|
+
|
177
|
+
# @!attribute [r] untracked
|
178
|
+
# Whether the file is untracked
|
179
|
+
# @return [Boolean]
|
180
|
+
attr_accessor :untracked
|
181
|
+
|
182
|
+
# @!attribute [r] stage
|
183
|
+
# The stage of the file
|
184
|
+
#
|
185
|
+
# * '0': the unmerged state
|
186
|
+
# * '1': the common ancestor (or original) version
|
187
|
+
# * '2': "our version" from the current branch head
|
188
|
+
# * '3': "their version" from the other branch head
|
189
|
+
# @return [String]
|
190
|
+
attr_accessor :stage
|
132
191
|
|
133
192
|
def initialize(base, hash)
|
134
193
|
@base = base
|
@@ -158,10 +217,19 @@ module Git
|
|
158
217
|
private
|
159
218
|
|
160
219
|
def construct_status
|
220
|
+
# Lists all files in the index and the worktree
|
221
|
+
# git ls-files --stage
|
222
|
+
# { file => { path: file, mode_index: '100644', sha_index: 'dd4fc23', stage: '0' } }
|
161
223
|
@files = @base.lib.ls_files
|
162
224
|
|
225
|
+
# Lists files in the worktree that are not in the index
|
226
|
+
# Add untracked files to @files
|
163
227
|
fetch_untracked
|
228
|
+
|
229
|
+
# Lists files that are different between the index vs. the worktree
|
164
230
|
fetch_modified
|
231
|
+
|
232
|
+
# Lists files that are different between the repo HEAD vs. the worktree
|
165
233
|
fetch_added
|
166
234
|
|
167
235
|
@files.each do |k, file_hash|
|
@@ -170,28 +238,68 @@ module Git
|
|
170
238
|
end
|
171
239
|
|
172
240
|
def fetch_untracked
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
Dir.glob('**/*', File::FNM_DOTMATCH, base: root_dir) do |file|
|
177
|
-
next if @files[file] || File.directory?(File.join(root_dir, file)) ||
|
178
|
-
ignore.include?(file) || file =~ %r{^.git\/.+}
|
179
|
-
|
241
|
+
# git ls-files --others --exclude-standard, chdir: @git_work_dir)
|
242
|
+
# { file => { path: file, untracked: true } }
|
243
|
+
@base.lib.untracked_files.each do |file|
|
180
244
|
@files[file] = { path: file, untracked: true }
|
181
245
|
end
|
182
246
|
end
|
183
247
|
|
184
248
|
def fetch_modified
|
185
|
-
#
|
249
|
+
# Files changed between the index vs. the worktree
|
250
|
+
# git diff-files
|
251
|
+
# { file => { path: file, type: 'M', mode_index: '100644', mode_repo: '100644', sha_index: '0000000', :sha_repo: '52c6c4e' } }
|
186
252
|
@base.lib.diff_files.each do |path, data|
|
187
253
|
@files[path] ? @files[path].merge!(data) : @files[path] = data
|
188
254
|
end
|
189
255
|
end
|
190
256
|
|
191
257
|
def fetch_added
|
192
|
-
|
258
|
+
unless @base.lib.empty?
|
259
|
+
# Files changed between the repo HEAD vs. the worktree
|
260
|
+
# git diff-index HEAD
|
261
|
+
# { file => { path: file, type: 'M', mode_index: '100644', mode_repo: '100644', sha_index: '0000000', :sha_repo: '52c6c4e' } }
|
193
262
|
@base.lib.diff_index('HEAD').each do |path, data|
|
194
|
-
|
263
|
+
@files[path] ? @files[path].merge!(data) : @files[path] = data
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# It's worth noting that (like git itself) this gem will not behave well if
|
269
|
+
# ignoreCase is set inconsistently with the file-system itself. For details:
|
270
|
+
# https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreignoreCase
|
271
|
+
def ignore_case?
|
272
|
+
return @_ignore_case if defined?(@_ignore_case)
|
273
|
+
@_ignore_case = @base.config('core.ignoreCase') == 'true'
|
274
|
+
rescue Git::FailedError
|
275
|
+
@_ignore_case = false
|
276
|
+
end
|
277
|
+
|
278
|
+
def downcase_keys(hash)
|
279
|
+
hash.map { |k, v| [k.downcase, v] }.to_h
|
280
|
+
end
|
281
|
+
|
282
|
+
def lc_changed
|
283
|
+
@_lc_changed ||= changed.transform_keys(&:downcase)
|
284
|
+
end
|
285
|
+
|
286
|
+
def lc_added
|
287
|
+
@_lc_added ||= added.transform_keys(&:downcase)
|
288
|
+
end
|
289
|
+
|
290
|
+
def lc_deleted
|
291
|
+
@_lc_deleted ||= deleted.transform_keys(&:downcase)
|
292
|
+
end
|
293
|
+
|
294
|
+
def lc_untracked
|
295
|
+
@_lc_untracked ||= untracked.transform_keys(&:downcase)
|
296
|
+
end
|
297
|
+
|
298
|
+
def case_aware_include?(cased_hash, downcased_hash, file)
|
299
|
+
if ignore_case?
|
300
|
+
send(downcased_hash).include?(file.downcase)
|
301
|
+
else
|
302
|
+
send(cased_hash).include?(file)
|
195
303
|
end
|
196
304
|
end
|
197
305
|
end
|
data/lib/git/version.rb
CHANGED