git 2.0.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ebad290719cdefc27125cf9a2ebb0d3544334c2d49a079220c0714a701ce141
4
- data.tar.gz: 293499cbb61ca9b4d374e86d0bd4357ed3f3b1254a46aa57c095cf0816afd7f6
3
+ metadata.gz: 7c7aebf8b61eb75a0d3e587fae03711b1d9cec89c7fb69462bda24c069daeaa4
4
+ data.tar.gz: f73bd8a6e030209305ffbcc1bae372cd6820745569142ddd7239b366ef78d322
5
5
  SHA512:
6
- metadata.gz: 8fc0929f6ff79eea57f5dbd5f05da813bb55f6c44f925ce45f4ad4f3a011c99e3cfa2d00c4a18824e1521ab975fa70057127b143d77e301f0d5d2382cd4d7480
7
- data.tar.gz: 5ef0e326223cc983605c8afc002e3fe77808d337a3a3dcfd1b25588adf58b5c697a3451fd8baae777f727a5f2ba3cb92f2c3e811c79bc9f5da836b24ad5a8a6b
6
+ metadata.gz: 32c0e605d3ee280c19cf863f5b9a5fc9437171b9facbbee074b2ddca096c4cae3f08ddf42cb6cad7a91512824f40cd51940e1846c1f1a3e5bb7f4e7ee52e154b
7
+ data.tar.gz: 528bf8926dbf6b76681b8333ca3d797b1e28854921f6abcd5b2fd9a13c6861c25e6ad75462efb818c1c74de0980c96974a423ad2a19aaf87d5b27e3e2ffca8cf
data/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## v2.0.1 (2024-05-21)
9
+
10
+ [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.0.0..v2.0.1)
11
+
12
+ Changes since v2.0.0:
13
+
14
+ * da435b1 Document and add tests for Git::Status
15
+ * c8a77db Fix Git::Base#status on an empty repo
16
+ * 712fdad Fix Git::Status#untracked when run from worktree subdir
17
+ * 6a59bc8 Remove the Git::Base::Factory module
18
+
8
19
  ## v2.0.0 (2024-05-10)
9
20
 
10
21
  [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.0.0.pre4..v2.0.0)
data/README.md CHANGED
@@ -23,11 +23,8 @@
23
23
 
24
24
  ## Summary
25
25
 
