git 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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