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.
NOTE: Maybe we should need to use a git library instead of shelling out to git. Only if this functionality is not enough for the gem on the future.
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.
20 21 22 |
# File 'lib/rails_wayback/git.rb', line 20 def initialize(root: nil) @root = Pathname.new(root || RailsWayback.configuration.app_root_path) end |
Instance Method Details
#branches ⇒ Object
38 39 40 41 |
# File 'lib/rails_wayback/git.rb', line 38 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).
71 72 73 74 75 76 |
# File 'lib/rails_wayback/git.rb', line 71 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
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/rails_wayback/git.rb', line 114 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
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/rails_wayback/git.rb', line 43 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
30 31 32 |
# File 'lib/rails_wayback/git.rb', line 30 def current_branch run("rev-parse", "--abbrev-ref", "HEAD").strip end |
#current_commit ⇒ Object
34 35 36 |
# File 'lib/rails_wayback/git.rb', line 34 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.
102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rails_wayback/git.rb', line 102 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
24 25 26 27 28 |
# File 'lib/rails_wayback/git.rb', line 24 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).
86 87 88 89 90 91 92 93 94 |
# File 'lib/rails_wayback/git.rb', line 86 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
57 58 59 60 61 |
# File 'lib/rails_wayback/git.rb', line 57 def resolve_ref(ref) run("rev-parse", "--verify", "#{ref}^{commit}").strip rescue GitError raise RefNotFoundError, "Unknown git ref: #{ref.inspect}" end |
#root ⇒ Object
127 128 129 |
# File 'lib/rails_wayback/git.rb', line 127 def root @root end |
#show(ref, path) ⇒ Object
63 64 65 |
# File 'lib/rails_wayback/git.rb', line 63 def show(ref, path) run("show", "#{ref}:#{path}") end |