Module: Fastlane::Helper::GitHelper
- Defined in:
- lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb
Overview
Helper methods to execute git-related operations
Constant Summary collapse
- DEFAULT_GIT_BRANCH =
Fallback default branch of the client repository.
'trunk'
Class Method Summary collapse
-
.branch_exists?(branch_name) ⇒ Bool
Checks if a branch exists locally.
-
.branch_exists_on_remote?(branch_name:, remote_name: 'origin') ⇒ Boolean
Checks if a branch exists on the repository's remote.
-
.checkout_and_pull(branch) ⇒ Bool
Switch to the given branch and pull its latest commits.
-
.commit(message:, files: nil) ⇒ Bool
git addthe specified files (if any provided) then commit them using the provided message. -
.create_branch(branch_name, from: nil) ⇒ Object
Create a new branch named
branch_name, cutting it from branch/commit/tagfrom. -
.create_tag(version, push: true) ⇒ Object
Creates a tag for the given version, and optionally push it to the remote.
-
.current_git_branch ⇒ String
Returns the current git branch, or "HEAD" if it's not checked out to any branch Can NOT be replaced using the environment variables such as
GIT_BRANCHorBUILDKITE_BRANCH. -
.delete_local_branch_if_exists!(branch_name) ⇒ Boolean
Delete a local branch if it exists.
-
.delete_remote_branch_if_exists!(branch_name, remote_name: 'origin') ⇒ Boolean
Delete a remote branch if it exists.
-
.delete_tags(tags_to_delete, delete_on_remote: false) ⇒ Object
Delete the mentioned local tags in the local working copy, and optionally delete them on the remote too.
-
.fetch_all_tags ⇒ Object
Fetch all the tags from the remote.
-
.find_merge_base(ref1, ref2) ⇒ String
Use
git merge-baseto find as good a common ancestors as possible for a merge. -
.first_existing_ancestor_of(path:) ⇒ Pathname
Travels back the hierarchy of the given path until it finds an existing ancestor, or it reaches the root of the file system.
-
.get_commit_sha(ref: 'HEAD', prepend_origin_if_needed: false) ⇒ String
Get the SHA of a given git ref.
-
.has_git_lfs? ⇒ Bool
Check if the current directory has git-lfs enabled.
-
.is_git_repo?(path: Dir.pwd) ⇒ Bool
Checks if the given path, or current directory if no path is given, is inside a Git repository.
-
.is_ignored?(path:) ⇒ Bool
Checks whether a given path is ignored by Git, relying on Git's
check-ignoreunder the hood. -
.list_local_tags(matching: '*') ⇒ Array<String>
List all the tags in the local working copy, optionally filtering the list using a pattern.
-
.list_tags_on_current_commit ⇒ Array<String>
Returns the list of tags that are pointing to the current commit (HEAD).
-
.point_to_same_commit?(ref1, ref2) ⇒ Boolean
Checks if two git references point to the same commit.
Class Method Details
.branch_exists?(branch_name) ⇒ Bool
Checks if a branch exists locally.
238 239 240 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 238 def self.branch_exists?(branch_name) !Action.sh('git', 'branch', '--list', branch_name).empty? end |
.branch_exists_on_remote?(branch_name:, remote_name: 'origin') ⇒ Boolean
Checks if a branch exists on the repository's remote.
249 250 251 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 249 def self.branch_exists_on_remote?(branch_name:, remote_name: 'origin') !Action.sh('git', 'ls-remote', '--heads', remote_name, branch_name).empty? end |
.checkout_and_pull(branch) ⇒ Bool
Switch to the given branch and pull its latest commits.
63 64 65 66 67 68 69 70 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 63 def self.checkout_and_pull(branch) branch = branch.first.join('/') if branch.is_a?(Hash) Action.sh('git', 'checkout', branch) Action.sh('git', 'pull') true rescue StandardError false end |
.commit(message:, files: nil) ⇒ Bool
git add the specified files (if any provided) then commit them using the provided message.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 100 def self.commit(message:, files: nil) files = [files] if files.is_a?(String) args = [] if files == :all args = ['-a'] elsif !files.nil? && !files.empty? Action.sh('git', 'add', *files) end begin Action.sh('git', 'commit', *args, '-m', ) true rescue StandardError false end end |
.create_branch(branch_name, from: nil) ⇒ Object
Create a new branch named branch_name, cutting it from branch/commit/tag from
If the branch with that name already exists, it will instead switch to it and pull new commits.
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 80 def self.create_branch(branch_name, from: nil) if branch_exists?(branch_name) UI.("Branch #{branch_name} already exists. Skipping creation.") Action.sh('git', 'checkout', branch_name) Action.sh('git', 'pull', 'origin', branch_name) else Action.sh('git', 'checkout', from) unless from.nil? Action.sh('git', 'checkout', '-b', branch_name) end end |
.create_tag(version, push: true) ⇒ Object
Creates a tag for the given version, and optionally push it to the remote.
138 139 140 141 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 138 def self.create_tag(version, push: true) Action.sh('git', 'tag', version) Action.sh('git', 'push', 'origin', version) if push end |
.current_git_branch ⇒ String
Returns the current git branch, or "HEAD" if it's not checked out to any branch
Can NOT be replaced using the environment variables such as GIT_BRANCH or BUILDKITE_BRANCH
fastlane already has a helper action for this called git_branch, however it's modified
by CI environment variables. We need to check which branch we are actually on and not the
initial branch a CI build is started from, so we are using the git_branch_name_using_HEAD
helper instead.
See https://docs.fastlane.tools/actions/git_branch/#git_branch
227 228 229 230 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 227 def self.current_git_branch # We can't use `other_action.git_branch`, because it is modified by environment variables in Buildkite. Fastlane::Actions.git_branch_name_using_HEAD end |
.delete_local_branch_if_exists!(branch_name) ⇒ Boolean
Delete a local branch if it exists.
258 259 260 261 262 263 264 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 258 def self.delete_local_branch_if_exists!(branch_name) git_repo = Git.open(Dir.pwd) return false unless git_repo.is_local_branch?(branch_name) git_repo.branch(branch_name).delete true end |
.delete_remote_branch_if_exists!(branch_name, remote_name: 'origin') ⇒ Boolean
Delete a remote branch if it exists.
272 273 274 275 276 277 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 272 def self.delete_remote_branch_if_exists!(branch_name, remote_name: 'origin') git_repo = Git.open(Dir.pwd) return false unless git_repo.branches.any? { |b| b.remote&.name == remote_name && b.name == branch_name } git_repo.push(remote_name, branch_name, delete: true) end |
.delete_tags(tags_to_delete, delete_on_remote: false) ⇒ Object
Delete the mentioned local tags in the local working copy, and optionally delete them on the remote too.
167 168 169 170 171 172 173 174 175 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 167 def self.(, delete_on_remote: false) g = Git.open(Dir.pwd) local_tag_names = g..map(&:name) Array().each do |tag| g.delete_tag(tag) if local_tag_names.include?(tag) g.push('origin', ":refs/tags/#{tag}") if delete_on_remote end end |
.fetch_all_tags ⇒ Object
Fetch all the tags from the remote.
179 180 181 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 179 def self. Action.sh('git', 'fetch', '--tags') end |
.find_merge_base(ref1, ref2) ⇒ String
If a reference (e.g. branch name) can't be found locally, it will try with the same ref prefixed with origin/
Use git merge-base to find as good a common ancestors as possible for a merge
190 191 192 193 194 195 196 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 190 def self.find_merge_base(ref1, ref2) git_repo = Git.open(Dir.pwd) # Resolve to shas, mostly so that we can support cases with and without `origin/` explicit prefix on branch names ref1_sha, ref2_sha = [ref1, ref2].map { |ref| get_commit_sha(ref: ref, prepend_origin_if_needed: true) } git_repo.merge_base(ref1_sha, ref2_sha)&.first&.sha end |
.first_existing_ancestor_of(path:) ⇒ Pathname
Travels back the hierarchy of the given path until it finds an existing ancestor, or it reaches the root of the file system.
39 40 41 42 43 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 39 def self.first_existing_ancestor_of(path:) p = Pathname(path). p = p.parent until p.exist? || p.root? p end |
.get_commit_sha(ref: 'HEAD', prepend_origin_if_needed: false) ⇒ String
Get the SHA of a given git ref. Typically useful to get the SHA of the current HEAD commit.
124 125 126 127 128 129 130 131 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 124 def self.get_commit_sha(ref: 'HEAD', prepend_origin_if_needed: false) repo = Git.open(Dir.pwd) repo.revparse(ref) rescue Git::FailedError raise unless prepend_origin_if_needed repo.revparse("origin/#{ref}") end |
.has_git_lfs? ⇒ Bool
Check if the current directory has git-lfs enabled
49 50 51 52 53 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 49 def self.has_git_lfs? return false unless is_git_repo? !`git config --get-regex lfs`.empty? end |
.is_git_repo?(path: Dir.pwd) ⇒ Bool
Checks if the given path, or current directory if no path is given, is inside a Git repository
19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 19 def self.is_git_repo?(path: Dir.pwd) # If the path doesn't exist, find its first ancestor. path = first_existing_ancestor_of(path: path) # Get the path's directory, so we can look in it for the Git folder dir = path.directory? ? path : path.dirname # Recursively look for the Git folder until it's found or we read the the file system root dir = dir.parent until Dir.entries(dir).include?('.git') || dir.root? # If we reached the root, we haven't found a repo. # (Technically, there could be a repo in the root of the system, but that's a usecase that we don't need to support at this time) dir.root? == false end |
.is_ignored?(path:) ⇒ Bool
Checks whether a given path is ignored by Git, relying on Git's check-ignore under the hood.
284 285 286 287 288 289 290 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 284 def self.is_ignored?(path:) return true unless is_git_repo?(path: path) Actions.sh('git', 'check-ignore', path) do |status, _, _| status.success? end end |
.list_local_tags(matching: '*') ⇒ Array<String>
List all the tags in the local working copy, optionally filtering the list using a pattern
158 159 160 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 158 def self.(matching: '*') Action.sh('git', 'tag', '--list', matching).split("\n") end |
.list_tags_on_current_commit ⇒ Array<String>
Returns the list of tags that are pointing to the current commit (HEAD)
147 148 149 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 147 def self. Action.sh('git', 'tag', '--points-at', 'HEAD').split("\n") end |
.point_to_same_commit?(ref1, ref2) ⇒ Boolean
Checks if two git references point to the same commit.
205 206 207 208 209 210 211 212 213 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb', line 205 def self.point_to_same_commit?(ref1, ref2) begin ref1_sha = get_commit_sha(ref: ref1, prepend_origin_if_needed: true) ref2_sha = get_commit_sha(ref: ref2, prepend_origin_if_needed: true) rescue StandardError => e UI.user_error! "Error fetching commits for #{ref1} and/or #{ref2}: #{e.}" end ref1_sha == ref2_sha end |