git 1.14.0 → 1.16.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: 344c98cd98670d4afa26aae12680f28ad857f1fdbca4384a10c9cf7ed7937a8a
4
- data.tar.gz: 9d857e44f2457f6c5208bebca6935991c2e88fbd82b2c482c570cd7afcca7c38
3
+ metadata.gz: 06d2809c51685e3171199f0eb8bce4c02a7970d61d12fabbde7bf2ab3850a86b
4
+ data.tar.gz: 439eac61b04b8fcdafa739f7f6f27cfc89f00d557aac52aacd6f71762bc8281e
5
5
  SHA512:
6
- metadata.gz: 6fd40652aa02ad36238522ee2210ad7c01ced240f0a1b91f2de3e6baefe93dd0a20fb22b80821ee45bf974d73a3cc346e4a5adbaa2322384b57e2bb0251d491d
7
- data.tar.gz: 0c8d86fe09a9e4f8d06c1d8bb0abf05eff45a2746450253ccf751163e4340b873df4eff2dbfb0711aad30c61303e0c692802a378bceb46a26a1e17ba08927268
6
+ metadata.gz: 57db3b512e1d30130f1ab8bf9f77a701591c4c05c8c9fe35e9d047329cc7fe08b6e17c93d276bcfbfcb3e5c92a8dcb48cc571d513a7a981d69989eac7daea957
7
+ data.tar.gz: ee2b51658bda3767a01729888c60b677d79d69b75fadb8659a6d56144e82f51e21da817f7f310b1af0be9baedda37923315adac10ad7a65be1624b6ecb0628fb
data/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## v1.16.0 (2023-03-03)
9
+
10
+ [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.15.0..v1.16.0)
11
+
12
+ Changes since v1.15.0:
13
+
14
+ * 536d Fix parsing when in detached HEAD state in Git::Lib#branches_all (#641)
15
+ * 5c68 Fix parsing of symbolic refs in `Git::Lib#branches_all` (#640)
16
+ * 7d88 Remote#branch and #merge should default to current branch instead of "master" (#639)
17
+ * 3dda0 `#branch` name should default to current branch instead of `master` (#638)
18
+ * d33d #checkout without args should do same as `git checkout` with no args (#637)
19
+ * 0c90 #push without args should do same as `git push` with no args (#636)
20
+ * 2b19 Make it easier to run test files from the command line (#635)
21
+
22
+ ## v1.15.0 (2023-03-01)
23
+
24
+ [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.14.0..v1.15.0)
25
+
26
+ Changes since v1.14.0:
27
+
28
+ * b40d #pull with no options should do the same thing as `git pull` with no options (#633)
29
+ * 9c5e Fix error when calling `Git::Lib#remove` with `recursive` or `cached` options (#632)
30
+ * 806e Add Git::Log#all option (#630)
31
+ * d905 Allow a repo to be opened giving a non-root repo directory (#629)
32
+ * 1ccd Rewrite worktree tests (#628)
33
+ * 4409 Fix Git::Branch#update_ref (#626)
34
+
8
35
  ## v1.14.0 (2023-02-25)
9
36
 
10
37
  [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.13.2..v1.14.0)
data/CONTRIBUTING.md CHANGED
@@ -84,11 +84,11 @@ In order to ensure high quality, all pull requests must meet these requirements:
84
84
  While working on specific features you can run individual test files or
85
85
  a group of tests using `bin/test`:
86
86
 
87
- # run a single file:
88
- $ bin/test tests/units/test_object.rb
87
+ # run a single file (from tests/units):
88
+ $ bin/test test_object
89
89
 
90
90
  # run multiple files:
91
- $ bin/test tests/units/test_object.rb tests/units/test_archive.rb
91
+ $ bin/test test_object test_archive
92
92
 
93
93
  # run all unit tests:
94
94
  $ bin/test
data/README.md CHANGED
@@ -66,6 +66,10 @@ like:
66
66
 
67
67
  `@git.log(20).object("some_file").since("2 weeks ago").between('v2.6', 'v2.7').each { |commit| [block] }`
68
68
 
69
+ Pass the `--all` option to `git log` as follows:
70
+
71
+ `@git.log.all.each { |commit| [block] }`
72
+
69
73
  **Git::Worktrees** - Enumerable object that holds `Git::Worktree objects`.
70
74
 
71
75
  ## Examples
@@ -3,9 +3,8 @@ module Git
3
3
  class Base
4
4
 
5
5
  module Factory
6
-
7
6
  # @return [Git::Branch] an object for branch_name
8
- def branch(branch_name = 'master')
7
+ def branch(branch_name = self.current_branch)
9
8
  Git::Branch.new(self, branch_name)
10
9
  end
11
10
 
@@ -93,7 +92,6 @@ module Git
93
92
  shas = self.lib.merge_base(*args)
94
93
  shas.map { |sha| gcommit(sha) }
95
94
  end
96
-
97
95
  end
98
96
 
99
97
  end
data/lib/git/base.rb CHANGED
@@ -58,9 +58,26 @@ module Git
58
58
  self.new(options)
59
59
  end
60
60
 
61
+ def self.root_of_worktree(working_dir)
62
+ result = working_dir
63
+ status = nil
64
+ Dir.chdir(working_dir) do
65
+ git_cmd = "#{Git::Base.config.binary_path} -c core.quotePath=true -c color.ui=false rev-parse --show-toplevel 2>&1"
66
+ result = `#{git_cmd}`.chomp
67
+ status = $?
68
+ end
69
+ raise ArgumentError, "'#{working_dir}' is not in a git working tree" unless status.success?
70
+ result
71
+ end
72
+
61
73
  # (see Git.open)
62
74
  def self.open(working_dir, options = {})
75
+ raise ArgumentError, "'#{working_dir}' is not a directory" unless Dir.exist?(working_dir)
76
+
77
+ working_dir = root_of_worktree(working_dir) unless options[:repository]
78
+
63
79
  normalize_paths(options, default_working_directory: working_dir)
80
+
64
81
  self.new(options)
65
82
  end
66
83
 
@@ -255,10 +272,12 @@ module Git
255
272
  end
256
273
 
257
274
  # removes file(s) from the git repository
258
- def remove(path = '.', opts = {})
259
- self.lib.remove(path, opts)
275
+ def rm(path = '.', opts = {})
276
+ self.lib.rm(path, opts)
260
277
  end
261
278
 
279
+ alias remove rm
280
+
262
281
  # resets the working directory to the provided commitish
263
282
  def reset(commitish = nil, opts = {})
264
283
  self.lib.reset(commitish, opts)
@@ -331,8 +350,8 @@ module Git
331
350
  end
332
351
 
333
352
  # checks out a branch as the new git working directory
334
- def checkout(branch = 'master', opts = {})
335
- self.lib.checkout(branch, opts)
353
+ def checkout(*args, **options)
354
+ self.lib.checkout(*args, **options)
336
355
  end
337
356
 
338
357
  # checks out an old version of a file
@@ -355,11 +374,8 @@ module Git
355
374
  #
356
375
  # @git.config('remote.remote-name.push', 'refs/heads/master:refs/heads/master')
357
376
  #
358
- def push(remote = 'origin', branch = 'master', opts = {})
359
- # Small hack to keep backwards compatibility with the 'push(remote, branch, tags)' method signature.
360
- opts = {:tags => opts} if [true, false].include?(opts)
361
-
362
- self.lib.push(remote, branch, opts)
377
+ def push(*args, **options)
378
+ self.lib.push(*args, **options)
363
379
  end
364
380
 
365
381
  # merges one or more branches into the current working branch
@@ -380,7 +396,7 @@ module Git
380
396
  # @git.pull('upstream') # pulls from upstream/master
381
397
  # @git.pull('upstream', 'develope') # pulls from upstream/develop
382
398
  #
383
- def pull(remote='origin', branch='master')
399
+ def pull(remote = nil, branch = nil)
384
400
  self.lib.pull(remote, branch)
385
401
  end
386
402
 
data/lib/git/branch.rb CHANGED
@@ -78,7 +78,11 @@ module Git
78
78
  end
79
79
 
80
80
  def update_ref(commit)
81
- @base.lib.update_ref(@full, commit)
81
+ if @remote
82
+ @base.lib.update_ref("refs/remotes/#{@remote.name}/#{@name}", commit)
83
+ else
84
+ @base.lib.update_ref("refs/heads/#{@name}", commit)
85
+ end
82
86
  end
83
87
 
84
88
  def to_a
@@ -114,7 +118,7 @@ module Git
114
118
  # param [String] name branch full name.
115
119
  # return [<Git::Remote,NilClass,String>] an Array containing the remote and branch names.
116
120
  def parse_name(name)
117
- if name.match(/^(?:remotes)?\/([^\/]+)\/(.+)/)
121
+ if name.match(/^(?:remotes\/)?([^\/]+)\/(.+)/)
118
122
  return [Git::Remote.new(@base, $1), $2]
119
123
  end
120
124
 
data/lib/git/lib.rb CHANGED
@@ -347,13 +347,42 @@ module Git
347
347
  command('symbolic-ref', 'HEAD', "refs/heads/#{branch_name}")
348
348
  end
349
349
 
350
+ BRANCH_LINE_REGEXP = /
351
+ ^
352
+ # Prefix indicates if this branch is checked out. The prefix is one of:
353
+ (?:
354
+ (?<current>\*[[:blank:]]) | # Current branch (checked out in the current worktree)
355
+ (?<worktree>\+[[:blank:]]) | # Branch checked out in a different worktree
356
+ [[:blank:]]{2} # Branch not checked out
357
+ )
358
+
359
+ # The branch's full refname
360
+ (?:
361
+ (?<not_a_branch>\(not[[:blank:]]a[[:blank:]]branch\)) |
362
+ (?:\(HEAD[[:blank:]]detached[[:blank:]]at[[:blank:]](?<detached_ref>[^\)]+)\)) |
363
+ (?<refname>[^[[:blank:]]]+)
364
+ )
365
+
366
+ # Optional symref
367
+ # If this ref is a symbolic reference, this is the ref referenced
368
+ (?:
369
+ [[:blank:]]->[[:blank:]](?<symref>.*)
370
+ )?
371
+ $
372
+ /x
373
+
350
374
  def branches_all
351
- arr = []
352
- command_lines('branch', '-a').each do |b|
353
- current = (b[0, 2] == '* ')
354
- arr << [b.gsub('* ', '').strip, current]
355
- end
356
- arr
375
+ command_lines('branch', '-a').map do |line|
376
+ match_data = line.match(BRANCH_LINE_REGEXP)
377
+ raise GitExecuteError, 'Unexpected branch line format' unless match_data
378
+ next nil if match_data[:not_a_branch] || match_data[:detached_ref]
379
+ [
380
+ match_data[:refname],
381
+ !match_data[:current].nil?,
382
+ !match_data[:worktree].nil?,
383
+ match_data[:symref]
384
+ ]
385
+ end.compact
357
386
  end
358
387
 
359
388
  def worktrees_all
@@ -628,16 +657,12 @@ module Git
628
657
  command('add', *arr_opts)
629
658
  end
630
659
 
631
- def remove(path = '.', opts = {})
660
+ def rm(path = '.', opts = {})
632
661
  arr_opts = ['-f'] # overrides the up-to-date check by default
633
- arr_opts << ['-r'] if opts[:recursive]
634
- arr_opts << ['--cached'] if opts[:cached]
662
+ arr_opts << '-r' if opts[:recursive]
663
+ arr_opts << '--cached' if opts[:cached]
635
664
  arr_opts << '--'
636
- if path.is_a?(Array)
637
- arr_opts += path
638
- else
639
- arr_opts << path
640
- end
665
+ arr_opts += Array(path)
641
666
 
642
667
  command('rm', *arr_opts)
643
668
  end
@@ -776,11 +801,16 @@ module Git
776
801
  #
777
802
  # @param [String] branch
778
803
  # @param [Hash] opts
779
- def checkout(branch, opts = {})
804
+ def checkout(branch = nil, opts = {})
805
+ if branch.is_a?(Hash) && opts == {}
806
+ opts = branch
807
+ branch = nil
808
+ end
809
+
780
810
  arr_opts = []
781
811
  arr_opts << '-b' if opts[:new_branch] || opts[:b]
782
812
  arr_opts << '--force' if opts[:force] || opts[:f]
783
- arr_opts << branch
813
+ arr_opts << branch if branch
784
814
  arr_opts << opts[:start_point] if opts[:start_point] && arr_opts.include?('-b')
785
815
 
786
816
  command('checkout', *arr_opts)
@@ -912,26 +942,47 @@ module Git
912
942
  command('fetch', *arr_opts)
913
943
  end
914
944
 
915
- def push(remote, branch = 'master', opts = {})
945
+ def push(remote = nil, branch = nil, opts = nil)
946
+ if opts.nil? && branch.instance_of?(Hash)
947
+ opts = branch
948
+ branch = nil
949
+ end
950
+
951
+ if opts.nil? && remote.instance_of?(Hash)
952
+ opts = remote
953
+ remote = nil
954
+ end
955
+
956
+ opts ||= {}
957
+
916
958
  # Small hack to keep backwards compatibility with the 'push(remote, branch, tags)' method signature.
917
959
  opts = {:tags => opts} if [true, false].include?(opts)
918
960
 
961
+ raise ArgumentError, "You must specify a remote if a branch is specified" if remote.nil? && !branch.nil?
962
+
919
963
  arr_opts = []
920
964
  arr_opts << '--mirror' if opts[:mirror]
921
965
  arr_opts << '--delete' if opts[:delete]
922
966
  arr_opts << '--force' if opts[:force] || opts[:f]
923
- arr_opts << remote
967
+ arr_opts << remote if remote
968
+ arr_opts_with_branch = arr_opts.dup
969
+ arr_opts_with_branch << branch if branch
924
970
 
925
971
  if opts[:mirror]
926
- command('push', *arr_opts)
972
+ command('push', *arr_opts_with_branch)
927
973
  else
928
- command('push', *arr_opts, branch)
974
+ command('push', *arr_opts_with_branch)
929
975
  command('push', '--tags', *arr_opts) if opts[:tags]
930
976
  end
931
977
  end
932
978
 
933
- def pull(remote='origin', branch='master')
934
- command('pull', remote, branch)
979
+ def pull(remote = nil, branch = nil)
980
+ raise ArgumentError, "You must specify a remote if a branch is specified" if remote.nil? && !branch.nil?
981
+
982
+ arr_opts = []
983
+ arr_opts << remote if remote
984
+ arr_opts << branch if branch
985
+ command('pull', *arr_opts)
935
986
  end
936
987
 
937
988
  def tag_sha(tag_name)
@@ -974,8 +1025,8 @@ module Git
974
1025
  command('commit-tree', *arr_opts, redirect: "< #{escape t.path}")
975
1026
  end
976
1027
 
977
- def update_ref(branch, commit)
978
- command('update-ref', branch, commit)
1028
+ def update_ref(ref, commit)
1029
+ command('update-ref', ref, commit)
979
1030
  end
980
1031
 
981
1032
  def checkout_index(opts = {})
@@ -1182,7 +1233,12 @@ module Git
1182
1233
  def log_common_options(opts)
1183
1234
  arr_opts = []
1184
1235
 
1185
- arr_opts << "-#{opts[:count]}" if opts[:count]
1236
+ if opts[:count] && !opts[:count].is_a?(Integer)
1237
+ raise ArgumentError, "The log count option must be an Integer but was #{opts[:count].inspect}"
1238
+ end
1239
+
1240
+ arr_opts << "--max-count=#{opts[:count]}" if opts[:count]
1241
+ arr_opts << "--all" if opts[:all]
1186
1242
  arr_opts << "--no-color"
1187
1243
  arr_opts << "--cherry" if opts[:cherry]
1188
1244
  arr_opts << "--since=#{opts[:since]}" if opts[:since].is_a? String
data/lib/git/log.rb CHANGED
@@ -1,24 +1,19 @@
1
1
  module Git
2
-
2
+
3
3
  # object that holds the last X commits on given branch
4
4
  class Log
5
5
  include Enumerable
6
-
6
+
7
7
  def initialize(base, count = 30)
8
8
  dirty_log
9
9
  @base = base
10
10
  @count = count
11
-
12
- @commits = nil
13
- @author = nil
14
- @grep = nil
15
- @object = nil
16
- @path = nil
17
- @since = nil
18
- @skip = nil
19
- @until = nil
20
- @between = nil
21
- @cherry = nil
11
+ end
12
+
13
+ def all
14
+ dirty_log
15
+ @all = true
16
+ self
22
17
  end
23
18
 
24
19
  def object(objectish)
@@ -32,37 +27,37 @@ module Git
32
27
  @author = regex
33
28
  return self
34
29
  end
35
-
30
+
36
31
  def grep(regex)
37
32
  dirty_log
38
33
  @grep = regex
39
34
  return self
40
35
  end
41
-
36
+
42
37
  def path(path)
43
38
  dirty_log
44
39
  @path = path
45
40
  return self
46
41
  end
47
-
42
+
48
43
  def skip(num)
49
44
  dirty_log
50
45
  @skip = num
51
46
  return self
52
47
  end
53
-
48
+
54
49
  def since(date)
55
50
  dirty_log
56
51
  @since = date
57
52
  return self
58
53
  end
59
-
54
+
60
55
  def until(date)
61
56
  dirty_log
62
57
  @until = date
63
58
  return self
64
59
  end
65
-
60
+
66
61
  def between(sha1, sha2 = nil)
67
62
  dirty_log
68
63
  @between = [sha1, sha2]
@@ -74,24 +69,24 @@ module Git
74
69
  @cherry = true
75
70
  return self
76
71
  end
77
-
72
+
78
73
  def to_s
79
74
  self.map { |c| c.to_s }.join("\n")
80
75
  end
81
-
76
+
82
77
 
83
78
  # forces git log to run
84
-
79
+
85
80
  def size
86
81
  check_log
87
82
  @commits.size rescue nil
88
83
  end
89
-
84
+
90
85
  def each(&block)
91
86
  check_log
92
87
  @commits.each(&block)
93
88
  end
94
-
89
+
95
90
  def first
96
91
  check_log
97
92
  @commits.first rescue nil
@@ -107,29 +102,30 @@ module Git
107
102
  @commits[index] rescue nil
108
103
  end
109
104
 
110
-
111
- private
112
-
105
+
106
+ private
107
+
113
108
  def dirty_log
114
109
  @dirty_flag = true
115
110
  end
116
-
111
+
117
112
  def check_log
118
113
  if @dirty_flag
119
114
  run_log
120
115
  @dirty_flag = false
121
116
  end
122
117
  end
123
-
118
+
124
119
  # actually run the 'git log' command
125
- def run_log
126
- log = @base.lib.full_log_commits(:count => @count, :object => @object,
127
- :path_limiter => @path, :since => @since,
128
- :author => @author, :grep => @grep, :skip => @skip,
129
- :until => @until, :between => @between, :cherry => @cherry)
120
+ def run_log
121
+ log = @base.lib.full_log_commits(
122
+ count: @count, all: @all, object: @object, path_limiter: @path, since: @since,
123
+ author: @author, grep: @grep, skip: @skip, until: @until, between: @between,
124
+ cherry: @cherry
125
+ )
130
126
  @commits = log.map { |c| Git::Object::Commit.new(@base, c['sha'], c) }
131
127
  end
132
-
128
+
133
129
  end
134
-
130
+
135
131
  end
data/lib/git/remote.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Git
2
2
  class Remote < Path
3
-
3
+
4
4
  attr_accessor :name, :url, :fetch_opts
5
-
5
+
6
6
  def initialize(base, name)
7
7
  @base = base
8
8
  config = @base.lib.config_remote(name)
@@ -10,27 +10,29 @@ module Git
10
10
  @url = config['url']
11
11
  @fetch_opts = config['fetch']
12
12
  end
13
-
13
+
14
14
  def fetch(opts={})
15
15
  @base.fetch(@name, opts)
16
16
  end
17
-
17
+
18
18
  # merge this remote locally
19
- def merge(branch = 'master')
20
- @base.merge("#{@name}/#{branch}")
19
+ def merge(branch = @base.current_branch)
20
+ remote_tracking_branch = "#{@name}/#{branch}"
21
+ @base.merge(remote_tracking_branch)
21
22
  end
22
-
23
- def branch(branch = 'master')
24
- Git::Branch.new(@base, "#{@name}/#{branch}")
23
+
24
+ def branch(branch = @base.current_branch)
25
+ remote_tracking_branch = "#{@name}/#{branch}"
26
+ Git::Branch.new(@base, remote_tracking_branch)
25
27
  end
26
-
28
+
27
29
  def remove
28
- @base.lib.remote_remove(@name)
30
+ @base.lib.remote_remove(@name)
29
31
  end
30
-
32
+
31
33
  def to_s
32
34
  @name
33
35
  end
34
-
36
+
35
37
  end
36
38
  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='1.14.0'
4
+ VERSION='1.16.0'
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: 1.14.0
4
+ version: 1.16.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-02-26 00:00:00.000000000 Z
11
+ date: 2023-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable