git 1.8.1 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of git might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4baf98bc2847ece4cb13a4f558b1654facb3c8add9ce58eebb024a139f880742
4
- data.tar.gz: 9c1448896ab666dbe25c38484074fc81814a53fdb6b5e8eac599f58ebdde713b
3
+ metadata.gz: 6dd58567bba3a5effab0e3d3f565f5b3891dcf056ef4df11c1521037bbe9f489
4
+ data.tar.gz: a1f8f9968a3927ce99f393805c34b0ca23941c37f27607d296eaecba9dc0f872
5
5
  SHA512:
6
- metadata.gz: a71409e92d3c79d2c41c2dc693eb031dda63e1d50ddbfcc90c3fea04c30c25341d40a086934f4582f3207fba9a20240c1061ad79a007cdcae19969c9a662c341
7
- data.tar.gz: 78c864391d9dcc90f238d78cd616e65c7ccc0fddd2ae7d0a206e31f5d5726d4945ceecdb201680c9630bc7123b88696b744ae8a5f0a9094f743ac0473106c4dc
6
+ metadata.gz: b1231323bde0b63677f46945800dc950a004cd854bee8c1d5a6711c8709c3dd87fb0c187f54c39c94ae07f92674f27a94b23fe3200a1799992f272c0bd84d315
7
+ data.tar.gz: 8d89a33a9cbee9357f9a4ffb568ec38506749aa81b931f9b2e862af0420c549c1738fde90e48eede6650c3202d31b9463e852eea5b358020b5561e5a60e12ef3
@@ -12,7 +12,7 @@ jobs:
12
12
  strategy:
13
13
  fail-fast: false
14
14
  matrix:
15
- ruby: [2.3, 2.7]
15
+ ruby: [2.3, 2.7, 3.0]
16
16
  operating-system: [ubuntu-latest]
17
17
  include:
18
18
  - ruby: head
@@ -40,3 +40,6 @@ jobs:
40
40
 
41
41
  - name: Run Build
42
42
  run: bundle exec rake default
43
+
44
+ - name: Test Gem
45
+ run: bundle exec rake test:gem
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## 1.10.1
9
+
10
+ See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.1
11
+
12
+ ## 1.10.0
13
+
14
+ See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.0
15
+
16
+ ## 1.9.1
17
+
18
+ See https://github.com/ruby-git/ruby-git/releases/tag/v1.9.1
19
+
20
+ ## 1.9.0
21
+
22
+ See https://github.com/ruby-git/ruby-git/releases/tag/v1.9.0
23
+
8
24
  ## 1.8.1
9
25
 
10
26
  See https://github.com/ruby-git/ruby-git/releases/tag/v1.8.1
data/CONTRIBUTING.md CHANGED
@@ -78,12 +78,14 @@ In order to ensure high quality, all pull requests must meet these requirements:
78
78
 
79
79
  ### Unit tests
80
80
  * All changes must be accompanied by new or modified unit tests
