Class: Ace::Git::Molecules::BranchReader

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/git/molecules/branch_reader.rb

Overview

Reads git branch information Consolidated from ace-review GitBranchReader (adapted to use CommandExecutor)

Class Method Summary collapse

Class Method Details

.count_commits(range, executor: Atoms::CommandExecutor) ⇒ Object

Count commits in a rev-list range; nil when the range is invalid (e.g. no upstream configured)



88
89
90
91
92
93
# File 'lib/ace/git/molecules/branch_reader.rb', line 88

def count_commits(range, executor: Atoms::CommandExecutor)
  result = executor.execute("git", "rev-list", "--count", range)
  return nil unless result[:success]

  result[:output].strip.to_i
end

.current_branch(executor: Atoms::CommandExecutor) ⇒ String|nil

Get current git branch name or commit SHA if detached

Parameters:

  • executor (Module) (defaults to: Atoms::CommandExecutor) —

    Command executor

Returns:

  • (String|nil) —

    branch name, commit SHA (if detached), or nil if not in git repo



13
14
15
# File 'lib/ace/git/molecules/branch_reader.rb', line 13

def current_branch(executor: Atoms::CommandExecutor)
  executor.current_branch
end

.detached?(executor: Atoms::CommandExecutor) ⇒ Boolean

Check if HEAD is detached

Parameters:

  • executor (Module) (defaults to: Atoms::CommandExecutor) —

    Command executor

Returns:

  • (Boolean) —

    true if HEAD is detached



20
21
22
23
24
25
# File 'lib/ace/git/molecules/branch_reader.rb', line 20

def detached?(executor: Atoms::CommandExecutor)
  result = executor.execute("git", "rev-parse", "--abbrev-ref", "HEAD")
  return false unless result[:success]

  result[:output].strip == "HEAD"
end

.format_status(ahead, behind) ⇒ String

Format tracking status as human-readable string

Parameters:

  • ahead (Integer) —

    Commits ahead of remote

  • behind (Integer) —

    Commits behind remote

Returns:

  • (String) —

    Status description



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ace/git/molecules/branch_reader.rb', line 74

def format_status(ahead, behind)
  if ahead == 0 && behind == 0
    "up to date"
  elsif ahead > 0 && behind > 0
    "#{ahead} ahead, #{behind} behind"
  elsif ahead > 0
    "#{ahead} ahead"
  else
    "#{behind} behind"
  end
end

.full_info(executor: Atoms::CommandExecutor) ⇒ Hash

Get full branch information

Parameters:

  • executor (Module) (defaults to: Atoms::CommandExecutor) —

    Command executor

Returns:

  • (Hash) —

    Branch information



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ace/git/molecules/branch_reader.rb', line 51

def full_info(executor: Atoms::CommandExecutor)
  branch = current_branch(executor: executor)

  return {error: "Not in git repository or no branch"} if branch.nil?

  tracking = tracking_branch(executor: executor)
  status = tracking_status(executor: executor)

  {
    name: branch,
    detached: detached?(executor: executor),
    tracking: tracking,
    ahead: status[:ahead],
    behind: status[:behind],
    up_to_date: status[:ahead] == 0 && status[:behind] == 0,
    status_description: format_status(status[:ahead], status[:behind])
  }
end

.tracking_branch(executor: Atoms::CommandExecutor) ⇒ String|nil

Get remote tracking branch

Parameters:

  • executor (Module) (defaults to: Atoms::CommandExecutor) —

    Command executor

Returns:

  • (String|nil) —

    tracking branch name or nil



30
31
32
# File 'lib/ace/git/molecules/branch_reader.rb', line 30

def tracking_branch(executor: Atoms::CommandExecutor)
  executor.tracking_branch
end

.tracking_status(executor: Atoms::CommandExecutor) ⇒ Hash

Get remote tracking status (ahead/behind counts)

Parameters:

  • executor (Module) (defaults to: Atoms::CommandExecutor) —

    Command executor

Returns:

  • (Hash) —

    { ahead: Integer, behind: Integer }



37
38
39
40
41
42
43
44
45
46
# File 'lib/ace/git/molecules/branch_reader.rb', line 37

def tracking_status(executor: Atoms::CommandExecutor)
  ahead = count_commits("@{upstream}..HEAD", executor: executor)
  behind = count_commits("HEAD..@{upstream}", executor: executor)

  if ahead.nil? || behind.nil?
    return {ahead: 0, behind: 0, error: "No tracking branch or not in git repo"}
  end

  {ahead: ahead, behind: behind}
end