diff --git a/CHANGELOG.md b/CHANGELOG.md index 9711c891..c3c3bd4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ # Change Log +## v1.13.0 (2022-12-10) + +[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.12.0...v1.13.0) + +* 8349224 Update list of maintainers (#598) +* 4fe8738 In ls-files do not unescape file paths with eval (#602) +* 74b8e11 Add start_point option for checkout command (#597) +* ff6dcf4 Do not assume the default branch is 'master' in tests +* 8279298 Fix exception when Git is autoloaded (#594) + ## v1.12.0 See https://github.com/ruby-git/ruby-git/releases/tag/v1.12.0 @@ -151,4 +161,3 @@ See https://github.com/ruby-git/ruby-git/releases/tag/v1.4.0 ## 1.0.1 * Initial version - diff --git a/MAINTAINERS.md b/MAINTAINERS.md index ef13361f..7290f137 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -7,7 +7,6 @@ When making changes in this repository, one of the maintainers below must review and approve your pull request. -### Maintainers - +* [James Couball](https://github.com/jcouball) +* [Frank Throckmorton](https://github.com/frankthrock) * [Per Lundberg](https://github.com/perlun) -* [James Couball](https://github.com/jcouball) \ No newline at end of file diff --git a/README.md b/README.md index db38fbf6..df3b3e4b 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,7 @@ g.branch('existing_branch').checkout g.branch('master').contains?('existing_branch') g.checkout('new_branch') +g.checkout('new_branch', new_branch: true, start_point: 'master') g.checkout(g.branch('new_branch')) g.branch(name).merge(branch2) diff --git a/lib/git.rb b/lib/git.rb index 1da03ce5..fe38972f 100644 --- a/lib/git.rb +++ b/lib/git.rb @@ -27,11 +27,6 @@ require 'git/worktree' require 'git/worktrees' -lib = Git::Lib.new(nil, nil) -unless lib.meets_required_version? - $stderr.puts "[WARNING] The git gem requires git #{lib.required_command_version.join('.')} or later, but only found #{lib.current_command_version.join('.')}. You should probably upgrade." -end - # The Git module provides the basic functions to open a git # reference to work with. You can open a working directory, # open a bare repository, initialize a new repo or clone an diff --git a/lib/git/lib.rb b/lib/git/lib.rb index fce8b274..293f2878 100644 --- a/lib/git/lib.rb +++ b/lib/git/lib.rb @@ -63,6 +63,8 @@ def initialize(base = nil, logger = nil) @git_work_dir = base[:working_directory] end @logger = logger + + Git::Lib.warn_if_old_command(self) end # creates or reinitializes the repository @@ -486,7 +488,9 @@ def ls_files(location=nil) command_lines('ls-files', '--stage', location).each do |line| (info, file) = line.split("\t") (mode, sha, stage) = info.split - file = eval(file) if file =~ /^\".*\"$/ # This takes care of quoted strings returned from git + if file.start_with?('"') && file.end_with?('"') + file = Git::EscapedPath.new(file[1..-2]).unescape + end hsh[file] = {:path => file, :mode_index => mode, :sha_index => sha, :stage => stage} end hsh @@ -762,11 +766,21 @@ def branch_delete(branch) command('branch', '-D', branch) end + # Runs checkout command to checkout or create branch + # + # accepts options: + # :new_branch + # :force + # :start_point + # + # @param [String] branch + # @param [Hash] opts def checkout(branch, opts = {}) arr_opts = [] arr_opts << '-b' if opts[:new_branch] || opts[:b] arr_opts << '--force' if opts[:force] || opts[:f] arr_opts << branch + arr_opts << opts[:start_point] if opts[:start_point] && arr_opts.include?('-b') command('checkout', arr_opts) end @@ -1027,6 +1041,13 @@ def meets_required_version? (self.current_command_version <=> self.required_command_version) >= 0 end + def self.warn_if_old_command(lib) + return true if @version_checked + unless lib.meets_required_version? + $stderr.puts "[WARNING] The git gem requires git #{lib.required_command_version.join('.')} or later, but only found #{lib.current_command_version.join('.')}. You should probably upgrade." + end + @version_checked = true + end private diff --git a/lib/git/version.rb b/lib/git/version.rb index 52159024..bd53cc7c 100644 --- a/lib/git/version.rb +++ b/lib/git/version.rb @@ -1,5 +1,5 @@ module Git # The current gem version # @return [String] the current gem version. - VERSION='1.12.0' + VERSION='1.13.0' end diff --git a/tests/all_tests.rb b/tests/all_tests.rb index 60bac481..ff3ade79 100644 --- a/tests/all_tests.rb +++ b/tests/all_tests.rb @@ -1,5 +1,8 @@ Dir.chdir(File.dirname(__FILE__)) do - Dir.glob('**/test_*.rb') do |test_case| - require "#{File.expand_path(File.dirname(__FILE__))}/#{test_case}" + Dir.glob('**/test_*.rb') do |test_case| + require "#{File.expand_path(File.dirname(__FILE__))}/#{test_case}" end end + +# To run a single test: +# require_relative 'units/test_lib_meets_required_version' diff --git a/tests/units/test_init.rb b/tests/units/test_init.rb index 4ec4771d..596d42bb 100644 --- a/tests/units/test_init.rb +++ b/tests/units/test_init.rb @@ -38,7 +38,10 @@ def test_git_init assert(File.directory?(File.join(path, '.git'))) assert(File.exist?(File.join(path, '.git', 'config'))) assert_equal('false', repo.config('core.bare')) - assert_equal("ref: refs/heads/master\n", File.read("#{path}/.git/HEAD")) + + branch = `git config --get init.defaultBranch`.strip + branch = 'master' if branch.empty? + assert_equal("ref: refs/heads/#{branch}\n", File.read("#{path}/.git/HEAD")) end end diff --git a/tests/units/test_lib.rb b/tests/units/test_lib.rb index 71acd21e..f886a400 100644 --- a/tests/units/test_lib.rb +++ b/tests/units/test_lib.rb @@ -87,6 +87,19 @@ def test_checkout assert(@lib.checkout('master')) end + def test_checkout_with_start_point + assert(@lib.reset(nil, hard: true)) # to get around worktree status on windows + + actual_cmd = nil + @lib.define_singleton_method(:run_command) do |git_cmd, &block| + actual_cmd = git_cmd + super(git_cmd, &block) + end + + assert(@lib.checkout('test_checkout_b2', {new_branch: true, start_point: 'master'})) + assert_match(%r/checkout ['"]-b['"] ['"]test_checkout_b2['"] ['"]master['"]/, actual_cmd) + end + # takes parameters, returns array of appropriate commit objects # :count # :since diff --git a/tests/units/test_lib_meets_required_version.rb b/tests/units/test_lib_meets_required_version.rb new file mode 100644 index 00000000..fce57241 --- /dev/null +++ b/tests/units/test_lib_meets_required_version.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../test_helper' + +class TestLibMeetsRequiredVersion < Test::Unit::TestCase + def test_with_supported_command_version + lib = Git::Lib.new(nil, nil) + major_version, minor_version = lib.required_command_version + lib.define_singleton_method(:current_command_version) { [major_version, minor_version] } + assert lib.meets_required_version? + end + + def test_with_old_command_version + lib = Git::Lib.new(nil, nil) + major_version, minor_version = lib.required_command_version + + # Set the major version to be returned by #current_command_version to be an + # earlier version than required + major_version = major_version - 1 + + lib.define_singleton_method(:current_command_version) { [major_version, minor_version] } + assert !lib.meets_required_version? + end +end diff --git a/tests/units/test_ls_files_with_escaped_path.rb b/tests/units/test_ls_files_with_escaped_path.rb new file mode 100644 index 00000000..47607dd3 --- /dev/null +++ b/tests/units/test_ls_files_with_escaped_path.rb @@ -0,0 +1,22 @@ +#!/usr/bin/env ruby +# encoding: utf-8 + +require File.dirname(__FILE__) + '/../test_helper' + +# Test diff when the file path has to be quoted according to core.quotePath +# See https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath +# +class TestLsFilesWithEscapedPath < Test::Unit::TestCase + def test_diff_with_non_ascii_filename + in_temp_dir do |path| + create_file('my_other_file_☠', "First Line\n") + create_file('README.md', '# My Project') + `git init` + `git add .` + `git config --local core.safecrlf false` if Gem.win_platform? + `git commit -m "First Commit"` + paths = Git.open('.').ls_files.keys.sort + assert_equal(["my_other_file_☠", 'README.md'].sort, paths) + end + end +end