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 add` the 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/tag `from`.
-
.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_BRANCH` or `BUILDKITE_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-base` to 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-ignore` under 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.
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 |