git 1.17.2 → 1.19.0

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: cebf2eab3cc2c8cc605b1e3b9aeafa2f2c82ef0a50be725fc211fdb55a7980c0
4
- data.tar.gz: 9df1a5d2f067aa183a65cea1cd21e7260b72213f92c50b60bda26f261b2e7d23
3
+ metadata.gz: 41e2cebd7f83840b2e72176aa0d0a9f7b2441dbbe26f916b795877037bc82b6c
4
+ data.tar.gz: 03d373beb11219313117e419afdfce5be3ee225fd2f69dbee8d2e75b76ff7f10
5
5
  SHA512:
6
- metadata.gz: 57019fb39b7476d7ee5d97fd1c21f1bffa3b1fbd59413e5bb602794c106f38c2bc528c1a86b98b89bc835976671ea836a1bdf911aa9a281b81b97d221c12b80d
7
- data.tar.gz: d2f2927fbdf6b13b66d931183d6effb5fbb651e10c77a393e6b035ccc88e5b6ffd60dbed859fa6c400cd4551df253be89074e20aaa0f40379b609e79bd3553fa
6
+ metadata.gz: f0eb02c8af807265598c6e1fce6910d46dc6de257b4874e5957a65fd5788457eb084a4bec94b9e20ab69f05e4dff1d8bd7704f5a5af80679e0ab0ed819f3ef06
7
+ data.tar.gz: 78e566642f10ce5d18ff7112e864a9b1e4b6347cb4445abe5d1e0dea2e6f4b316e7218b896fdef39e17efdb928a0b1a2a2d169b640675f6d282f2537f99dfc86
data/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## v1.19.0 (2023-12-28)
9
+
10
+ [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.18.0..v1.19.0)
11
+
12
+ Changes since v1.18.0:
13
+
14
+ * 3bdb280 Add option to push all branches to a remote repo at one time (#678)
15
+ * b0d89ac Remove calls to Dir.chdir (#673)
16
+ * e64c2f6 Refactor tests for read_tree, write_tree, and commit_tree (#679)
17
+ * 0bb965d Explicitly name remote tracking branch in test (#676)
18
+ * 8481f8c Document how to delete a remote branch (#672)
19
+ * dce6816 show .log example with count in README, fixes #667 (#668)
20
+ * b1799f6 Update test of 'git worktree add' with no commits (#670)
21
+ * dd5a24d Add --filter to Git.clone for partial clones (#663)
22
+
23
+ ## v1.18.0 (2023-03-19)
24
+
25
+ [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.17.2..v1.18.0)
26
+
27
+ Changes since v1.17.2:
28
+
29
+ * 3c70 Add support for `--update-head-ok` to `fetch` (#660)
30
+ * b53d Do not generate yard documentation when building in TruffleRuby (#659)
31
+ * 5af1 Correctly report command output when there is an error (#658)
32
+ * b27a Add test to ensure that `Git.open` works to open a submodule (#655)
33
+ * 5b0e Update Git.clone to set multiple config variables (#653)
34
+
8
35
  ## v1.17.2 (2023-03-07)
9
36
 
10
37
  [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.17.1..v1.17.2)
data/README.md CHANGED
@@ -113,6 +113,7 @@ g.repo
113
113
  g.dir
114
114
 
115
115
  g.log # returns a Git::Log object, which is an Enumerator of Git::Commit objects
116
+ g.log(200)
116
117
  g.log.since('2 weeks ago')
117
118
  g.log.between('v2.5', 'v2.6')
118
119
  g.log.each {|l| puts l.sha }
@@ -188,6 +189,18 @@ end
188
189
  g.config('user.name') # returns 'Scott Chacon'
189
190
  g.config # returns whole config hash
190
191
 
192
+ # Configuration can be set when cloning using the :config option.
193
+ # This option can be an single configuration String or an Array
194
+ # if multiple config items need to be set.
195
+ #
196
+ g = Git.clone(
197
+ git_uri, destination_path,
198
+ :config => [
199
+ 'core.sshCommand=ssh -i /home/user/.ssh/id_rsa',
200
+ 'submodule.recurse=true'
201
+ ]
202
+ )
203
+
191
204
  g.tags # returns array of Git::Tag objects
192
205
 
193
206
  g.show()
@@ -224,6 +237,9 @@ g.dir #=> /tmp/clone/ruby-git-clean
224
237
  g.config('user.name', 'Scott Chacon')
225
238
  g.config('user.email', 'email@email.com')
226
239
 
240
+ # Clone can take a filter to tell the serve to send a partial clone
241
+ g = Git.clone(git_url, name, :path => path, :filter => 'tree:0')
242
+
227
243
  # Clone can take an optional logger
228
244
  logger = Logger.new
229
245
  g = Git.clone(git_url, NAME, :log => logger)
@@ -270,6 +286,9 @@ g.branch('new_branch').delete
270
286
  g.branch('existing_branch').checkout
271
287
  g.branch('master').contains?('existing_branch')
272
288
 
289
+ # delete remote branch
290
+ g.push('origin', 'remote_branch_name', force: true, delete: true)
291
+
273
292
  g.checkout('new_branch')
274
293
  g.checkout('new_branch', new_branch: true, start_point: 'master')
275
294
  g.checkout(g.branch('new_branch'))
@@ -299,6 +318,7 @@ g.fetch
299
318
  g.fetch(g.remotes.first)
300
319
  g.fetch('origin', {:ref => 'some/ref/head'} )
301
320
  g.fetch(all: true, force: true, depth: 2)
321
+ g.fetch('origin', {:'update-head-ok' => true})
302
322
 
303
323
  g.pull
304
324
  g.pull(Git::Repo, Git::Branch) # fetch and a merge
@@ -322,6 +342,12 @@ g.repack
322
342
  g.push
323
343
  g.push(g.remote('name'))
324
344
 
345
+ # delete remote branch
346
+ g.push('origin', 'remote_branch_name', force: true, delete: true)
347
+
348
+ # push all branches to remote at one time
349
+ g.push('origin', all: true)
350
+
325
351
  g.worktree('/tmp/new_worktree').add
326
352
  g.worktree('/tmp/new_worktree', 'branch1').add
327
353
  g.worktree('/tmp/new_worktree').remove
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ task :test do
18
18
  end
19
19
  default_tasks << :test
20
20
 
21
- unless RUBY_PLATFORM == 'java'
21
+ unless RUBY_PLATFORM == 'java' || RUBY_ENGINE == 'truffleruby'
22
22
  #
23
23
  # YARD documentation for this project can NOT be built with JRuby.
24
24
  # This project uses the redcarpet gem which can not be installed on JRuby.
data/git.gemspec CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  s.add_development_dependency 'bump', '~> 0.10'
33
33
  s.add_development_dependency 'create_github_release', '~> 0.2'
34
34
  s.add_development_dependency 'minitar', '~> 0.9'
35
+ s.add_development_dependency 'mocha', '~> 2.1'
35
36
  s.add_development_dependency 'rake', '~> 13.0'
36
37
  s.add_development_dependency 'test-unit', '~> 3.3'
37
38
 
data/lib/git/base.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'git/base/factory'
2
2
  require 'logger'
3
+ require 'open3'
3
4
 
4
5
  module Git
5
6
  # Git::Base is the main public interface for interacting with Git commands.
@@ -66,11 +67,11 @@ module Git
66
67
  def self.root_of_worktree(working_dir)
67
68
  result = working_dir
68
69
  status = nil
69
- Dir.chdir(working_dir) do
70
- git_cmd = "#{Git::Base.config.binary_path} -c core.quotePath=true -c color.ui=false rev-parse --show-toplevel 2>&1"
71
- result = `#{git_cmd}`.chomp
72
- status = $?
73
- end
70
+
71
+ git_cmd = "#{Git::Base.config.binary_path} -c core.quotePath=true -c color.ui=false rev-parse --show-toplevel 2>&1"
72
+ result, status = Open3.capture2(git_cmd, chdir: File.expand_path(working_dir))
73
+ result = result.chomp
74
+
74
75
  raise ArgumentError, "'#{working_dir}' is not in a git working tree" unless status.success?
75
76
  result
76
77
  end
@@ -14,18 +14,20 @@ module Git
14
14
  class FailedError < Git::GitExecuteError
15
15
  # Create a FailedError object
16
16
  #
17
+ # Since this gem redirects stderr to stdout, the stdout of the process is used.
18
+ #
17
19
  # @example
18
20
  # `exit 1` # set $? appropriately for this example
19
- # result = Git::CommandLineResult.new(%w[git status], $?, '', "failed")
21
+ # result = Git::CommandLineResult.new(%w[git status], $?, 'stdout', 'stderr')
20
22
  # error = Git::FailedError.new(result)
21
23
  # error.message #=>
22
- # "[\"git\", \"status\"]\nstatus: pid 89784 exit 1\nstderr: \"failed\""
24
+ # "[\"git\", \"status\"]\nstatus: pid 89784 exit 1\noutput: \"stdout\""
23
25
  #
24
26
  # @param result [Git::CommandLineResult] the result of the git command including
25
27
  # the git command, status, stdout, and stderr
26
28
  #
27
29
  def initialize(result)
28
- super("#{result.git_cmd}\nstatus: #{result.status}\nstderr: #{result.stderr.inspect}")
30
+ super("#{result.git_cmd}\nstatus: #{result.status}\noutput: #{result.stdout.inspect}")
29
31
  @result = result
30
32
  end
31
33
 
@@ -35,14 +37,14 @@ module Git
35
37
  #
36
38
  # @example
37
39
  # `exit 1` # set $? appropriately for this example
38
- # result = Git::CommandLineResult.new(%w[git status], $?, '', "failed")
40
+ # result = Git::CommandLineResult.new(%w[git status], $?, 'stdout', 'stderr')
39
41
  # error = Git::FailedError.new(result)
40
42
  # error.result #=>
41
43
  # #<Git::CommandLineResult:0x00000001046bd488
42
44
  # @git_cmd=["git", "status"],
43
45
  # @status=#<Process::Status: pid 89784 exit 1>,
44
- # @stderr="failed",
45
- # @stdout="">
46
+ # @stderr="stderr",
47
+ # @stdout="stdout">
46
48
  #
47
49
  # @return [Git::CommandLineResult]
48
50
  #
data/lib/git/lib.rb CHANGED
@@ -2,6 +2,7 @@ require 'git/failed_error'
2
2
  require 'logger'
3
3
  require 'tempfile'
4
4
  require 'zlib'
5
+ require 'open3'
5
6
 
6
7
  module Git
7
8
  class Lib
@@ -84,6 +85,7 @@ module Git
84
85
  # :bare:: no working directory
85
86
  # :branch:: name of branch to track (rather than 'master')
86
87
  # :depth:: the number of commits back to pull
88
+ # :filter:: specify partial clone
87
89
  # :origin:: name of remote (same as remote)
88
90
  # :path:: directory where the repo will be cloned
89
91
  # :remote:: name of remote (rather than 'origin')
@@ -101,7 +103,8 @@ module Git
101
103
  arr_opts << '--bare' if opts[:bare]
102
104
  arr_opts << '--branch' << opts[:branch] if opts[:branch]
103
105
  arr_opts << '--depth' << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
104
- arr_opts << '--config' << opts[:config] if opts[:config]
106
+ arr_opts << '--filter' << opts[:filter] if opts[:filter]
107
+ Array(opts[:config]).each { |c| arr_opts << '--config' << c }
105
108
  arr_opts << '--origin' << opts[:remote] || opts[:origin] if opts[:remote] || opts[:origin]
106
109
  arr_opts << '--recursive' if opts[:recursive]
107
110
  arr_opts << '--mirror' if opts[:mirror]
@@ -439,7 +442,10 @@ module Git
439
442
  def list_files(ref_dir)
440
443
  dir = File.join(@git_dir, 'refs', ref_dir)
441
444
  files = []
442
- Dir.chdir(dir) { files = Dir.glob('**/*').select { |f| File.file?(f) } } rescue nil
445
+ begin
446
+ files = Dir.glob('**/*', base: dir).select { |f| File.file?(File.join(dir, f)) }
447
+ rescue
448
+ end
443
449
  files
444
450
  end
445
451
 
@@ -577,15 +583,7 @@ module Git
577
583
  end
578
584
 
579
585
  def config_get(name)
580
- do_get = Proc.new do |path|
581
- command('config', '--get', name)
582
- end
583
-
584
- if @git_dir
585
- Dir.chdir(@git_dir, &do_get)
586
- else
587
- do_get.call
588
- end
586
+ command('config', '--get', name, chdir: @git_dir)
589
587
  end
590
588
 
591
589
  def global_config_get(name)
@@ -593,15 +591,7 @@ module Git
593
591
  end
594
592
 
595
593
  def config_list
596
- build_list = Proc.new do |path|
597
- parse_config_list command_lines('config', '--list')
598
- end
599
-
600
- if @git_dir
601
- Dir.chdir(@git_dir, &build_list)
602
- else
603
- build_list.call
604
- end
594
+ parse_config_list command_lines('config', '--list', chdir: @git_dir)
605
595
  end
606
596
 
607
597
  def global_config_list
@@ -951,6 +941,7 @@ module Git
951
941
  arr_opts << '--prune' if opts[:p] || opts[:prune]
952
942
  arr_opts << '--prune-tags' if opts[:P] || opts[:'prune-tags']
953
943
  arr_opts << '--force' if opts[:f] || opts[:force]
944
+ arr_opts << '--update-head-ok' if opts[:u] || opts[:'update-head-ok']
954
945
  arr_opts << '--unshallow' if opts[:unshallow]
955
946
  arr_opts << '--depth' << opts[:depth] if opts[:depth]
956
947
  arr_opts << '--' if remote || opts[:ref]
@@ -981,7 +972,9 @@ module Git
981
972
  arr_opts = []
982
973
  arr_opts << '--mirror' if opts[:mirror]
983
974
  arr_opts << '--delete' if opts[:delete]
984
- arr_opts << '--force' if opts[:force] || opts[:f]
975
+ arr_opts << '--force' if opts[:force] || opts[:f]
976
+ arr_opts << '--all' if opts[:all] && remote
977
+
985
978
  Array(opts[:push_option]).each { |o| arr_opts << '--push-option' << o } if opts[:push_option]
986
979
  arr_opts << remote if remote
987
980
  arr_opts_with_branch = arr_opts.dup
@@ -1040,7 +1033,7 @@ module Git
1040
1033
  arr_opts = []
1041
1034
  arr_opts << tree
1042
1035
  arr_opts << '-p' << opts[:parent] if opts[:parent]
1043
- arr_opts += [opts[:parents]].map { |p| ['-p', p] }.flatten if opts[:parents]
1036
+ arr_opts += Array(opts[:parents]).map { |p| ['-p', p] }.flatten if opts[:parents]
1044
1037
  command('commit-tree', *arr_opts, redirect: "< #{escape t.path}")
1045
1038
  end
1046
1039
 
@@ -1105,6 +1098,22 @@ module Git
1105
1098
  version_parts.fill(0, version_parts.length...3)
1106
1099
  end
1107
1100
 
1101
+ # Returns current_command_version <=> other_version
1102
+ #
1103
+ # @example
1104
+ # lib.current_command_version #=> [2, 42, 0]
1105
+ #
1106
+ # lib.compare_version_to(2, 41, 0) #=> 1
1107
+ # lib.compare_version_to(2, 42, 0) #=> 0
1108
+ # lib.compare_version_to(2, 43, 0) #=> -1
1109
+ #
1110
+ # @param other_version [Array<Object>] the other version to compare to
1111
+ # @return [Integer] -1 if this version is less than other_version, 0 if equal, or 1 if greater than
1112
+ #
1113
+ def compare_version_to(*other_version)
1114
+ current_command_version <=> other_version
1115
+ end
1116
+
1108
1117
  def required_command_version
1109
1118
  [1, 6]
1110
1119
  end
@@ -1129,8 +1138,8 @@ module Git
1129
1138
  # @return [<String>] the names of the EVN variables involved in the git commands
1130
1139
  ENV_VARIABLE_NAMES = ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_SSH']
1131
1140
 
1132
- def command_lines(cmd, *opts)
1133
- cmd_op = command(cmd, *opts)
1141
+ def command_lines(cmd, *opts, chdir: nil)
1142
+ cmd_op = command(cmd, *opts, chdir: chdir)
1134
1143
  if cmd_op.encoding.name != "UTF-8"
1135
1144
  op = cmd_op.encode("UTF-8", "binary", :invalid => :replace, :undef => :replace)
1136
1145
  else
@@ -1176,7 +1185,7 @@ module Git
1176
1185
  restore_git_system_env_variables()
1177
1186
  end
1178
1187
 
1179
- def command(*cmd, redirect: '', chomp: true, &block)
1188
+ def command(*cmd, redirect: '', chomp: true, chdir: nil, &block)
1180
1189
  Git::Lib.warn_if_old_command(self)
1181
1190
 
1182
1191
  raise 'cmd can not include a nested array' if cmd.any? { |o| o.is_a? Array }
@@ -1201,8 +1210,7 @@ module Git
1201
1210
 
1202
1211
  with_custom_env_variables do
1203
1212
  command_thread = Thread.new do
1204
- output = run_command(git_cmd, &block)
1205
- status = $?
1213
+ output, status = run_command(git_cmd, chdir, &block)
1206
1214
  end
1207
1215
  command_thread.join
1208
1216
  end
@@ -1284,10 +1292,17 @@ module Git
1284
1292
  arr_opts
1285
1293
  end
1286
1294
 
1287
- def run_command(git_cmd, &block)
1288
- return IO.popen(git_cmd, &block) if block_given?
1295
+ def run_command(git_cmd, chdir=nil, &block)
1296
+ block ||= Proc.new do |io|
1297
+ io.readlines.map { |l| Git::EncodingUtils.normalize_encoding(l) }.join
1298
+ end
1299
+
1300
+ opts = {}
1301
+ opts[:chdir] = File.expand_path(chdir) if chdir
1289
1302
 
1290
- `#{git_cmd}`.lines.map { |l| Git::EncodingUtils.normalize_encoding(l) }.join
1303
+ Open3.popen2(git_cmd, opts) do |stdin, stdout, wait_thr|
1304
+ [block.call(stdout), wait_thr.value]
1305
+ end
1291
1306
  end
1292
1307
 
1293
1308
  def escape(s)
data/lib/git/status.rb CHANGED
@@ -172,13 +172,12 @@ module Git
172
172
  def fetch_untracked
173
173
  ignore = @base.lib.ignored_files
174
174
 
175
- Dir.chdir(@base.dir.path) do
176
- Dir.glob('**/*', File::FNM_DOTMATCH) do |file|
177
- next if @files[file] || File.directory?(file) ||
178
- ignore.include?(file) || file =~ %r{^.git\/.+}
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
179
 
180
- @files[file] = { path: file, untracked: true }
181
- end
180
+ @files[file] = { path: file, untracked: true }
182
181
  end
183
182
  end
184
183
 
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='1.17.2'
4
+ VERSION='1.19.0'
5
5
  end
data/lib/git.rb CHANGED
@@ -133,9 +133,15 @@ module Git
133
133
  # @option options [String] :branch The name of a branch or tag to checkout
134
134
  # instead of the default branch.
135
135
  #
136
+ # @option options [Array, String] :config A list of configuration options to
137
+ # set on the newly created repository.
138
+ #
136
139
  # @option options [Integer] :depth Create a shallow clone with a history
137
140
  # truncated to the specified number of commits.
138
141
  #
142
+ # @option options [String] :filter Request that the server send a partial
143
+ # clone according to the given filter
144
+ #
139
145
  # @option options [Logger] :log A logger to use for Git operations. Git
140
146
  # commands are logged at the `:info` level. Additional logging is done
141
147
  # at the `:debug` level.
@@ -166,6 +172,18 @@ module Git
166
172
  # @example Create a bare repository in the directory `ruby-git.git`
167
173
  # git = Git.clone('https://github.com/ruby-git/ruby-git.git', bare: true)
168
174
  #
175
+ # @example Clone a repository and set a single config option
176
+ # git = Git.clone(
177
+ # 'https://github.com/ruby-git/ruby-git.git',
178
+ # config: 'submodule.recurse=true'
179
+ # )
180
+ #
181
+ # @example Clone a repository and set multiple config options
182
+ # git = Git.clone(
183
+ # 'https://github.com/ruby-git/ruby-git.git',
184
+ # config: ['user.name=John Doe', 'user.email=john@doe.com']
185
+ # )
186
+ #
169
187
  # @return [Git::Base] an object that can execute git commands in the context
170
188
  # of the cloned local working copy or cloned repository.
171
189
  #
@@ -226,7 +244,7 @@ module Git
226
244
  options.delete(:remote)
227
245
  repo = clone(repository, name, {:depth => 1}.merge(options))
228
246
  repo.checkout("origin/#{options[:branch]}") if options[:branch]
229
- Dir.chdir(repo.dir.to_s) { FileUtils.rm_r '.git' }
247
+ FileUtils.rm_r File.join(repo.dir.to_s, '.git')
230
248
  end
231
249
 
232
250
  # Same as g.config, but forces it to be at the global level
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: 1.17.2
4
+ version: 1.19.0
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: 2023-03-07 00:00:00.000000000 Z
11
+ date: 2023-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mocha
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.1'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -235,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
249
  version: '0'
236
250
  requirements:
237
251
  - git 1.6.0.0, or greater
238
- rubygems_version: 3.4.1
252
+ rubygems_version: 3.4.14
239
253
  signing_key:
240
254
  specification_version: 4
241
255
  summary: An API to create, read, and manipulate Git repositories