Class: RobotLab::To::CommitManager
- Inherits:
-
Object
- Object
- RobotLab::To::CommitManager
- Defined in:
- lib/robot_lab/to/commit_manager.rb
Overview
All git operations needed by the orchestrator.
All subprocess calls use explicit argv arrays (no shell interpolation). GIT_TERMINAL_PROMPT=0 prevents credential prompts from hanging the loop.
Constant Summary collapse
- GIT_ENV =
{ "GIT_TERMINAL_PROMPT" => "0" }.freeze
Instance Method Summary collapse
- #add_all ⇒ Object
- #add_to_local_exclude(entry) ⇒ Object
- #changed_files_since(base_sha) ⇒ Object
-
#changed_vs_worktree(ref) ⇒ Object
Files differing between a ref and the current working tree (uncommitted changes), INCLUDING new untracked files.
-
#checkout_branch(name) ⇒ Object
Switch to an existing branch (used when resuming a prior run).
- #commit(message) ⇒ Object
- #create_branch(name) ⇒ Object
- #current_branch ⇒ Object
- #diff_stat(base_sha) ⇒ Object
- #head_exists? ⇒ Boolean
- #head_sha ⇒ Object
-
#initialize(work_dir: Dir.pwd) ⇒ CommitManager
constructor
A new instance of CommitManager.
- #reset_hard ⇒ Object
-
#show(ref, path) ⇒ Object
Contents of a path at a given ref, or "" when it did not exist there.
- #staged? ⇒ Boolean
-
#tracked_files ⇒ Object
All tracked files — the project's committed layout.
Constructor Details
#initialize(work_dir: Dir.pwd) ⇒ CommitManager
Returns a new instance of CommitManager.
14 15 16 |
# File 'lib/robot_lab/to/commit_manager.rb', line 14 def initialize(work_dir: Dir.pwd) @work_dir = work_dir end |
Instance Method Details
#add_all ⇒ Object
41 42 43 |
# File 'lib/robot_lab/to/commit_manager.rb', line 41 def add_all git("add", "-A") end |
#add_to_local_exclude(entry) ⇒ Object
75 76 77 78 79 80 81 82 |
# File 'lib/robot_lab/to/commit_manager.rb', line 75 def add_to_local_exclude(entry) exclude = Pathname.new(@work_dir).join(".git", "info", "exclude") exclude.parent.mkpath content = exclude.exist? ? exclude.read : "" return if content.include?(entry) File.open(exclude, "a") { |f| f.puts(entry) } end |
#changed_files_since(base_sha) ⇒ Object
84 85 86 87 88 |
# File 'lib/robot_lab/to/commit_manager.rb', line 84 def changed_files_since(base_sha) out, _err, _status = Open3.capture3(GIT_ENV, "git", "diff", "--name-only", "#{base_sha}..HEAD", chdir: @work_dir) out.lines.map(&:chomp).reject(&:empty?) end |
#changed_vs_worktree(ref) ⇒ Object
Files differing between a ref and the current working tree (uncommitted
changes), INCLUDING new untracked files. Used by pairwise evals to compare
a draft against its parent -- and a prose doer typically CREATES the
document, so the untracked case is the common one (git diff alone misses
new files).
95 96 97 98 99 100 |
# File 'lib/robot_lab/to/commit_manager.rb', line 95 def changed_vs_worktree(ref) tracked, = Open3.capture3(GIT_ENV, "git", "diff", "--name-only", ref, chdir: @work_dir) untracked, = Open3.capture3(GIT_ENV, "git", "ls-files", "--others", "--exclude-standard", chdir: @work_dir) (tracked.lines + untracked.lines).map(&:chomp).reject(&:empty?).uniq end |
#checkout_branch(name) ⇒ Object
Switch to an existing branch (used when resuming a prior run).
31 32 33 |
# File 'lib/robot_lab/to/commit_manager.rb', line 31 def checkout_branch(name) git("checkout", name) end |
#commit(message) ⇒ Object
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/robot_lab/to/commit_manager.rb', line 45 def commit() out, err, status = Open3.capture3( GIT_ENV, "git", "-c", "commit.gpgsign=false", "-c", "tag.gpgsign=false", "commit", "-m", , chdir: @work_dir ) return if status.success? raise CommitFailedError.new("git commit failed", output: (out + err).strip) end |
#create_branch(name) ⇒ Object
26 27 28 |
# File 'lib/robot_lab/to/commit_manager.rb', line 26 def create_branch(name) git("checkout", "-b", name) end |
#current_branch ⇒ Object
18 19 20 |
# File 'lib/robot_lab/to/commit_manager.rb', line 18 def current_branch git("rev-parse", "--abbrev-ref", "HEAD").chomp end |
#diff_stat(base_sha) ⇒ Object
69 70 71 72 73 |
# File 'lib/robot_lab/to/commit_manager.rb', line 69 def diff_stat(base_sha) out, _err, _status = Open3.capture3(GIT_ENV, "git", "diff", "--stat", "#{base_sha}..HEAD", chdir: @work_dir) parse_diff_stat(out) end |
#head_exists? ⇒ Boolean
56 57 58 59 60 |
# File 'lib/robot_lab/to/commit_manager.rb', line 56 def head_exists? _out, _err, status = Open3.capture3(GIT_ENV, "git", "rev-parse", "--verify", "HEAD", chdir: @work_dir) status.success? end |
#head_sha ⇒ Object
22 23 24 |
# File 'lib/robot_lab/to/commit_manager.rb', line 22 def head_sha git("rev-parse", "HEAD").chomp end |
#reset_hard ⇒ Object
62 63 64 65 66 67 |
# File 'lib/robot_lab/to/commit_manager.rb', line 62 def reset_hard return unless head_exists? git("reset", "--hard", "HEAD") git("clean", "-fd") end |
#show(ref, path) ⇒ Object
Contents of a path at a given ref, or "" when it did not exist there.
103 104 105 106 107 |
# File 'lib/robot_lab/to/commit_manager.rb', line 103 def show(ref, path) out, _err, status = Open3.capture3(GIT_ENV, "git", "show", "#{ref}:#{path}", chdir: @work_dir) status.success? ? out : "" end |
#staged? ⇒ Boolean
35 36 37 38 39 |
# File 'lib/robot_lab/to/commit_manager.rb', line 35 def staged? _out, _err, status = Open3.capture3(GIT_ENV, "git", "diff", "--cached", "--quiet", chdir: @work_dir) !status.success? # exit 1 = changes are staged end |
#tracked_files ⇒ Object
All tracked files — the project's committed layout. Excludes the run dir (it's in .git/info/exclude), so it's a clean workspace digest.
111 112 113 114 115 116 |
# File 'lib/robot_lab/to/commit_manager.rb', line 111 def tracked_files out, _err, status = Open3.capture3(GIT_ENV, "git", "ls-files", chdir: @work_dir) return [] unless status.success? out.lines.map(&:chomp).reject(&:empty?) end |