require 'active_support/deprecation' module Git # An object used to manage deprecations # # A ActiveSupport::Deprecation object used to manage the deprecations scheduled # to be removed in the next major release of the `git`` gem. # # @example Deprecate a method # Git.deprecation.deprecate_methods(Git::Branch, stashes: 'use Git::Base#stash_list instead') # # @example Set the deprecation behavior # # Log all deprecation warnings to $stderr (the default) # Git.deprecation.behavior = :stderr # # # Raise an ActiveSupport::DeprecationException # Git.deprecation.behavior = :raise # # # Do nothing # Git.deprecation.behavior = :raise # # @see https://api.rubyonrails.org/classes/ActiveSupport/Deprecation.html ActiveSupport::Deprecation # # @return [ActiveSupport::Deprecation] # def self.deprecation @deprecation ||= ActiveSupport::Deprecation.new('2.0.0', 'git') end end require 'git/author' require 'git/base' require 'git/branch' require 'git/branches' require 'git/command_line_result' require 'git/config' require 'git/diff' require 'git/encoding_utils' require 'git/escaped_path' require 'git/failed_error' require 'git/git_execute_error' require 'git/index' require 'git/lib' require 'git/log' require 'git/object' require 'git/path' require 'git/remote' require 'git/repository' require 'git/signaled_error' require 'git/status' require 'git/stash' require 'git/stashes' require 'git/url' require 'git/version' require 'git/working_directory' require 'git/worktree' require 'git/worktrees' # 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 # existing remote repository. # # @author Scott Chacon (mailto:schacon@gmail.com) # module Git #g.config('user.name', 'Scott Chacon') # sets value #g.config('user.email', 'email@email.com') # sets value #g.config('user.name') # returns 'Scott Chacon' #g.config # returns whole config hash def config(name = nil, value = nil) lib = Git::Lib.new if(name && value) # set value lib.config_set(name, value) elsif (name) # return value lib.config_get(name) else # return hash lib.config_list end end def self.configure yield Base.config end def self.config return Base.config end def global_config(name = nil, value = nil) self.class.global_config(name, value) end # Open a bare repository # # Opens a bare repository located in the `git_dir` directory. # Since there is no working copy, you can not checkout or commit # but you can do most read operations. # # @see https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository # What is a bare repository? # # @example Open a bare repository and retrieve the first commit SHA # repository = Git.bare('ruby-git.git') # puts repository.log[0].sha #=> "64c6fa011d3287bab9158049c85f3e85718854a0" # # @param [Pathname] git_dir The path to the bare repository directory # containing an initialized Git repository. If a relative path is given, it # is converted to an absolute path using # [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path). # # @param [Hash] options The options for this command (see list of valid # options below) # # @option options [Logger] :log A logger to use for Git operations. Git commands # are logged at the `:info` level. Additional logging is done at the `:debug` # level. # # @return [Git::Base] an object that can execute git commands in the context # of the bare repository. # def self.bare(git_dir, options = {}) Base.bare(git_dir, options) end # Clone a repository into an empty or newly created directory # # @see https://git-scm.com/docs/git-clone git clone # @see https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a GIT URLs # # @param repository_url [URI, Pathname] The (possibly remote) repository url to clone # from. See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a) # for more information. # # @param directory [Pathname, nil] The directory to clone into # # If `directory` is a relative directory it is relative to the `path` option if # given. If `path` is not given, `directory` is relative to the current working # directory. # # If `nil`, `directory` will be set to the basename of the last component of # the path from the `repository_url`. For example, for the URL: # `https://github.com/org/repo.git`, `directory` will be set to `repo`. # # If the last component of the path is `.git`, the next-to-last component of # the path is used. For example, for the URL `/Users/me/foo/.git`, `directory` # will be set to `foo`. # # @param [Hash] options The options for this command (see list of valid # options below) # # @option options [Boolean] :bare Make a bare Git repository. See # [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository). # # @option options [String] :branch The name of a branch or tag to checkout # instead of the default branch. # # @option options [Integer] :depth Create a shallow clone with a history # truncated to the specified number of commits. # # @option options [Logger] :log A logger to use for Git operations. Git # commands are logged at the `:info` level. Additional logging is done # at the `:debug` level. # # @option options [Boolean] :mirror Set up a mirror of the source repository. # # @option options [String] :origin Use the value instead `origin` to track # the upstream repository. # # @option options [Pathname] :path The directory to clone into. May be used # as an alternative to the `directory` parameter. If specified, the # `path` option is used instead of the `directory` parameter. # # @option options [Boolean] :recursive After the clone is created, initialize # all submodules within, using their default settings. # # @example Clone into the default directory `ruby-git` # git = Git.clone('https://github.com/ruby-git/ruby-git.git') # # @example Clone and then checkout the `development` branch # git = Git.clone('https://github.com/ruby-git/ruby-git.git', branch: 'development') # # @example Clone into a different directory `my-ruby-git` # git = Git.clone('https://github.com/ruby-git/ruby-git.git', 'my-ruby-git') # # or: # git = Git.clone('https://github.com/ruby-git/ruby-git.git', path: 'my-ruby-git') # # @example Create a bare repository in the directory `ruby-git.git` # git = Git.clone('https://github.com/ruby-git/ruby-git.git', bare: true) # # @return [Git::Base] an object that can execute git commands in the context # of the cloned local working copy or cloned repository. # def self.clone(repository_url, directory = nil, options = {}) clone_to_options = options.select { |key, _value| %i[bare mirror].include?(key) } directory ||= Git::URL.clone_to(repository_url, **clone_to_options) Base.clone(repository_url, directory, options) end # Returns the name of the default branch of the given repository # # @example with a URI string # Git.default_branch('https://github.com/ruby-git/ruby-git') # => 'master' # Git.default_branch('https://github.com/rspec/rspec-core') # => 'main' # # @example with a URI object # repository_uri = URI('https://github.com/ruby-git/ruby-git') # Git.default_branch(repository_uri) # => 'master' # # @example with a local repository # Git.default_branch('.') # => 'master' # # @example with a local repository Pathname # repository_path = Pathname('.') # Git.default_branch(repository_path) # => 'master' # # @example with the logging option # logger = Logger.new(STDOUT, level: Logger::INFO) # Git.default_branch('.', log: logger) # => 'master' # I, [2022-04-13T16:01:33.221596 #18415] INFO -- : git '-c' 'core.quotePath=true' '-c' 'color.ui=false' ls-remote '--symref' '--' '.' 'HEAD' 2>&1 # # @param repository [URI, Pathname, String] The (possibly remote) repository to get the default branch name for # # See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a) # for more information. # # @param [Hash] options The options for this command (see list of valid # options below) # # @option options [Logger] :log A logger to use for Git operations. Git # commands are logged at the `:info` level. Additional logging is done # at the `:debug` level. # # @return [String] the name of the default branch # def self.default_branch(repository, options = {}) Base.repository_default_branch(repository, options) end # Export the current HEAD (or a branch, if options[:branch] # is specified) into the +name+ directory, then remove all traces of git from the # directory. # # See +clone+ for options. Does not obey the :remote option, # since the .git info will be deleted anyway; always uses the default # remote, 'origin.' def self.export(repository, name, options = {}) options.delete(:remote) repo = clone(repository, name, {:depth => 1}.merge(options)) repo.checkout("origin/#{options[:branch]}") if options[:branch] Dir.chdir(repo.dir.to_s) { FileUtils.rm_r '.git' } end # Same as g.config, but forces it to be at the global level # #g.config('user.name', 'Scott Chacon') # sets value #g.config('user.email', 'email@email.com') # sets value #g.config('user.name') # returns 'Scott Chacon' #g.config # returns whole config hash def self.global_config(name = nil, value = nil) lib = Git::Lib.new(nil, nil) if(name && value) # set value lib.global_config_set(name, value) elsif (name) # return value lib.global_config_get(name) else # return hash lib.global_config_list end end # Create an empty Git repository or reinitialize an existing Git repository # # @param [Pathname] directory If the `:bare` option is NOT given or is not # `true`, the repository will be created in `"#{directory}/.git"`. # Otherwise, the repository is created in `"#{directory}"`. # # All directories along the path to `directory` are created if they do not exist. # # A relative path is referenced from the current working directory of the process # and converted to an absolute path using # [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path). # # @param [Hash] options The options for this command (see list of valid # options below) # # @option options [Boolean] :bare Instead of creating a repository at # `"#{directory}/.git"`, create a bare repository at `"#{directory}"`. # See [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository). # # @option options [String] :initial_branch Use the specified name for the # initial branch in the newly created repository. # # @option options [Pathname] :repository the path to put the newly initialized # Git repository. The default for non-bare repository is `"#{directory}/.git"`. # # A relative path is referenced from the current working directory of the process # and converted to an absolute path using # [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path). # # @option options [Logger] :log A logger to use for Git operations. Git # commands are logged at the `:info` level. Additional logging is done # at the `:debug` level. # # @return [Git::Base] an object that can execute git commands in the context # of the newly initialized repository # # @example Initialize a repository in the current directory # git = Git.init # # @example Initialize a repository in some other directory # git = Git.init '~/code/ruby-git' # # @example Initialize a bare repository # git = Git.init '~/code/ruby-git.git', bare: true # # @example Initialize a repository in a non-default location (outside of the working copy) # git = Git.init '~/code/ruby-git', repository: '~/code/ruby-git.git' # # @see https://git-scm.com/docs/git-init git init # def self.init(directory = '.', options = {}) Base.init(directory, options) end # returns a Hash containing information about the references # of the target repository # # options # :refs # # @param [String|NilClass] location the target repository location or nil for '.' # @return [{String=>Hash}] the available references of the target repo. def self.ls_remote(location = nil, options = {}) Git::Lib.new.ls_remote(location, options) end # Open a an existing Git working directory # # Git.open will most likely be the most common way to create # a git reference, referring to an existing working directory. # # If not provided in the options, the library will assume # the repository and index are in the default places (`.git/`, `.git/index`). # # @example Open the Git working directory in the current directory # git = Git.open # # @example Open a Git working directory in some other directory # git = Git.open('~/Projects/ruby-git') # # @example Use a logger to see what is going on # logger = Logger.new(STDOUT) # git = Git.open('~/Projects/ruby-git', log: logger) # # @example Open a working copy whose repository is in a non-standard directory # git = Git.open('~/Projects/ruby-git', repository: '~/Project/ruby-git.git') # # @param [Pathname] working_dir the path to the working directory to use # for git commands. # # A relative path is referenced from the current working directory of the process # and converted to an absolute path using # [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path). # # @param [Hash] options The options for this command (see list of valid # options below) # # @option options [Pathname] :repository used to specify a non-standard path to # the repository directory. The default is `"#{working_dir}/.git"`. # # @option options [Pathname] :index used to specify a non-standard path to an # index file. The default is `"#{working_dir}/.git/index"` # # @option options [Logger] :log A logger to use for Git operations. Git # commands are logged at the `:info` level. Additional logging is done # at the `:debug` level. # # @return [Git::Base] an object that can execute git commands in the context # of the opened working copy # def self.open(working_dir, options = {}) Base.open(working_dir, options) end end