Class: RailsWayback::Git
- Inherits:
-
Object
- Object
- RailsWayback::Git
- Defined in:
- lib/rails_wayback/git.rb
Overview
Thin wrapper around shell git for the host application repository.
We shell out to git instead of pulling in a dependency to keep the gem light. All commands are scoped to the host app root and return plain Ruby data structures.
Defined Under Namespace
Instance Method Summary collapse
- #branches ⇒ Object
-
#branches_containing(sha) ⇒ Object
Returns the local branch names that contain
shain their history. - #checkout_ref(ref, into:) ⇒ Object
- #commits(branch, limit: RailsWayback.configuration.max_commits) ⇒ Object
- #current_branch ⇒ Object
- #current_commit ⇒ Object
-
#diff_paths(ref, paths: []) ⇒ Object
Returns the list of files that differ between
refand the current working tree (unstaged changes included). -
#initialize(root: nil) ⇒ Git
constructor
A new instance of Git.
- #repository? ⇒ Boolean
-
#resolve_branch_for(sha) ⇒ Object
Same as
branches_containing, but picks the most contextual one for display in the bar when the developer did NOT provide an explicit branch alongside the sha: * if the current branch contains the sha, prefer it (keeps you in your own context — the sha is on your history line), * otherwise pick the first non-current local branch that contains it (typical case of traveling AWAY from your branch), * returns nil if no local branch contains the sha (detached ref). - #resolve_ref(ref) ⇒ Object
- #root ⇒ Object
- #show(ref, path) ⇒ Object
Constructor Details
#initialize(root: nil) ⇒ Git
Returns a new instance of Git.
17 18 19 |
# File 'lib/rails_wayback/git.rb', line 17 def initialize(root: nil) @root = Pathname.new(root || RailsWayback.configuration.app_root_path) end |
Instance Method Details
#branches ⇒ Object
35 36 37 38 |
# File 'lib/rails_wayback/git.rb', line 35 def branches output = run("for-each-ref", "--format=%(refname:short)", "refs/heads/") output.split("\n").map(&:strip).reject(&:empty?) end |
#branches_containing(sha) ⇒ Object
Returns the local branch names that contain sha in their history.
Used by the bar to reflect the branch you are RENDERING with when
you travel, instead of the branch that is checked out on disk
(which never moves — the gem never touches your working tree).
68 69 70 71 72 73 |
# File 'lib/rails_wayback/git.rb', line 68 def branches_containing(sha) output = run("branch", "--contains", sha, "--format=%(refname:short)") output.split("\n").map(&:strip).reject(&:empty?) rescue GitError [] end |
#checkout_ref(ref, into:) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/rails_wayback/git.rb', line 111 def checkout_ref(ref, into:) target = Pathname.new(into) FileUtils.mkdir_p(target) # `git --work-tree` + `checkout` writes the ref's contents into a # detached directory without touching the developer's HEAD or index. env = { "GIT_INDEX_FILE" => target.join(".rails_wayback_index").to_s } run_with_env(env, "--work-tree=#{target}", "read-tree", ref) run_with_env(env, "--work-tree=#{target}", "checkout-index", "--all", "--force") target ensure FileUtils.rm_f(target.join(".rails_wayback_index")) if target end |
#commits(branch, limit: RailsWayback.configuration.max_commits) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/rails_wayback/git.rb', line 40 def commits(branch, limit: RailsWayback.configuration.max_commits) output = run( "log", branch, "--max-count=#{limit.to_i}", "--pretty=format:%H%x1f%h%x1f%s%x1f%an%x1f%ad", "--date=iso-strict" ) output.split("\n").reject(&:empty?).map do |line| sha, short, subject, , date = line.split("\x1f", 5) Commit.new(sha: sha, short_sha: short, subject: subject, author: , date: date) end end |
#current_branch ⇒ Object
27 28 29 |
# File 'lib/rails_wayback/git.rb', line 27 def current_branch run("rev-parse", "--abbrev-ref", "HEAD").strip end |
#current_commit ⇒ Object
31 32 33 |
# File 'lib/rails_wayback/git.rb', line 31 def current_commit run("rev-parse", "HEAD").strip end |
#diff_paths(ref, paths: []) ⇒ Object
Returns the list of files that differ between ref and the current
working tree (unstaged changes included). Optionally scoped to a set
of pathspecs so we only report files inside the paths the gem
actually swaps for rendering. Never raises: on git failure we log
and return an empty list so a missing/broken ref never breaks the
bar.
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rails_wayback/git.rb', line 99 def diff_paths(ref, paths: []) args = ["diff", "--name-only", ref] args += ["--", *paths] unless paths.empty? output = run(*args) output.split("\n").map(&:strip).reject(&:empty?) rescue GitError => e if defined?(Rails) && Rails.respond_to?(:logger) Rails.logger.warn("[rails-wayback] diff_paths(#{ref.inspect}) failed: #{e.}") end [] end |
#repository? ⇒ Boolean
21 22 23 24 25 |
# File 'lib/rails_wayback/git.rb', line 21 def repository? Dir.exist?(@root.join(".git")) || run("rev-parse", "--is-inside-work-tree").strip == "true" rescue GitError false end |
#resolve_branch_for(sha) ⇒ Object
Same as branches_containing, but picks the most contextual one
for display in the bar when the developer did NOT provide an
explicit branch alongside the sha:
- if the current branch contains the sha, prefer it (keeps you in your own context — the sha is on your history line),
- otherwise pick the first non-current local branch that contains it (typical case of traveling AWAY from your branch),
- returns nil if no local branch contains the sha (detached ref).
83 84 85 86 87 88 89 90 91 |
# File 'lib/rails_wayback/git.rb', line 83 def resolve_branch_for(sha) candidates = branches_containing(sha) return nil if candidates.empty? here = current_branch return here if candidates.include?(here) candidates.first end |
#resolve_ref(ref) ⇒ Object
54 55 56 57 58 |
# File 'lib/rails_wayback/git.rb', line 54 def resolve_ref(ref) run("rev-parse", "--verify", "#{ref}^{commit}").strip rescue GitError raise RefNotFoundError, "Unknown git ref: #{ref.inspect}" end |
#root ⇒ Object
124 125 126 |
# File 'lib/rails_wayback/git.rb', line 124 def root @root end |
#show(ref, path) ⇒ Object
60 61 62 |
# File 'lib/rails_wayback/git.rb', line 60 def show(ref, path) run("show", "#{ref}:#{path}") end |