81
- * The entire test suite must pass when `bundle exec rake test` is run from the
82
- project's local working copy
83
-
84
- ### Continuous Integration
85
- * All tests must pass in the project's [Travis CI](https://travis-ci.org/ruby-git/ruby-git)
86
- build before the pull request will be merged
81
+ * The entire test suite must pass when `bundle exec rake default` is run from the
82
+ project's local working copy.
83
+
84
+ ### Continuous integration
85
+ * All tests must pass in the project's [GitHub Continuous Integration build](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI)
86
+ before the pull request will be merged.
87
+ * The [Continuous Integration workflow](https://github.com/ruby-git/ruby-git/blob/master/.github/workflows/continuous_integration.yml)
88
+ runs both `bundle exec rake default` and `bundle exec rake test:gem` from the project's [Rakefile](https://github.com/ruby-git/ruby-git/blob/master/Rakefile).
87
89
 
88
90
  ### Documentation
89
91
  * New and updated public methods must have [YARD](https://yardoc.org/)
@@ -0,0 +1,12 @@
1
+ FROM rust
2
+
3
+ # Build the docker image (from this project's root directory):
4
+ # docker build --file Dockerfile.changelog-rs --tag changelog-rs .
5
+ #
6
+ # Use this image to output a changelog (from this project's root directory):
7
+ # docker run --rm --volume "$PWD:/worktree" changelog-rs v1.9.1 v1.10.0
8
+
9
+ RUN cargo install changelog-rs
10
+ WORKDIR /worktree
11
+
12
+ ENTRYPOINT ["/usr/local/cargo/bin/changelog-rs", "/worktree"]
data/README.md CHANGED
@@ -146,6 +146,7 @@ g.revparse('v2.5:Makefile')
146
146
 
147
147
  g.branches # returns Git::Branch objects
148
148
  g.branches.local
149
+ g.current_branch
149
150
  g.branches.remote
150
151
  g.branches[:master].gcommit
151
152
  g.branches['origin/master'].gcommit
@@ -225,6 +226,14 @@ g.remove('file.txt', :cached => true) # git rm -f --cached -- "file.txt"
225
226
  g.commit('message')
226
227
  g.commit_all('message')
227
228
 
229
+ # Sign a commit using the gpg key configured in the user.signingkey config setting
230
+ g.config('user.signingkey', '0A46826A')
231
+ g.commit('message', gpg_sign: true)
232
+
233
+ # Sign a commit using a specified gpg key
234
+ key_id = '0A46826A'
235
+ g.commit('message', gpg_sign: key_id)
236
+
228
237
  g = Git.clone(repo, 'myrepo')
229
238
  g.chdir do
230
239
  new_file('test-file', 'blahblahblah')
data/RELEASING.md CHANGED
@@ -6,9 +6,11 @@
6
6
  # How to release a new git.gem
7
7
 
8
8
  Releasing a new version of the `git` gem requires these steps:
9
- * [Prepare the release](#prepare-the-release)
10
- * [Create a GitHub release](#create-a-github-release)
11
- * [Build and release the gem](#build-and-release-the-gem)
9
+
10
+ - [How to release a new git.gem](#how-to-release-a-new-gitgem)
11
+ - [Prepare the release](#prepare-the-release)
12
+ - [Create a GitHub release](#create-a-github-release)
13
+ - [Build and release the gem](#build-and-release-the-gem)
12
14
 
13
15
  These instructions use an example where the current release version is `1.5.0`
14
16
  and the new release version to be created is `1.6.0.pre1`.
@@ -18,45 +20,49 @@ and the new release version to be created is `1.6.0.pre1`.
18
20
  From a fork of ruby-git, create a PR containing changes to (1) bump the
19
21
  version number, (2) update the CHANGELOG.md, and (3) tag the release.
20
22
 
21
- * Bump the version number in lib/git/version.rb following [Semantic Versioning](https://semver.org)
22
- guidelines
23
- * Add a link in CHANGELOG.md to the release tag which will be created later
24
- in this guide
25
- * Create a new tag using [git-extras](https://github.com/tj/git-extras/blob/master/Commands.md#git-release)
26
- `git release` command
27
- * For example: `git release v1.6.0.pre1`
28
- * These should be the only changes in the PR
29
- * An example of these changes for `v1.6.0.pre1` can be found in [PR #435](https://github.com/ruby-git/ruby-git/pull/435)
30
- * Get the PR reviewed, approved and merged to master.
23
+ - Bump the version number in lib/git/version.rb following [Semantic Versioning](https://semver.org)
24
+ guidelines
25
+ - Add a link in CHANGELOG.md to the release tag which will be created later
26
+ in this guide
27
+ - Create a new tag using [git-extras](https://github.com/tj/git-extras/blob/master/Commands.md#git-release)
28
+ `git release` command
29
+ - For example: `git release v1.6.0.pre1`
30
+ - These should be the only changes in the PR
31
+ - An example of these changes for `v1.6.0.pre1` can be found in [PR #435](https://github.com/ruby-git/ruby-git/pull/435)
32
+ - Get the PR reviewed, approved and merged to master.
31
33
 
32
34
  ## Create a GitHub release
33
35
 
34
36
  On [the ruby-git releases page](https://github.com/ruby-git/ruby-git/releases),
35
37
  select `Draft a new release`
36
38
 
37
- * Select the tag corresponding to the version being released `v1.6.0.pre1`
38
- * The Target should be `master`
39
- * For the release description, use the output of [changelog-rs](https://github.com/perlun/changelog-rs)
40
- * Since the release has not been created yet, you will need to supply
41
- `changeling-rs` with the current release tag and the tag the new release
42
- is being created from
43
- * For example: `changelog-rs . v1.5.0 v1.6.0.pre1`
44
- * Copy the output, omitting the tag header `## v1.6.0.pre1` and paste into
45
- the release description
46
- * The release description can be edited later if needed
47
- * Select the appropriate value for `This is a pre-release`
48
- * Since `v1.6.0.pre1` is a pre-release, check `This is a pre-release`
39
+ - Select the tag corresponding to the version being released `v1.6.0.pre1`
40
+ - The Target should be `master`
41
+ - For the release description, use the output of [changelog-rs](https://github.com/perlun/changelog-rs)
42
+ - A Docker image is provided in [Dockerfile.changelog-rs](https://github.com/ruby-git/ruby-git/blob/master/Dockerfile.changelog-rs)
43
+ so you don't have to install changelog-rs or the Rust tool chain. To build the
44
+ Docker image, run this command from this project's root directory:
45
+ - `docker build --file Dockerfile.changelog-rs --tag changelog-rs .`
46
+ - To run the changelog-rs command using this image, run the following command
47
+ from this project's root directory (replace the tag names appropriate for the
48
+ current release):
49
+ - `docker run --rm --volume "$PWD:/worktree" changelog-rs v1.5.0 v1.6.0.pre1`
50
+ - Copy the output, omitting the tag header `## v1.6.0.pre1` and paste into
51
+ the release description
52
+ - The release description can be edited later if needed
53
+ - Select the appropriate value for `This is a pre-release`
54
+ - Since `v1.6.0.pre1` is a pre-release, check `This is a pre-release`
49
55
 
50
56
  ## Build and release the gem
51
57
 
52
58
  Clone [ruby-git/ruby-git](https://github.com/ruby-git/ruby-git) directly (not a
53
59
  fork) and ensure your local working copy is on the master branch
54
60
 
55
- * Verify that you are not on a fork with the command `git remote -v`
56
- * Verify that the version number is correct by running `rake -T` and inspecting
57
- the output for the `release[remote]` task
61
+ - Verify that you are not on a fork with the command `git remote -v`
62
+ - Verify that the version number is correct by running `rake -T` and inspecting
63
+ the output for the `release[remote]` task
58
64
 
59
65
  Build the git gem and push it to rubygems.org with the command `rake release`
60
66
 
61
- * Ensure that your `gem sources list` includes `https://rubygems.org` (in my
62
- case, I usually have my work’s internal gem repository listed)
67
+ - Ensure that your `gem sources list` includes `https://rubygems.org` (in my
68
+ case, I usually have my work’s internal gem repository listed)
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'English'
2
3
 
3
4
  require "#{File.expand_path(File.dirname(__FILE__))}/lib/git/version"
4
5
 
@@ -41,4 +42,15 @@ unless RUBY_PLATFORM == 'java'
41
42
  # default_tasks << :yardstick
42
43
  end
43
44
 
45
+ default_tasks << :build
46
+
44
47
  task default: default_tasks
48
+
49
+ desc 'Build and install the git gem and run a sanity check'
50
+ task :'test:gem' => :install do
51
+ output = `ruby -e "require 'git'; g = Git.open('.'); puts g.log.size"`.chomp
52
+ raise 'Gem test failed' unless $CHILD_STATUS.success?
53
+ raise 'Expected gem test to return an integer' unless output =~ /^\d+$/
54
+
55
+ puts 'Gem Test Succeeded'
56
+ end
data/lib/git/base.rb CHANGED
@@ -12,40 +12,35 @@ module Git
12
12
 
13
13
  # (see Git.bare)
14
14
  def self.bare(git_dir, options = {})
15
- self.new({:repository => git_dir}.merge(options))
15
+ normalize_paths(options, default_repository: git_dir, bare: true)
16
+ self.new(options)
16
17
  end
17
18
 
18
19
  # (see Git.clone)
19
20
  def self.clone(repository, name, options = {})
20
- self.new(Git::Lib.new(nil, options[:log]).clone(repository, name, options))
21
+ new_options = Git::Lib.new(nil, options[:log]).clone(repository, name, options)
22
+ normalize_paths(new_options, bare: options[:bare] || options[:mirror])
23
+ self.new(new_options)
21
24
  end
22
25
 
23
26
  # Returns (and initialize if needed) a Git::Config instance
24
27
  #
25
28
  # @return [Git::Config] the current config instance.
26
29
  def self.config
27
- return @@config ||= Config.new
30
+ @@config ||= Config.new
28
31
  end
29
32
 
30
33
  # (see Git.init)
31
- def self.init(directory, options = {})
32
- options[:working_directory] ||= directory
33
- options[:repository] ||= File.join(options[:working_directory], '.git')
34
-
35
- FileUtils.mkdir_p(options[:working_directory]) if options[:working_directory] && !File.directory?(options[:working_directory])
34
+ def self.init(directory = '.', options = {})
35
+ normalize_paths(options, default_working_directory: directory, default_repository: directory, bare: options[:bare])
36
36
 
37
- init_options = { :bare => options[:bare] }
37
+ init_options = {
38
+ :bare => options[:bare],
39
+ :initial_branch => options[:initial_branch]
40
+ }
38
41
 
39
- options.delete(:working_directory) if options[:bare]
40
-
41
- # Submodules have a .git *file* not a .git folder.
42
- # This file's contents point to the location of
43
- # where the git refs are held (In the parent repo)
44
- if options[:working_directory] && File.file?(File.join(options[:working_directory], '.git'))
45
- git_file = File.open('.git').read[8..-1].strip
46
- options[:repository] = git_file
47
- options[:index] = git_file + '/index'
48
- end
42
+ directory = options[:bare] ? options[:repository] : options[:working_directory]
43
+ FileUtils.mkdir_p(directory) unless File.exist?(directory)
49
44
 
50
45
  # TODO: this dance seems awkward: this creates a Git::Lib so we can call
51
46
  # init so we can create a new Git::Base which in turn (ultimately)
@@ -63,21 +58,8 @@ module Git
63
58
  end
64
59
 
65
60
  # (see Git.open)
66
- def self.open(working_dir, options={})
67
- # TODO: move this to Git.open?
68
-
69
- options[:working_directory] ||= working_dir
70
- options[:repository] ||= File.join(options[:working_directory], '.git')
71
-
72
- # Submodules have a .git *file* not a .git folder.
73
- # This file's contents point to the location of
74
- # where the git refs are held (In the parent repo)
75
- if options[:working_directory] && File.file?(File.join(options[:working_directory], '.git'))
76
- git_file = File.open('.git').read[8..-1].strip
77
- options[:repository] = git_file
78
- options[:index] = git_file + '/index'
79
- end
80
-
61
+ def self.open(working_dir, options = {})
62
+ normalize_paths(options, default_working_directory: working_dir)
81
63
  self.new(options)
82
64
  end
83
65
 
@@ -137,13 +119,14 @@ module Git
137
119
 
138
120
  #g.config('user.name', 'Scott Chacon') # sets value
139
121
  #g.config('user.email', 'email@email.com') # sets value
122
+ #g.config('user.email', 'email@email.com', file: 'path/to/custom/config) # sets value in file
140
123
  #g.config('user.name') # returns 'Scott Chacon'
141
124
  #g.config # returns whole config hash
142
- def config(name = nil, value = nil)
143
- if(name && value)
125
+ def config(name = nil, value = nil, options = {})
126
+ if name && value
144
127
  # set value
145
- lib.config_set(name, value)
146
- elsif (name)
128
+ lib.config_set(name, value, options)
129
+ elsif name
147
130
  # return value
148
131
  lib.config_get(name)
149
132
  else
@@ -286,6 +269,7 @@ module Git
286
269
  # options:
287
270
  # :force
288
271
  # :d
272
+ # :ff
289
273
  #
290
274
  def clean(opts = {})
291
275
  self.lib.clean(opts)
@@ -387,7 +371,7 @@ module Git
387
371
  # @git.pull('upstream', 'develope') # pulls from upstream/develop
388
372
  #
389
373
  def pull(remote='origin', branch='master')
390
- self.lib.pull(remote, branch)
374
+ self.lib.pull(remote, branch)
391
375
  end
392
376
 
393
377
  # returns an array of Git:Remote objects
@@ -566,7 +550,6 @@ module Git
566
550
  with_working(temp_dir, &blk)
567
551
  end
568
552
 
569
-
570
553
  # runs git rev-parse to convert the objectish to a full sha
571
554
  #
572
555
  # @example
@@ -591,6 +574,93 @@ module Git
591
574
  self.lib.branch_current
592
575
  end
593
576
 
594
- end
577
+ private
578
+
579
+ # Normalize options before they are sent to Git::Base.new
580
+ #
581
+ # Updates the options parameter by setting appropriate values for the following keys:
582
+ # * options[:working_directory]
583
+ # * options[:repository]
584
+ # * options[:index]
585
+ #
586
+ # All three values will be set to absolute paths. An exception is that
587
+ # :working_directory will be set to nil if bare is true.
588
+ #
589
+ private_class_method def self.normalize_paths(
590
+ options, default_working_directory: nil, default_repository: nil, bare: false
591
+ )
592
+ normalize_working_directory(options, default: default_working_directory, bare: bare)
593
+ normalize_repository(options, default: default_repository, bare: bare)
594
+ normalize_index(options)
595
+ end
596
+
597
+ # Normalize options[:working_directory]
598
+ #
599
+ # If working with a bare repository, set to `nil`.
600
+ # Otherwise, set to the first non-nil value of:
601
+ # 1. `options[:working_directory]`,
602
+ # 2. the `default` parameter, or
603
+ # 3. the current working directory
604
+ #
605
+ # Finally, if options[:working_directory] is a relative path, convert it to an absoluite
606
+ # path relative to the current directory.
607
+ #
608
+ private_class_method def self.normalize_working_directory(options, default:, bare: false)
609
+ working_directory =
610
+ if bare
611
+ nil
612
+ else
613
+ File.expand_path(options[:working_directory] || default || Dir.pwd)
614
+ end
595
615
 
616
+ options[:working_directory] = working_directory
617
+ end
618
+
619
+ # Normalize options[:repository]
620
+ #
621
+ # If working with a bare repository, set to the first non-nil value out of:
622
+ # 1. `options[:repository]`
623
+ # 2. the `default` parameter
624
+ # 3. the current working directory
625
+ #
626
+ # Otherwise, set to the first non-nil value of:
627
+ # 1. `options[:repository]`
628
+ # 2. `.git`
629
+ #
630
+ # Next, if options[:repository] refers to a *file* and not a *directory*, set
631
+ # options[:repository] to the contents of that file. This is the case when
632
+ # working with a submodule or a secondary working tree (created with git worktree
633
+ # add). In these cases the repository is actually contained/nested within the
634
+ # parent's repository directory.
635
+ #
636
+ # Finally, if options[:repository] is a relative path, convert it to an absolute
637
+ # path relative to:
638
+ # 1. the current directory if working with a bare repository or
639
+ # 2. the working directory if NOT working with a bare repository
640
+ #
641
+ private_class_method def self.normalize_repository(options, default:, bare: false)
642
+ repository =
643
+ if bare
644
+ File.expand_path(options[:repository] || default || Dir.pwd)
645
+ else
646
+ File.expand_path(options[:repository] || '.git', options[:working_directory])
647
+ end
648
+
649
+ if File.file?(repository)
650
+ repository = File.expand_path(File.open(repository).read[8..-1].strip, options[:working_directory])
651
+ end
652
+
653
+ options[:repository] = repository
654
+ end
655
+
656
+ # Normalize options[:index]
657
+ #
658
+ # If options[:index] is a relative directory, convert it to an absolute
659
+ # directory relative to the repository directory
660
+ #
661
+ private_class_method def self.normalize_index(options)
662
+ index = File.expand_path(options[:index] || 'index', options[:repository])
663
+ options[:index] = index
664
+ end
665
+ end
596
666
  end
data/lib/git/diff.rb CHANGED
@@ -129,8 +129,8 @@ module Git
129
129
  final = {}
130
130
  current_file = nil
131
131
  @full_diff.split("\n").each do |line|
132
- if m = /^diff --git a\/(.*?) b\/(.*?)/.match(line)
133
- current_file = m[1]
132
+ if m = %r{\Adiff --git ("?)a/(.+?)\1 ("?)b/(.+?)\3\z}.match(line)
133
+ current_file = Git::EscapedPath.new(m[2]).unescape
134
134
  final[current_file] = defaults.merge({:patch => line, :path => current_file})
135
135
  else
136
136
  if m = /^index ([0-9a-f]{4,40})\.\.([0-9a-f]{4,40})( ......)*/.match(line)
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rchardet'
4
+
5
+ module Git
6
+ # Method that can be used to detect and normalize string encoding
7
+ module EncodingUtils
8
+ def self.default_encoding
9
+ __ENCODING__.name
10
+ end
11
+
12
+ def self.best_guess_encoding
13
+ # Encoding::ASCII_8BIT.name
14
+ Encoding::UTF_8.name
15
+ end
16
+
17
+ def self.detected_encoding(str)
18
+ CharDet.detect(str)['encoding'] || best_guess_encoding
19
+ end
20
+
21
+ def self.encoding_options
22
+ { invalid: :replace, undef: :replace }
23
+ end
24
+
25
+ def self.normalize_encoding(str)
26
+ return str if str.valid_encoding? && str.encoding.name == default_encoding
27
+
28
+ return str.encode(default_encoding, str.encoding, **encoding_options) if str.valid_encoding?
29
+
30
+ str.encode(default_encoding, detected_encoding(str), **encoding_options)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Git
4
+ # Represents an escaped Git path string
5
+ #
6
+ # Git commands that output paths (e.g. ls-files, diff), will escape usual
7
+ # characters in the path with backslashes in the same way C escapes control
8
+ # characters (e.g. \t for TAB, \n for LF, \\ for backslash) or bytes with values
9
+ # larger than 0x80 (e.g. octal \302\265 for "micro" in UTF-8).
10
+ #
11
+ # @example
12
+ # Git::GitPath.new('\302\265').unescape # => "µ"
13
+ #
14
+ class EscapedPath
15
+ UNESCAPES = {
16
+ 'a' => 0x07,
17
+ 'b' => 0x08,
18
+ 't' => 0x09,
19
+ 'n' => 0x0a,
20
+ 'v' => 0x0b,
21
+ 'f' => 0x0c,
22
+ 'r' => 0x0d,
23
+ 'e' => 0x1b,
24
+ '\\' => 0x5c,
25
+ '"' => 0x22,
26
+ "'" => 0x27
27
+ }.freeze
28
+
29
+ attr_reader :path
30
+
31
+ def initialize(path)
32
+ @path = path
33
+ end
34
+
35
+ # Convert an escaped path to an unescaped path
36
+ def unescape
37
+ bytes = escaped_path_to_bytes(path)
38
+ str = bytes.pack('C*')
39
+ str.force_encoding(Encoding::UTF_8)
40
+ end
41
+
42
+ private
43
+
44
+ def extract_octal(path, index)
45
+ [path[index + 1..index + 4].to_i(8), 4]
46
+ end
47
+
48
+ def extract_escape(path, index)
49
+ [UNESCAPES[path[index + 1]], 2]
50
+ end
51
+
52
+ def extract_single_char(path, index)
53
+ [path[index].ord, 1]
54
+ end
55
+
56
+ def next_byte(path, index)
57
+ if path[index] == '\\' && path[index + 1] >= '0' && path[index + 1] <= '7'
58
+ extract_octal(path, index)
59
+ elsif path[index] == '\\' && UNESCAPES.include?(path[index + 1])
60
+ extract_escape(path, index)
61
+ else
62
+ extract_single_char(path, index)
63
+ end
64
+ end
65
+
66
+ def escaped_path_to_bytes(path)
67
+ index = 0
68
+ [].tap do |bytes|
69
+ while index < path.length
70
+ byte, chars_used = next_byte(path, index)
71
+ bytes << byte
72
+ index += chars_used
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
data/lib/git/lib.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'rchardet'
2
1
  require 'tempfile'
3
2
  require 'zlib'
4
3
 
@@ -71,10 +70,12 @@ module Git
71
70
  # options:
72
71
  # :bare
73
72
  # :working_directory
73
+ # :initial_branch
74
74
  #
75
75
  def init(opts={})
76
76
  arr_opts = []
77
77
  arr_opts << '--bare' if opts[:bare]
78
+ arr_opts << "--initial-branch=#{opts[:initial_branch]}" if opts[:initial_branch]
78
79
 
79
80
  command('init', arr_opts)
80
81
  end
@@ -583,8 +584,12 @@ module Git
583
584
 
584
585
  ## WRITE COMMANDS ##
585
586
 
586
- def config_set(name, value)
587
- command('config', name, value)
587
+ def config_set(name, value, options = {})
588
+ if options[:file].to_s.empty?
589
+ command('config', name, value)
590
+ else
591
+ command('config', '--file', options[:file], name, value)
592
+ end
588
593
  end
589
594
 
590
595
  def global_config_set(name, value)
@@ -642,6 +647,7 @@ module Git
642
647
  # :date
643
648
  # :no_verify
644
649
  # :allow_empty_message
650
+ # :gpg_sign
645
651
  #
646
652
  # @param [String] message the commit message to be used
647
653
  # @param [Hash] opts the commit options to be used
@@ -655,6 +661,14 @@ module Git
655
661
  arr_opts << "--date=#{opts[:date]}" if opts[:date].is_a? String
656
662
  arr_opts << '--no-verify' if opts[:no_verify]
657
663
  arr_opts << '--allow-empty-message' if opts[:allow_empty_message]
664
+ if opts[:gpg_sign]
665
+ arr_opts <<
666
+ if opts[:gpg_sign] == true
667
+ '--gpg-sign'
668
+ else
669
+ "--gpg-sign=#{opts[:gpg_sign]}"
670
+ end
671
+ end
658
672
 
659
673
  command('commit', arr_opts)
660
674
  end
@@ -669,6 +683,7 @@ module Git
669
683
  def clean(opts = {})
670
684
  arr_opts = []
671
685
  arr_opts << '--force' if opts[:force]
686
+ arr_opts << '-ff' if opts[:ff]
672
687
  arr_opts << '-d' if opts[:d]
673
688
  arr_opts << '-x' if opts[:x]
674
689
 
@@ -759,6 +774,7 @@ module Git
759
774
 
760
775
  def merge(branch, message = nil, opts = {})
761
776
  arr_opts = []
777
+ arr_opts << '--no-commit' if opts[:no_commit]
762
778
  arr_opts << '--no-ff' if opts[:no_ff]
763
779
  arr_opts << '-m' << message if message
764
780
  arr_opts += [branch]
@@ -866,6 +882,7 @@ module Git
866
882
  arr_opts << '--tags' if opts[:t] || opts[:tags]
867
883
  arr_opts << '--prune' if opts[:p] || opts[:prune]
868
884
  arr_opts << '--unshallow' if opts[:unshallow]
885
+ arr_opts << '--depth' << opts[:depth] if opts[:depth]
869
886
 
870
887
  command('fetch', arr_opts)
871
888
  end
@@ -1067,7 +1084,8 @@ module Git
1067
1084
  global_opts = []
1068
1085
  global_opts << "--git-dir=#{@git_dir}" if !@git_dir.nil?
1069
1086
  global_opts << "--work-tree=#{@git_work_dir}" if !@git_work_dir.nil?
1070
- global_opts << ["-c", "color.ui=false"]
1087
+ global_opts << %w[-c core.quotePath=true]
1088
+ global_opts << %w[-c color.ui=false]
1071
1089
 
1072
1090
  opts = [opts].flatten.map {|s| escape(s) }.join(' ')
1073
1091
 
@@ -1158,35 +1176,10 @@ module Git
1158
1176
  arr_opts
1159
1177
  end
1160
1178
 
1161
- def default_encoding
1162
- __ENCODING__.name
1163
- end
1164
-
1165
- def best_guess_encoding
1166
- # Encoding::ASCII_8BIT.name
1167
- Encoding::UTF_8.name
1168
- end
1169
-
1170
- def detected_encoding(str)
1171
- CharDet.detect(str)['encoding'] || best_guess_encoding
1172
- end
1173
-
1174
- def encoding_options
1175
- { invalid: :replace, undef: :replace }
1176
- end
1177
-
1178
- def normalize_encoding(str)
1179
- return str if str.valid_encoding? && str.encoding.name == default_encoding
1180
-
1181
- return str.encode(default_encoding, str.encoding, **encoding_options) if str.valid_encoding?
1182
-
1183
- str.encode(default_encoding, detected_encoding(str), **encoding_options)
1184
- end
1185
-
1186
1179
  def run_command(git_cmd, &block)
1187
1180
  return IO.popen(git_cmd, &block) if block_given?
1188
1181
 
1189
- `#{git_cmd}`.lines.map { |l| normalize_encoding(l) }.join
1182
+ `#{git_cmd}`.lines.map { |l| Git::EncodingUtils.normalize_encoding(l) }.join
1190
1183
  end
1191
1184
 
1192
1185
  def escape(s)
@@ -1198,8 +1191,9 @@ module Git
1198
1191
  end
1199
1192
 
1200
1193
  def escape_for_windows(s)
1201
- # Windows does not need single quote escaping inside double quotes
1202
- %Q{"#{s}"}
1194
+ # Escape existing double quotes in s and then wrap the result with double quotes
1195
+ escaped_string = s.to_s.gsub('"','\\"')
1196
+ %Q{"#{escaped_string}"}
1203
1197
  end
1204
1198
 
1205
1199
  def windows_platform?
@@ -1207,6 +1201,5 @@ module Git
1207
1201
  win_platform_regex = /mingw|mswin/
1208
1202
  RUBY_PLATFORM =~ win_platform_regex || RUBY_DESCRIPTION =~ win_platform_regex
1209
1203
  end
1210
-
1211
1204
  end
1212
1205
  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.8.1'
4
+ VERSION='1.10.1'
5
5
  end
data/lib/git.rb CHANGED
@@ -9,6 +9,8 @@ require 'git/branch'
9
9
  require 'git/branches'
10
10
  require 'git/config'
11
11
  require 'git/diff'
12
+ require 'git/encoding_utils'
13
+ require 'git/escaped_path'
12
14
  require 'git/index'
13
15
  require 'git/lib'
14
16
  require 'git/log'
@@ -212,6 +214,9 @@ module Git
212
214
  # `"#{directory}/.git"`, create a bare repository at `"#{directory}"`.
213
215
  # See [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository).
214
216
  #
217
+ # @option options [String] :initial_branch Use the specified name for the
218
+ # initial branch in the newly created repository.
219
+ #
215
220
  # @option options [Pathname] :repository the path to put the newly initialized
216
221
  # Git repository. The default for non-bare repository is `"#{directory}/.git"`.
217
222
  #
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.8.1
4
+ version: 1.10.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: 2020-12-31 00:00:00.000000000 Z
11
+ date: 2022-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rchardet
@@ -125,6 +125,7 @@ files:
125
125
  - ".yardopts"
126
126
  - CHANGELOG.md
127
127
  - CONTRIBUTING.md
128
+ - Dockerfile.changelog-rs
128
129
  - Gemfile
129
130
  - ISSUE_TEMPLATE.md
130
131
  - LICENSE
@@ -142,6 +143,8 @@ files:
142
143
  - lib/git/branches.rb
143
144
  - lib/git/config.rb
144
145
  - lib/git/diff.rb
146
+ - lib/git/encoding_utils.rb
147
+ - lib/git/escaped_path.rb
145
148
  - lib/git/index.rb
146
149
  - lib/git/lib.rb
147
150
  - lib/git/log.rb
@@ -179,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
182
  version: '0'
180
183
  requirements:
181
184
  - git 1.6.0.0, or greater
182
- rubygems_version: 3.1.4
185
+ rubygems_version: 3.1.6
183
186
  signing_key:
184
187
  specification_version: 4
185
188
  summary: An API to create, read, and manipulate Git repositories