26
- The [git gem](https://rubygems.org/gems/git) provides an API that can be used to
27
- create, read, and manipulate Git repositories by wrapping system calls to the `git`
28
- command line. The API can be used for working with Git in complex interactions
29
- including branching and merging, object inspection and manipulation, history, patch
30
- generation and more.
26
+ The [git gem](https://rubygems.org/gems/git) provides a Ruby interface to the `git`
27
+ command line.
31
28
 
32
29
  Get started by obtaining a repository object by:
33
30
 
@@ -41,8 +38,7 @@ Methods that can be called on a repository object are documented in [Git::Base](
41
38
 
42
39
  git 2.0.0 has recently been released. Please give it a try.
43
40
 
44
-
45
- **If you have problems with the 2.x release, open an issue and use the 1.9.1 version
41
+ **If you have problems with the 2.x release, open an issue and use the 1.x version
46
42
  instead.** We will do our best to fix your issues in a timely fashion.
47
43
 
48
44
  **JRuby on Windows is not yet supported by the 2.x release line. Users running JRuby
data/lib/git/base.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'git/base/factory'
2
1
  require 'logger'
3
2
  require 'open3'
4
3
 
@@ -10,8 +9,6 @@ module Git
10
9
  # {Git.clone}, or {Git.bare}.
11
10
  #
12
11
  class Base
13
- include Git::Base::Factory
14
-
15
12
  # (see Git.bare)
16
13
  def self.bare(git_dir, options = {})
17
14
  normalize_paths(options, default_repository: git_dir, bare: true)
@@ -632,6 +629,96 @@ module Git
632
629
  self.lib.branch_current
633
630
  end
634
631
 
632
+ # @return [Git::Branch] an object for branch_name
633
+ def branch(branch_name = self.current_branch)
634
+ Git::Branch.new(self, branch_name)
635
+ end
636
+
637
+ # @return [Git::Branches] a collection of all the branches in the repository.
638
+ # Each branch is represented as a {Git::Branch}.
639
+ def branches
640
+ Git::Branches.new(self)
641
+ end
642
+
643
+ # returns a Git::Worktree object for dir, commitish
644
+ def worktree(dir, commitish = nil)
645
+ Git::Worktree.new(self, dir, commitish)
646
+ end
647
+
648
+ # returns a Git::worktrees object of all the Git::Worktrees
649
+ # objects for this repo
650
+ def worktrees
651
+ Git::Worktrees.new(self)
652
+ end
653
+
654
+ # @return [Git::Object::Commit] a commit object
655
+ def commit_tree(tree = nil, opts = {})
656
+ Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
657
+ end
658
+
659
+ # @return [Git::Diff] a Git::Diff object
660
+ def diff(objectish = 'HEAD', obj2 = nil)
661
+ Git::Diff.new(self, objectish, obj2)
662
+ end
663
+
664
+ # @return [Git::Object] a Git object
665
+ def gblob(objectish)
666
+ Git::Object.new(self, objectish, 'blob')
667
+ end
668
+
669
+ # @return [Git::Object] a Git object
670
+ def gcommit(objectish)
671
+ Git::Object.new(self, objectish, 'commit')
672
+ end
673
+
674
+ # @return [Git::Object] a Git object
675
+ def gtree(objectish)
676
+ Git::Object.new(self, objectish, 'tree')
677
+ end
678
+
679
+ # @return [Git::Log] a log with the specified number of commits
680
+ def log(count = 30)
681
+ Git::Log.new(self, count)
682
+ end
683
+
684
+ # returns a Git::Object of the appropriate type
685
+ # you can also call @git.gtree('tree'), but that's
686
+ # just for readability. If you call @git.gtree('HEAD') it will
687
+ # still return a Git::Object::Commit object.
688
+ #
689
+ # object calls a method that will run a rev-parse
690
+ # on the objectish and determine the type of the object and return
691
+ # an appropriate object for that type
692
+ #
693
+ # @return [Git::Object] an instance of the appropriate type of Git::Object
694
+ def object(objectish)
695
+ Git::Object.new(self, objectish)
696
+ end
697
+
698
+ # @return [Git::Remote] a remote of the specified name
699
+ def remote(remote_name = 'origin')
700
+ Git::Remote.new(self, remote_name)
701
+ end
702
+
703
+ # @return [Git::Status] a status object
704
+ def status
705
+ Git::Status.new(self)
706
+ end
707
+
708
+ # @return [Git::Object::Tag] a tag object
709
+ def tag(tag_name)
710
+ Git::Object.new(self, tag_name, 'tag', true)
711
+ end
712
+
713
+ # Find as good common ancestors as possible for a merge
714
+ # example: g.merge_base('master', 'some_branch', 'some_sha', octopus: true)
715
+ #
716
+ # @return [Array<Git::Object::Commit>] a collection of common ancestors
717
+ def merge_base(*args)
718
+ shas = self.lib.merge_base(*args)
719
+ shas.map { |sha| gcommit(sha) }
720
+ end
721
+
635
722
  private
636
723
 
637
724
  # Normalize options before they are sent to Git::Base.new
data/lib/git/lib.rb CHANGED
@@ -600,6 +600,9 @@ module Git
600
600
  command_lines('ls-files', '--others', '-i', '--exclude-standard')
601
601
  end
602
602
 
603
+ def untracked_files
604
+ command_lines('ls-files', '--others', '--exclude-standard', chdir: @git_work_dir)
605
+ end
603
606
 
604
607
  def config_remote(name)
605
608
  hsh = {}
@@ -704,6 +707,19 @@ module Git
704
707
  command('rm', *arr_opts)
705
708
  end
706
709
 
710
+ # Returns true if the repository is empty (meaning it has no commits)
711
+ #
712
+ # @return [Boolean]
713
+ #
714
+ def empty?
715
+ command('rev-parse', '--verify', 'HEAD')
716
+ false
717
+ rescue Git::FailedError => e
718
+ raise unless e.result.status.exitstatus == 128 &&
719
+ e.result.stderr == 'fatal: Needed a single revision'
720
+ true
721
+ end
722
+
707
723
  # Takes the commit message with the options and executes the commit command
708
724
  #
709
725
  # accepts options:
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
- # A class for git status
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
@@ -31,7 +37,6 @@ module Git
31
37
  changed.member?(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
  #
@@ -40,8 +45,8 @@ module Git
40
45
  @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.
@@ -126,9 +131,63 @@ module Git
126
131
 
127
132
  # subclass that does heavy lifting
128
133
  class StatusFile
129
- attr_accessor :path, :type, :stage, :untracked
130
- attr_accessor :mode_index, :mode_repo
131
- attr_accessor :sha_index, :sha_repo
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,30 @@ module Git
170
238
  end
171
239
 
172
240
  def fetch_untracked
173
- ignore = @base.lib.ignored_files
174
-
175
- root_dir = @base.dir.path
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
- # find modified in tree
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
- # find added but not committed - new files
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
- @files[path] ? @files[path].merge!(data) : @files[path] = data
263
+ @files[path] ? @files[path].merge!(data) : @files[path] = data
264
+ end
195
265
  end
196
266
  end
197
267
  end
data/lib/git/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Git
2
2
  # The current gem version
3
3
  # @return [String] the current gem version.
4
- VERSION='2.0.0'
4
+ VERSION='2.0.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon and others
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-11 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -213,7 +213,6 @@ files:
213
213
  - lib/git.rb
214
214
  - lib/git/author.rb
215
215
  - lib/git/base.rb
216
- - lib/git/base/factory.rb
217
216
  - lib/git/branch.rb
218
217
  - lib/git/branches.rb
219
218
  - lib/git/command_line.rb
@@ -244,8 +243,8 @@ licenses:
244
243
  metadata:
245
244
  homepage_uri: http://github.com/ruby-git/ruby-git
246
245
  source_code_uri: http://github.com/ruby-git/ruby-git
247
- changelog_uri: https://rubydoc.info/gems/git/2.0.0/file/CHANGELOG.md
248
- documentation_uri: https://rubydoc.info/gems/git/2.0.0
246
+ changelog_uri: https://rubydoc.info/gems/git/2.0.1/file/CHANGELOG.md
247
+ documentation_uri: https://rubydoc.info/gems/git/2.0.1
249
248
  post_install_message:
250
249
  rdoc_options: []
251
250
  require_paths:
@@ -1,99 +0,0 @@
1
- module Git
2
-
3
- class Base
4
-
5
- module Factory
6
- # @return [Git::Branch] an object for branch_name
7
- def branch(branch_name = self.current_branch)
8
- Git::Branch.new(self, branch_name)
9
- end
10
-
11
- # @return [Git::Branches] a collection of all the branches in the repository.
12
- # Each branch is represented as a {Git::Branch}.
13
- def branches
14
- Git::Branches.new(self)
15
- end
16
-
17
- # returns a Git::Worktree object for dir, commitish
18
- def worktree(dir, commitish = nil)
19
- Git::Worktree.new(self, dir, commitish)
20
- end
21
-
22
- # returns a Git::worktrees object of all the Git::Worktrees
23
- # objects for this repo
24
- def worktrees
25
- Git::Worktrees.new(self)
26
- end
27
-
28
- # @return [Git::Object::Commit] a commit object
29
- def commit_tree(tree = nil, opts = {})
30
- Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
31
- end
32
-
33
- # @return [Git::Diff] a Git::Diff object
34
- def diff(objectish = 'HEAD', obj2 = nil)
35
- Git::Diff.new(self, objectish, obj2)
36
- end
37
-
38
- # @return [Git::Object] a Git object
39
- def gblob(objectish)
40
- Git::Object.new(self, objectish, 'blob')
41
- end
42
-
43
- # @return [Git::Object] a Git object
44
- def gcommit(objectish)
45
- Git::Object.new(self, objectish, 'commit')
46
- end
47
-
48
- # @return [Git::Object] a Git object
49
- def gtree(objectish)
50
- Git::Object.new(self, objectish, 'tree')
51
- end
52
-
53
- # @return [Git::Log] a log with the specified number of commits
54
- def log(count = 30)
55
- Git::Log.new(self, count)
56
- end
57
-
58
- # returns a Git::Object of the appropriate type
59
- # you can also call @git.gtree('tree'), but that's
60
- # just for readability. If you call @git.gtree('HEAD') it will
61
- # still return a Git::Object::Commit object.
62
- #
63
- # object calls a factory method that will run a rev-parse
64
- # on the objectish and determine the type of the object and return
65
- # an appropriate object for that type
66
- #
67
- # @return [Git::Object] an instance of the appropriate type of Git::Object
68
- def object(objectish)
69
- Git::Object.new(self, objectish)
70
- end
71
-
72
- # @return [Git::Remote] a remote of the specified name
73
- def remote(remote_name = 'origin')
74
- Git::Remote.new(self, remote_name)
75
- end
76
-
77
- # @return [Git::Status] a status object
78
- def status
79
- Git::Status.new(self)
80
- end
81
-
82
- # @return [Git::Object::Tag] a tag object
83
- def tag(tag_name)
84
- Git::Object.new(self, tag_name, 'tag', true)
85
- end
86
-
87
- # Find as good common ancestors as possible for a merge
88
- # example: g.merge_base('master', 'some_branch', 'some_sha', octopus: true)
89
- #
90
- # @return [Array<Git::Object::Commit>] a collection of common ancestors
91
- def merge_base(*args)
92
- shas = self.lib.merge_base(*args)
93
- shas.map { |sha| gcommit(sha) }
94
- end
95
- end
96
-
97
- end
98
-
99
- end