git 1.19.1 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/RELEASING.md CHANGED
@@ -7,64 +7,79 @@
7
7
 
8
8
  Releasing a new version of the `git` gem requires these steps:
9
9
 
10
- - [How to release a new git.gem](#how-to-release-a-new-gitgem)
11
- - [Install Prerequisites](#install-prerequisites)
12
- - [Prepare the Release](#prepare-the-release)
13
- - [Review and Merge the Release](#review-and-merge-the-release)
14
- - [Build and Release the Gem](#build-and-release-the-gem)
15
-
16
- These instructions use an example where:
17
-
18
- - The default branch is `master`
19
- - The current release version is `1.5.0`
20
- - You want to create a new *minor* release, `1.6.0`
10
+ * [Install Prerequisites](#install-prerequisites)
11
+ * [Determine the SemVer release type](#determine-the-semver-release-type)
12
+ * [Create the release](#create-the-release)
13
+ * [Review the CHANGELOG and release PR](#review-the-changelog-and-release-pr)
14
+ * [Manually merge the release PR](#manually-merge-the-release-pr)
15
+ * [Publish the git gem to RubyGems.org](#publish-the-git-gem-to-rubygemsorg)
21
16
 
22
17
  ## Install Prerequisites
23
18
 
24
19
  The following tools need to be installed in order to create the release:
25
20
 
26
- - [git](https://git-scm.com) is used to interact with the local and remote repositories
27
- - [gh](https://cli.github.com) is used to create the release and PR in GitHub
28
- - [Docker](https://www.docker.com) is used to run the script to create the release notes
21
+ * [create_githhub_release](https://github.com/main-branch/create_github_release) is used to create the release
22
+ * [git](https://git-scm.com) is used by `create-github-release` to interact with the local and remote repositories
23
+ * [gh](https://cli.github.com) is used by `create-github-release` to create the release and PR in GitHub
29
24
 
30
- On a Mac, these tools can be installed using [brew](https://brew.sh):
25
+ On a Mac, these tools can be installed using [gem](https://guides.rubygems.org/rubygems-basics/) and [brew](https://brew.sh):
31
26
 
32
27
  ```shell
28
+ $ gem install create_github_release
29
+ ...
33
30
  $ brew install git
34
31
  ...
35
32
  $ brew install gh
36
33
  ...
37
- $ brew install --cask docker
38
- ...
39
34
  $
40
35
  ```
41
36
 
42
- ## Prepare the Release
37
+ ## Determine the SemVer release type
43
38
 
44
- Bump the version, create release notes, tag the release and create a GitHub release and PR which can be used to review the release.
39
+ Determine the SemVer version increment that should be applied for the new release:
45
40
 
46
- Steps:
41
+ * `major`: when the release includes incompatible API or functional changes.
42
+ * `minor`: when the release adds functionality in a backward-compatible manner
43
+ * `patch`: when the release includes small user-facing changes that are
44
+ backward-compatible and do not introduce new functionality.
47
45
 
48
- - Check out the code with `git clone https://github.com/ruby-git/ruby-git ruby-git-v1.6.0 && cd ruby-git-v1.6.0`
49
- - Install development dependencies using bundle `bundle install`
50
- - Based upon the nature of the changes, decide on the type of release: `major`, `minor`, or `patch` (in this example we will use `minor`)
51
- - Run the release script `bundle exec create-github-release minor`
46
+ ## Create the release
52
47
 
53
- ## Review and Merge the Release
48
+ Create the release using the `create-github-release` command. If the release type
49
+ is `major`, the command is:
54
50
 
55
- Have the release PR approved and merge the changes into the `master` branch.
51
+ ```shell
52
+ create-github-release major
53
+ ```
56
54
 
57
- **IMPORTANT** DO NOT merge to the `master` branch using the GitHub UI. Instead use the instructions below.
55
+ Follow the directions given by the `create-github-release` command to finish the
56
+ release. Where the instructions given by the command differ than the instructions
57
+ below, follow the instructions given by the command.
58
58
 
59
- Steps:
59
+ ## Review the CHANGELOG and release PR
60
60
 
61
- - Get the release PR reviewed and approved in GitHub
62
- - Merge the changes with the command `git checkout master && git merge --ff-only v1.6.0 && git push`
61
+ The `create-github-release` command will output a link to the CHANGELOG and the PR
62
+ it created for the release. Review the CHANGELOG and have someone review and approve
63
+ the release PR.
63
64
 
64
- ## Build and Release the Gem
65
+ ## Manually merge the release PR
65
66
 
66
- Build the gem and publish it to [rubygems.org](https://rubygems.org/gems/git)
67
+ It is important to manually merge the PR so a separate merge commit can be avoided.
68
+ Use the commands output by the `create-github-release` which will looks like this
69
+ if you are creating a 2.0.0 release:
67
70
 
68
- Steps:
71
+ ```shell
72
+ git checkout master
73
+ git merge --ff-only release-v2.0.0
74
+ git push
75
+ ```
76
+
77
+ This will automatically close the release PR.
78
+
79
+ ## Publish the git gem to RubyGems.org
69
80
 
70
- - Build and release the gem using rake `bundle exec rake release`
81
+ Finally, publish the git gem to RubyGems.org using the following command:
82
+
83
+ ```shell
84
+ rake release:rubygem_push
85
+ ```
data/git.gemspec CHANGED
@@ -24,22 +24,22 @@ Gem::Specification.new do |s|
24
24
  s.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{s.name}/#{s.version}"
25
25
 
26
26
  s.require_paths = ['lib']
27
- s.required_ruby_version = '>= 2.3'
28
- s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to?(:required_rubygems_version=)
29
- s.requirements = ['git 1.6.0.0, or greater']
27
+ s.required_ruby_version = '>= 3.0.0'
28
+ s.requirements = ['git 2.28.0 or greater']
30
29
 
30
+ s.add_runtime_dependency 'activesupport', '>= 5.0'
31
31
  s.add_runtime_dependency 'addressable', '~> 2.8'
32
+ s.add_runtime_dependency 'process_executer', '~> 1.1'
32
33
  s.add_runtime_dependency 'rchardet', '~> 1.8'
33
34
 
34
- s.add_development_dependency 'bump', '~> 0.10'
35
- s.add_development_dependency 'create_github_release', '~> 0.2'
35
+ s.add_development_dependency 'create_github_release', '~> 1.4'
36
36
  s.add_development_dependency 'minitar', '~> 0.9'
37
37
  s.add_development_dependency 'mocha', '~> 2.1'
38
- s.add_development_dependency 'rake', '~> 13.0'
39
- s.add_development_dependency 'test-unit', '~> 3.3'
38
+ s.add_development_dependency 'rake', '~> 13.1'
39
+ s.add_development_dependency 'test-unit', '~> 3.6'
40
40
 
41
41
  unless RUBY_PLATFORM == 'java'
42
- s.add_development_dependency 'redcarpet', '~> 3.5'
42
+ s.add_development_dependency 'redcarpet', '~> 3.6'
43
43
  s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
44
44
  s.add_development_dependency 'yardstick', '~> 0.9'
45
45
  end
data/lib/git/base.rb CHANGED
@@ -1,17 +1,16 @@
1
- require 'git/base/factory'
2
1
  require 'logger'
3
2
  require 'open3'
4
3
 
5
4
  module Git
6
- # Git::Base is the main public interface for interacting with Git commands.
5
+ # The main public interface for interacting with Git commands
7
6
  #
8
7
  # Instead of creating a Git::Base directly, obtain a Git::Base instance by
9
8
  # calling one of the follow {Git} class methods: {Git.open}, {Git.init},
10
9
  # {Git.clone}, or {Git.bare}.
11
10
  #
11
+ # @api public
12
+ #
12
13
  class Base
13
- include Git::Base::Factory
14
-
15
14
  # (see Git.bare)
16
15
  def self.bare(git_dir, options = {})
17
16
  normalize_paths(options, default_repository: git_dir, bare: true)
@@ -122,6 +121,62 @@ module Git
122
121
  @index = options[:index] ? Git::Index.new(options[:index], false) : nil
123
122
  end
124
123
 
124
+ # Update the index from the current worktree to prepare the for the next commit
125
+ #
126
+ # @example
127
+ # lib.add('path/to/file')
128
+ # lib.add(['path/to/file1','path/to/file2'])
129
+ # lib.add(all: true)
130
+ #
131
+ # @param [String, Array<String>] paths a file or files to be added to the repository (relative to the worktree root)
132
+ # @param [Hash] options
133
+ #
134
+ # @option options [Boolean] :all Add, modify, and remove index entries to match the worktree
135
+ # @option options [Boolean] :force Allow adding otherwise ignored files
136
+ #
137
+ def add(paths = '.', **options)
138
+ self.lib.add(paths, options)
139
+ end
140
+
141
+ # adds a new remote to this repository
142
+ # url can be a git url or a Git::Base object if it's a local reference
143
+ #
144
+ # @git.add_remote('scotts_git', 'git://repo.or.cz/rubygit.git')
145
+ # @git.fetch('scotts_git')
146
+ # @git.merge('scotts_git/master')
147
+ #
148
+ # Options:
149
+ # :fetch => true
150
+ # :track => <branch_name>
151
+ def add_remote(name, url, opts = {})
152
+ url = url.repo.path if url.is_a?(Git::Base)
153
+ self.lib.remote_add(name, url, opts)
154
+ Git::Remote.new(self, name)
155
+ end
156
+
157
+ # Create a new git tag
158
+ #
159
+ # @example
160
+ # repo.add_tag('tag_name', object_reference)
161
+ # repo.add_tag('tag_name', object_reference, {:options => 'here'})
162
+ # repo.add_tag('tag_name', {:options => 'here'})
163
+ #
164
+ # @param [String] name The name of the tag to add
165
+ # @param [Hash] options Opstions to pass to `git tag`.
166
+ # See [git-tag](https://git-scm.com/docs/git-tag) for more details.
167
+ # @option options [boolean] :annotate Make an unsigned, annotated tag object
168
+ # @option options [boolean] :a An alias for the `:annotate` option
169
+ # @option options [boolean] :d Delete existing tag with the given names.
170
+ # @option options [boolean] :f Replace an existing tag with the given name (instead of failing)
171
+ # @option options [String] :message Use the given tag message
172
+ # @option options [String] :m An alias for the `:message` option
173
+ # @option options [boolean] :s Make a GPG-signed tag.
174
+ #
175
+ def add_tag(name, *options)
176
+ self.lib.tag(name, *options)
177
+ self.tag(name)
178
+ end
179
+
125
180
  # changes current working directory for a block
126
181
  # to the git working directory
127
182
  #
@@ -254,27 +309,11 @@ module Git
254
309
  self.object('HEAD').grep(string, path_limiter, opts)
255
310
  end
256
311
 
257
- # updates the repository index using the working directory content
258
- #
259
- # @example
260
- # git.add
261
- # git.add('path/to/file')
262
- # git.add(['path/to/file1','path/to/file2'])
263
- # git.add(:all => true)
312
+ # List the files in the worktree that are ignored by git
313
+ # @return [Array<String>] the list of ignored files relative to teh root of the worktree
264
314
  #
265
- # options:
266
- # :all => true
267
- #
268
- # @param [String,Array] paths files paths to be added (optional, default='.')
269
- # @param [Hash] options
270
- # @option options [boolean] :all
271
- # Update the index not only where the working tree has a file matching
272
- # <pathspec> but also where the index already has an entry.
273
- # See [the --all option to git-add](https://git-scm.com/docs/git-add#Documentation/git-add.txt--A)
274
- # for more details.
275
- #
276
- def add(paths = '.', **options)
277
- self.lib.add(paths, options)
315
+ def ignored_files
316
+ self.lib.ignored_files
278
317
  end
279
318
 
280
319
  # removes file(s) from the git repository
@@ -409,14 +448,27 @@ module Git
409
448
  self.lib.conflicts(&block)
410
449
  end
411
450
 
412
- # pulls the given branch from the given remote into the current branch
451
+ # Pulls the given branch from the given remote into the current branch
452
+ #
453
+ # @param remote [String] the remote repository to pull from
454
+ # @param branch [String] the branch to pull from
455
+ # @param opts [Hash] options to pass to the pull command
413
456
  #
414
- # @git.pull # pulls from origin/master
415
- # @git.pull('upstream') # pulls from upstream/master
416
- # @git.pull('upstream', 'develope') # pulls from upstream/develop
457
+ # @option opts [Boolean] :allow_unrelated_histories (false) Merges histories of two projects that started their
458
+ # lives independently
459
+ # @example pulls from origin/master
460
+ # @git.pull
461
+ # @example pulls from upstream/master
462
+ # @git.pull('upstream')
463
+ # @example pulls from upstream/develop
464
+ # @git.pull('upstream', 'develop')
417
465
  #
418
- def pull(remote = nil, branch = nil)
419
- self.lib.pull(remote, branch)
466
+ # @return [Void]
467
+ #
468
+ # @raise [Git::FailedError] if the pull fails
469
+ # @raise [ArgumentError] if a branch is given without a remote
470
+ def pull(remote = nil, branch = nil, opts = {})
471
+ self.lib.pull(remote, branch, opts)
420
472
  end
421
473
 
422
474
  # returns an array of Git:Remote objects
@@ -424,22 +476,6 @@ module Git
424
476
  self.lib.remotes.map { |r| Git::Remote.new(self, r) }
425
477
  end
426
478
 
427
- # adds a new remote to this repository
428
- # url can be a git url or a Git::Base object if it's a local reference
429
- #
430
- # @git.add_remote('scotts_git', 'git://repo.or.cz/rubygit.git')
431
- # @git.fetch('scotts_git')
432
- # @git.merge('scotts_git/master')
433
- #
434
- # Options:
435
- # :fetch => true
436
- # :track => <branch_name>
437
- def add_remote(name, url, opts = {})
438
- url = url.repo.path if url.is_a?(Git::Base)
439
- self.lib.remote_add(name, url, opts)
440
- Git::Remote.new(self, name)
441
- end
442
-
443
479
  # sets the url for a remote
444
480
  # url can be a git url or a Git::Base object if it's a local reference
445
481
  #
@@ -463,7 +499,7 @@ module Git
463
499
  self.lib.tags.map { |r| tag(r) }
464
500
  end
465
501
 
466
- # Creates a new git tag (Git::Tag)
502
+ # Create a new git tag
467
503
  #
468
504
  # @example
469
505
  # repo.add_tag('tag_name', object_reference)
@@ -619,6 +655,96 @@ module Git
619
655
  self.lib.branch_current
620
656
  end
621
657
 
658
+ # @return [Git::Branch] an object for branch_name
659
+ def branch(branch_name = self.current_branch)
660
+ Git::Branch.new(self, branch_name)
661
+ end
662
+
663
+ # @return [Git::Branches] a collection of all the branches in the repository.
664
+ # Each branch is represented as a {Git::Branch}.
665
+ def branches
666
+ Git::Branches.new(self)
667
+ end
668
+
669
+ # returns a Git::Worktree object for dir, commitish
670
+ def worktree(dir, commitish = nil)
671
+ Git::Worktree.new(self, dir, commitish)
672
+ end
673
+
674
+ # returns a Git::worktrees object of all the Git::Worktrees
675
+ # objects for this repo
676
+ def worktrees
677
+ Git::Worktrees.new(self)
678
+ end
679
+
680
+ # @return [Git::Object::Commit] a commit object
681
+ def commit_tree(tree = nil, opts = {})
682
+ Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
683
+ end
684
+
685
+ # @return [Git::Diff] a Git::Diff object
686
+ def diff(objectish = 'HEAD', obj2 = nil)
687
+ Git::Diff.new(self, objectish, obj2)
688
+ end
689
+
690
+ # @return [Git::Object] a Git object
691
+ def gblob(objectish)
692
+ Git::Object.new(self, objectish, 'blob')
693
+ end
694
+
695
+ # @return [Git::Object] a Git object
696
+ def gcommit(objectish)
697
+ Git::Object.new(self, objectish, 'commit')
698
+ end
699
+
700
+ # @return [Git::Object] a Git object
701
+ def gtree(objectish)
702
+ Git::Object.new(self, objectish, 'tree')
703
+ end
704
+
705
+ # @return [Git::Log] a log with the specified number of commits
706
+ def log(count = 30)
707
+ Git::Log.new(self, count)
708
+ end
709
+
710
+ # returns a Git::Object of the appropriate type
711
+ # you can also call @git.gtree('tree'), but that's
712
+ # just for readability. If you call @git.gtree('HEAD') it will
713
+ # still return a Git::Object::Commit object.
714
+ #
715
+ # object calls a method that will run a rev-parse
716
+ # on the objectish and determine the type of the object and return
717
+ # an appropriate object for that type
718
+ #
719
+ # @return [Git::Object] an instance of the appropriate type of Git::Object
720
+ def object(objectish)
721
+ Git::Object.new(self, objectish)
722
+ end
723
+
724
+ # @return [Git::Remote] a remote of the specified name
725
+ def remote(remote_name = 'origin')
726
+ Git::Remote.new(self, remote_name)
727
+ end
728
+
729
+ # @return [Git::Status] a status object
730
+ def status
731
+ Git::Status.new(self)
732
+ end
733
+
734
+ # @return [Git::Object::Tag] a tag object
735
+ def tag(tag_name)
736
+ Git::Object.new(self, tag_name, 'tag', true)
737
+ end
738
+
739
+ # Find as good common ancestors as possible for a merge
740
+ # example: g.merge_base('master', 'some_branch', 'some_sha', octopus: true)
741
+ #
742
+ # @return [Array<Git::Object::Commit>] a collection of common ancestors
743
+ def merge_base(*args)
744
+ shas = self.lib.merge_base(*args)
745
+ shas.map { |sha| gcommit(sha) }
746
+ end
747
+
622
748
  private
623
749
 
624
750
  # Normalize options before they are sent to Git::Base.new