Module: Utils::Git Private

Extended by:
SystemCommand::Mixin
Defined in:
utils/git.rb

Overview

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Helper functions for querying Git information.

See Also:

Class Method Summary collapse

Methods included from SystemCommand::Mixin

system_command, system_command!

Class Method Details

.available?Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


14
15
16
# File 'utils/git.rb', line 14

def self.available?
  !version.null?
end

.cherry_pick!(repo, *args, resolve: false, verbose: false) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Special case of git cherry-pick that permits non-verbose output and optional resolution on merge conflict.

Parameters:

  • repo (Pathname, String)
  • args (String)
  • resolve (Boolean) (defaults to: false)
  • verbose (Boolean) (defaults to: false)

Returns:



168
169
170
171
172
173
174
175
176
177
178
# File 'utils/git.rb', line 168

def self.cherry_pick!(repo, *args, resolve: false, verbose: false)
  cmd = [git.to_s, "-C", repo, "cherry-pick"] + args
  output = Utils.popen_read(*cmd, err: :out)
  if $CHILD_STATUS.success?
    puts output if verbose
    output
  else
    system git.to_s, "-C", repo.to_s, "cherry-pick", "--abort" unless resolve
    raise ErrorDuringExecution.new(cmd, status: $CHILD_STATUS, output: [[:stdout, output]])
  end
end

.clear_available_cachevoid

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



48
49
50
51
52
# File 'utils/git.rb', line 48

def self.clear_available_cache
  remove_instance_variable(:@version) if defined?(@version)
  remove_instance_variable(:@path) if defined?(@path)
  remove_instance_variable(:@git) if defined?(@git)
end

.count_coauthors(repository_path, person, from:, to:) ⇒ Integer

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:

  • (Integer)


191
192
193
194
195
196
197
198
199
200
# File 'utils/git.rb', line 191

def self.count_coauthors(repository_path, person, from:, to:)
  return 0 if repository_path.blank?

  cmd = [git.to_s, "-C", repository_path.to_s, "log", "--oneline"]
  cmd << "--format='%(trailers:key=Co-authored-by:)''"
  cmd << "--before=#{to}" if to
  cmd << "--after=#{from}" if from

  Utils.safe_popen_read(*cmd).lines.count { |l| l.include?(person) }
end

.ensure_installed!void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'utils/git.rb', line 114

def self.ensure_installed!
  return if available?

  # we cannot install brewed git if homebrew/core is unavailable.
  if CoreTap.instance.installed?
    begin
      # Otherwise `git` will be installed from source in tests that need it. This is slow
      # and will also likely fail due to `OS::Linux` and `OS::Mac` being undefined.
      raise "Refusing to install Git on a generic OS." if ENV["HOMEBREW_TEST_GENERIC_OS"]

      require "formula"
      Formula["git"].ensure_installed!
      clear_available_cache
    rescue
      raise "Git is unavailable"
    end
  end

  raise "Git is unavailable" unless available?
end

.file_at_commit(repo, file, commit) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



107
108
109
110
111
# File 'utils/git.rb', line 107

def self.file_at_commit(repo, file, commit)
  relative_file = Pathname(file)
  relative_file = relative_file.relative_path_from(repo) if relative_file.absolute?
  Utils.popen_read(git, "-C", repo, "show", "#{commit}:#{relative_file}")
end

.gitPathname

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



36
37
38
# File 'utils/git.rb', line 36

def self.git
  @git ||= T.let(HOMEBREW_SHIMS_PATH/"shared/git", T.nilable(Pathname))
end

.last_revision_commit_of_file(repo, file, before_commit: nil) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



58
59
60
61
62
63
64
65
66
# File 'utils/git.rb', line 58

def self.last_revision_commit_of_file(repo, file, before_commit: nil)
  args = if before_commit.nil?
    ["--skip=1"]
  else
    [before_commit.split("..").first]
  end

  Utils.popen_read(git, "-C", repo, "log", "--format=%h", "--abbrev=7", "--max-count=1", *args, "--", file).chomp
