Class: Onair::Git
- Inherits:
-
Object
- Object
- Onair::Git
- Defined in:
- lib/onair/git.rb
Overview
The only place that shells out to git. Everything else takes an instance as a dependency — this is the seam unit tests fake. All methods degrade to nil/false/[] on failure; they never raise.
Defined Under Namespace
Classes: Identity
Instance Method Summary collapse
- #ancestor?(ancestor_sha, descendant_sha) ⇒ Boolean
- #commit_info(sha) ⇒ Object
- #count_between(from_sha, to_sha) ⇒ Object
-
#fetch_once! ⇒ Object
Best-effort, at most once per process, skipped under --no-fetch.
-
#first_parent_below(sha, count) ⇒ Object
The
first-parent commits just below the given head (head itself excluded), as [sha, author_name, author_email] tuples. - #has_commit?(sha) ⇒ Boolean
- #identity ⇒ Object
-
#initialize(fetch_allowed: true, dir: nil) ⇒ Git
constructor
A new instance of Git.
-
#origin_repo ⇒ Object
"owner/name" parsed from the origin remote, or nil.
-
#remote_head(branch) ⇒ Object
Tip of origin/
straight from the remote — accurate without a pull.
Constructor Details
#initialize(fetch_allowed: true, dir: nil) ⇒ Git
Returns a new instance of Git.
12 13 14 15 16 |
# File 'lib/onair/git.rb', line 12 def initialize(fetch_allowed: true, dir: nil) @fetch_allowed = fetch_allowed @dir = dir @fetched = false end |
Instance Method Details
#ancestor?(ancestor_sha, descendant_sha) ⇒ Boolean
50 51 52 |
# File 'lib/onair/git.rb', line 50 def ancestor?(ancestor_sha, descendant_sha) success?("merge-base", "--is-ancestor", ancestor_sha, descendant_sha) end |
#commit_info(sha) ⇒ Object
42 43 44 45 46 47 48 |
# File 'lib/onair/git.rb', line 42 def commit_info(sha) out = capture("log", "-1", "--format=%s%x09%an%x09%ae%x09%ct", sha) return nil if out.nil? subject, name, email, epoch = out.chomp.split("\t", 4) CommitInfo.new(subject:, author_name: name, author_email: email, committed_at: Time.at(epoch.to_i)) end |
#count_between(from_sha, to_sha) ⇒ Object
54 55 56 |
# File 'lib/onair/git.rb', line 54 def count_between(from_sha, to_sha) capture("rev-list", "--count", "#{from_sha}..#{to_sha}")&.strip&.to_i end |
#fetch_once! ⇒ Object
Best-effort, at most once per process, skipped under --no-fetch. The commit may still be absent afterward (force-pushed away); callers degrade via the "(commit not found)" fallback.
35 36 37 38 39 40 |
# File 'lib/onair/git.rb', line 35 def fetch_once! return if @fetched || !@fetch_allowed @fetched = true success?("fetch", "--quiet", "origin") end |
#first_parent_below(sha, count) ⇒ Object
The
60 61 62 63 64 65 |
# File 'lib/onair/git.rb', line 60 def first_parent_below(sha, count) out = capture("log", "--first-parent", "--skip=1", "-#{count}", "--format=%H%x09%an%x09%ae", sha) return [] if out.nil? out.lines.map { |line| line.chomp.split("\t", 3) } end |
#has_commit?(sha) ⇒ Boolean
28 29 30 |
# File 'lib/onair/git.rb', line 28 def has_commit?(sha) success?("cat-file", "-e", "#{sha}^{commit}") end |
#identity ⇒ Object
67 68 69 |
# File 'lib/onair/git.rb', line 67 def identity Identity.new(name: capture("config", "user.name")&.strip, email: capture("config", "user.email")&.strip) end |
#origin_repo ⇒ Object
"owner/name" parsed from the origin remote, or nil.
72 73 74 75 |
# File 'lib/onair/git.rb', line 72 def origin_repo url = capture("remote", "get-url", "origin")&.strip url&.match(%r{github\.com[:/](?<repo>[^/]+/[^/\s]+?)(?:\.git)?/?\z})&.[](:repo) end |
#remote_head(branch) ⇒ Object
Tip of origin/
20 21 22 23 24 25 26 |
# File 'lib/onair/git.rb', line 20 def remote_head(branch) out = capture("ls-remote", "origin", "refs/heads/#{branch}") sha = out.to_s[/\A\h+/] return sha unless sha.nil? || sha.empty? capture("rev-parse", "origin/#{branch}")&.strip end |