Class: E2B::Services::Git
- Inherits:
-
Object
- Object
- E2B::Services::Git
- Defined in:
- lib/e2b/services/git.rb
Overview
Git operations service for E2B sandbox
Runs git CLI commands inside the sandbox by delegating to the Commands service. Does not use RPC directly - all operations are performed via shell commands.
Constant Summary collapse
- DEFAULT_GIT_ENV =
Default environment variables applied to all git commands
{ "GIT_TERMINAL_PROMPT" => "0" }.freeze
- DEFAULT_TIMEOUT =
Default timeout for git operations in seconds
300- VALID_SCOPES =
Valid git config scopes
%w[global local system].freeze
Instance Method Summary collapse
-
#add(path, files: nil, all: true, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Stage files for commit.
-
#branches(path, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ GitBranches
List all branches (local and remote).
-
#checkout_branch(path, branch, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Checkout an existing branch.
-
#clone(url, path: nil, branch: nil, depth: nil, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Clone a git repository.
-
#commit(path, message, author_name: nil, author_email: nil, allow_empty: false, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Create a commit.
-
#configure_user(name, email, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ void
Configure the git user name and email.
-
#create_branch(path, branch, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Create a new branch.
-
#dangerously_authenticate(username, password, host: "github.com", protocol: "https", envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Configure a credential helper that accepts any credentials without prompting.
-
#delete_branch(path, branch, force: false, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Delete a branch.
-
#get_config(key, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ String?
Get a git configuration value.
-
#init(path, bare: false, initial_branch: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Initialize a new git repository.
-
#initialize(commands:) ⇒ Git
constructor
A new instance of Git.
-
#pull(path, remote: nil, branch: nil, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Pull changes from a remote repository.
-
#push(path, remote: nil, branch: nil, set_upstream: true, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Push commits to a remote repository.
-
#remote_add(path, name, url, fetch: false, overwrite: false, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Add a remote to a repository.
-
#remote_get(path, name, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ String?
Get the URL of a named remote.
-
#reset(path, mode: nil, target: nil, paths: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Reset the current HEAD to a specified state.
-
#restore(path, paths, staged: nil, worktree: nil, source: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Restore working tree files.
-
#set_config(key, value, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Set a git configuration value.
-
#status(path, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ GitStatus
Get the status of a git repository.
Constructor Details
#initialize(commands:) ⇒ Git
Returns a new instance of Git.
166 167 168 |
# File 'lib/e2b/services/git.rb', line 166 def initialize(commands:) @commands = commands end |
Instance Method Details
#add(path, files: nil, all: true, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Stage files for commit
358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/e2b/services/git.rb', line 358 def add(path, files: nil, all: true, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["add"] if all args << "-A" elsif files && !files.empty? files.each { |f| args << Shellwords.escape(f) } else args << "-A" end run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#branches(path, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ GitBranches
List all branches (local and remote)
298 299 300 301 302 |
# File 'lib/e2b/services/git.rb', line 298 def branches(path, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["branch", "-a", "--format=%(refname:short) %(HEAD)"] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) parse_branches(result.stdout) end |
#checkout_branch(path, branch, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Checkout an existing branch
327 328 329 330 |
# File 'lib/e2b/services/git.rb', line 327 def checkout_branch(path, branch, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["checkout", branch] run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#clone(url, path: nil, branch: nil, depth: nil, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Clone a git repository
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/e2b/services/git.rb', line 184 def clone(url, path: nil, branch: nil, depth: nil, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) clone_url = if username && password with_credentials(url, username, password) else url end args = ["clone"] args += ["--branch", branch] if branch args += ["--depth", depth.to_s] if depth args << Shellwords.escape(clone_url) args << Shellwords.escape(path) if path result = run_git(args, nil, envs: envs, user: user, cwd: cwd, timeout: timeout) check_auth_failure!(result) result end |
#commit(path, message, author_name: nil, author_email: nil, allow_empty: false, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Create a commit
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/e2b/services/git.rb', line 383 def commit(path, , author_name: nil, author_email: nil, allow_empty: false, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["commit", "-m", Shellwords.escape()] args << "--allow-empty" if allow_empty commit_envs = (envs || {}).dup if && commit_envs["GIT_AUTHOR_NAME"] = commit_envs["GIT_COMMITTER_NAME"] = commit_envs["GIT_AUTHOR_EMAIL"] = commit_envs["GIT_COMMITTER_EMAIL"] = end run_git(args, path, envs: commit_envs, user: user, cwd: cwd, timeout: timeout) end |
#configure_user(name, email, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ void
This method returns an undefined value.
Configure the git user name and email
605 606 607 608 609 610 |
# File 'lib/e2b/services/git.rb', line 605 def configure_user(name, email, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) set_config("user.name", name, scope: scope, path: path, envs: envs, user: user, cwd: cwd, timeout: timeout) set_config("user.email", email, scope: scope, path: path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#create_branch(path, branch, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Create a new branch
313 314 315 316 |
# File 'lib/e2b/services/git.rb', line 313 def create_branch(path, branch, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["branch", branch] run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#dangerously_authenticate(username, password, host: "github.com", protocol: "https", envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Configure a credential helper that accepts any credentials without prompting
WARNING: This stores credentials in plaintext in the git credential store. Use only in sandbox environments where security of stored credentials is acceptable.
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 |
# File 'lib/e2b/services/git.rb', line 570 def dangerously_authenticate(username, password, host: "github.com", protocol: "https", envs: nil, user: nil, cwd: nil, timeout: nil) # Configure credential helper to use the store set_config("credential.helper", "store", scope: "global", envs: envs, user: user, cwd: cwd, timeout: timeout) # Write credentials to the credential store via git credential approve credential_input = [ "protocol=#{protocol}", "host=#{host}", "username=#{username}", "password=#{password}", "" ].join("\n") escaped_input = Shellwords.escape(credential_input) args = ["credential", "approve"] cmd = build_git_command(args, nil) full_cmd = "echo #{escaped_input} | #{cmd}" merged_envs = DEFAULT_GIT_ENV.merge(envs || {}) @commands.run(full_cmd, cwd: cwd, envs: merged_envs, timeout: timeout || DEFAULT_TIMEOUT) end |
#delete_branch(path, branch, force: false, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Delete a branch
342 343 344 345 346 |
# File 'lib/e2b/services/git.rb', line 342 def delete_branch(path, branch, force: false, envs: nil, user: nil, cwd: nil, timeout: nil) flag = force ? "-D" : "-d" args = ["branch", flag, branch] run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#get_config(key, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ String?
Get a git configuration value
545 546 547 548 549 550 551 552 553 554 |
# File 'lib/e2b/services/git.rb', line 545 def get_config(key, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) validate_scope!(scope) args = ["config", scope_flag(scope), "--get", key] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) return nil unless result.success? value = result.stdout.strip value.empty? ? nil : value end |
#init(path, bare: false, initial_branch: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Initialize a new git repository
213 214 215 216 217 218 219 220 |
# File 'lib/e2b/services/git.rb', line 213 def init(path, bare: false, initial_branch: nil, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["init"] args << "--bare" if args += ["--initial-branch", initial_branch] if initial_branch args << Shellwords.escape(path) run_git(args, nil, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#pull(path, remote: nil, branch: nil, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Pull changes from a remote repository
When username and password are provided, the remote URL is temporarily modified to include credentials, then restored after the pull completes.
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/e2b/services/git.rb', line 500 def pull(path, remote: nil, branch: nil, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) effective_remote = remote || "origin" if username && password with_authenticated_remote(path, effective_remote, username, password, envs: envs, user: user, cwd: cwd, timeout: timeout) do do_pull(path, effective_remote, branch, envs: envs, user: user, cwd: cwd, timeout: timeout) end else do_pull(path, effective_remote, branch, envs: envs, user: user, cwd: cwd, timeout: timeout) end end |
#push(path, remote: nil, branch: nil, set_upstream: true, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Push commits to a remote repository
When username and password are provided, the remote URL is temporarily modified to include credentials, then restored after the push completes.
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 |
# File 'lib/e2b/services/git.rb', line 468 def push(path, remote: nil, branch: nil, set_upstream: true, username: nil, password: nil, envs: nil, user: nil, cwd: nil, timeout: nil) effective_remote = remote || "origin" if username && password with_authenticated_remote(path, effective_remote, username, password, envs: envs, user: user, cwd: cwd, timeout: timeout) do do_push(path, effective_remote, branch, set_upstream, envs: envs, user: user, cwd: cwd, timeout: timeout) end else do_push(path, effective_remote, branch, set_upstream, envs: envs, user: user, cwd: cwd, timeout: timeout) end end |
#remote_add(path, name, url, fetch: false, overwrite: false, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Add a remote to a repository
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/e2b/services/git.rb', line 234 def remote_add(path, name, url, fetch: false, overwrite: false, envs: nil, user: nil, cwd: nil, timeout: nil) if overwrite # Check if remote already exists existing = remote_get(path, name, envs: envs, user: user, cwd: cwd, timeout: timeout) if existing args = ["remote", "set-url", name, Shellwords.escape(url)] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) else args = ["remote", "add", name, Shellwords.escape(url)] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end else args = ["remote", "add", name, Shellwords.escape(url)] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end if fetch fetch_args = ["fetch", name] run_git(fetch_args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end result end |
#remote_get(path, name, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ String?
Get the URL of a named remote
267 268 269 270 271 272 273 274 |
# File 'lib/e2b/services/git.rb', line 267 def remote_get(path, name, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["remote", "get-url", name] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) return nil unless result.success? url = result.stdout.strip url.empty? ? nil : url end |
#reset(path, mode: nil, target: nil, paths: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Reset the current HEAD to a specified state
410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/e2b/services/git.rb', line 410 def reset(path, mode: nil, target: nil, paths: nil, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["reset"] args << "--#{mode}" if mode args << target if target if paths && !paths.empty? args << "--" paths.each { |p| args << Shellwords.escape(p) } end run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#restore(path, paths, staged: nil, worktree: nil, source: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Restore working tree files
435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'lib/e2b/services/git.rb', line 435 def restore(path, paths, staged: nil, worktree: nil, source: nil, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["restore"] args << "--staged" if staged args << "--worktree" if worktree args += ["--source", source] if source if paths.is_a?(Array) paths.each { |p| args << Shellwords.escape(p) } else args << Shellwords.escape(paths) end run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#set_config(key, value, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ E2B::Models::ProcessResult
Set a git configuration value
528 529 530 531 532 533 |
# File 'lib/e2b/services/git.rb', line 528 def set_config(key, value, scope: "global", path: nil, envs: nil, user: nil, cwd: nil, timeout: nil) validate_scope!(scope) args = ["config", scope_flag(scope), key, Shellwords.escape(value)] run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) end |
#status(path, envs: nil, user: nil, cwd: nil, timeout: nil) ⇒ GitStatus
Get the status of a git repository
284 285 286 287 288 |
# File 'lib/e2b/services/git.rb', line 284 def status(path, envs: nil, user: nil, cwd: nil, timeout: nil) args = ["status", "--porcelain=v2", "--branch"] result = run_git(args, path, envs: envs, user: user, cwd: cwd, timeout: timeout) parse_status(result.stdout) end |