end

.last_revision_commit_of_files(repo, files, before_commit: nil) ⇒ Array<([String, nil], Array<String>)>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'utils/git.rb', line 75

def self.last_revision_commit_of_files(repo, files, before_commit: nil)
  args = if before_commit.nil?
    ["--skip=1"]
  else
    [before_commit.split("..").first]
  end

  # git log output format:
  #   <commit_hash>
  #   <file_path1>
  #   <file_path2>
  #   ...
  # return [<commit_hash>, [file_path1, file_path2, ...]]
  rev, *paths = Utils.popen_read(
    git, "-C", repo, "log",
    "--pretty=format:%h", "--abbrev=7", "--max-count=1",
    "--diff-filter=d", "--name-only", *args, "--", *files
  ).lines.map(&:chomp).reject(&:empty?)
  [rev, paths]
end

.last_revision_of_file(repo, file, before_commit: nil) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



100
101
102
103
104
# File 'utils/git.rb', line 100

def self.last_revision_of_file(repo, file, before_commit: nil)
  relative_file = Pathname(file).relative_path_from(repo)
  commit_hash = last_revision_commit_of_file(repo, relative_file, before_commit:)
  file_at_commit(repo, file, commit_hash)
end

.pathString?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



28
29
30
31
32
33
# File 'utils/git.rb', line 28

def self.path
  return unless available?
  return @path if defined?(@path)

  @path = T.let(Utils.popen_read(git, "--homebrew=print-path").chomp.presence, T.nilable(String))
end

.remote_exists?(url) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:

  • (Boolean)


41
42
43
44
45
# File 'utils/git.rb', line 41

def self.remote_exists?(url)
  return true unless available?

  quiet_system "git", "ls-remote", url
end

.set_name_email!(author: true, committer: true) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Parameters:

  • author (Boolean) (defaults to: true)
  • committer (Boolean) (defaults to: true)


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'utils/git.rb', line 136

def self.set_name_email!(author: true, committer: true)
  if Homebrew::EnvConfig.git_name
    ENV["GIT_AUTHOR_NAME"] = Homebrew::EnvConfig.git_name if author
    ENV["GIT_COMMITTER_NAME"] = Homebrew::EnvConfig.git_name if committer
  end

  if Homebrew::EnvConfig.git_committer_name && committer
    ENV["GIT_COMMITTER_NAME"] = Homebrew::EnvConfig.git_committer_name
  end

  if Homebrew::EnvConfig.git_email
    ENV["GIT_AUTHOR_EMAIL"] = Homebrew::EnvConfig.git_email if author
    ENV["GIT_COMMITTER_EMAIL"] = Homebrew::EnvConfig.git_email if committer
  end

  return unless committer
  return unless Homebrew::EnvConfig.git_committer_email

  ENV["GIT_COMMITTER_EMAIL"] = Homebrew::EnvConfig.git_committer_email
end

.setup_gpg!void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



158
159
160
161
162
163
# File 'utils/git.rb', line 158

def self.setup_gpg!
  gnupg_bin = HOMEBREW_PREFIX/"opt/gnupg/bin"
  return unless gnupg_bin.directory?

  ENV["PATH"] = PATH.new(ENV.fetch("PATH")).prepend(gnupg_bin).to_s
end

.supports_partial_clone_sparse_checkout?Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


181
182
183
184
185
# File 'utils/git.rb', line 181

def self.supports_partial_clone_sparse_checkout?
  # There is some support for partial clones prior to 2.20, but we avoid using it
  # due to performance issues
  version >= Version.new("2.20.0")
end

.versionVersion

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



19
20
21
22
23
24
25
# File 'utils/git.rb', line 19

def self.version
  @version ||= T.let(begin
    stdout, _, status = system_command(git, args: ["--version"], verbose: false, print_stderr: false).to_a
    version_str = status.success? ? stdout.chomp[/git version (\d+(?:\.\d+)*)/, 1] : nil
    version_str.nil? ? Version::NULL : Version.new(version_str)
  end, T.nilable(Version))
end