Class: RightGit::Git::BranchCollection
- Inherits:
-
Object
- Object
- RightGit::Git::BranchCollection
- Includes:
- BelongsToRepository
- Defined in:
- lib/right_git/git/branch_collection.rb
Overview
A collection of Git branches. Acts a bit like an Array, allowing it to be mapped, sorted and compared as such.
Constant Summary collapse
- HEAD_REF =
Regexp matching (and capturing) the output of ‘git symbolic-ref’; used to determine which branch is currently checked out.
%r{^refs/heads/(#{Branch::BRANCH_NAME})$}
- NO_HEAD_REF =
The output of ‘git symbolic-ref’ when the HEAD ref is not on any branch.
/^HEAD is not a symbolic ref$/
- NOT_A_BRANCH =
The output of the ‘git branch’ command when the HEAD ref is not on any branch or in a detached HEAD state (e.g. “* (detached from v1.0)”) when pointing to a tag or the repo has no branches (“* (no branch)”).
This is not useful to RightGit, so we must filter it out of Git’s output when we see it.
/^\* \(.*\)$/
Instance Attribute Summary
Attributes included from BelongsToRepository
Instance Method Summary collapse
-
#[](argument) ⇒ Object
Accessor that acts like either a Hash or Array accessor.
-
#current ⇒ Branch
Return a Branch object representing whichever branch is currently checked out, IF AND ONLY IF that branch is a member of the collection.
-
#initialize(repo, branches = nil) ⇒ BranchCollection
constructor
Create a new BranchCollection.
-
#inspect ⇒ Object
Provide a programmer-friendly representation of this collection.
-
#local ⇒ BranchCollection
Return another collection that contains only the local branches in this collection.
-
#merged(revision) ⇒ BranchCollection
Queries and filters on branches reachable from the given revision, if any.
-
#method_missing(meth, *args, &block) ⇒ Object
Dispatch to the underlying Array of Branch objects, allowing the branch collection to act a bit like an Array.
-
#remote ⇒ BranchCollection
Return another collection that contains only the local branches in this collection.
-
#respond_to?(meth) ⇒ Boolean
Polite implementation of #respond_to that honors our #method_missing.
-
#to_s ⇒ Object
Provide a String representation of this collection, depicting it as a comma-separated list of branch names.
Methods included from BelongsToRepository
Constructor Details
#initialize(repo, branches = nil) ⇒ BranchCollection
Create a new BranchCollection. Don’t pass in a branches parameter unless you really know what you’re doing; it’s intended more for internal use than anything else.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/right_git/git/branch_collection.rb', line 53 def initialize(repo, branches=nil) @repo = repo if branches # Use an arbitrary set of branches that was passed in @branches = branches else @branches = [] # Initialize ourselves with all branches in the repository git_args = ['branch', '-a'] @repo.git_output(git_args).lines.each do |line| line.strip! if line =~ NOT_A_BRANCH #no-op; ignore this one else @branches << Branch.new(@repo, line) end end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object
Dispatch to the underlying Array of Branch objects, allowing the branch collection to act a bit like an Array.
If the dispatched-to method returns an Array, it is wrapped in another BranchCollection object before returning to the caller. This allows array-like method calls to be chained together without losing the BranchCollection-ness of the underlying object.
175 176 177 178 179 180 181 182 183 |
# File 'lib/right_git/git/branch_collection.rb', line 175 def method_missing(meth, *args, &block) result = @branches.__send__(meth, *args, &block) if result.is_a?(::Array) BranchCollection.new(@repo, result) else result end end |
Instance Method Details
#[](argument) ⇒ Object
Accessor that acts like either a Hash or Array accessor
159 160 161 162 163 164 165 166 167 |
# File 'lib/right_git/git/branch_collection.rb', line 159 def [](argument) case argument when String target = Branch.new(@repo, argument) @branches.detect { |b| b == target } else @branches.__send__(:[], argument) end end |
#current ⇒ Branch
Return a Branch object representing whichever branch is currently checked out, IF AND ONLY IF that branch is a member of the collection. If the current branch isn’t part of the collection or HEAD refers to something other than a branch, return nil.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/right_git/git/branch_collection.rb', line 92 def current lines = @repo.git_output(['symbolic-ref', 'HEAD'], :raise_on_failure => false).lines if lines.size == 1 line = lines.first.strip if (match = HEAD_REF.match(line)) @branches.detect { |b| b.fullname == match[1] } elsif line == NO_HEAD_REF nil end else raise GitError, "Unexpected output from 'git symbolic-ref'; need 1 lines, got #{lines.size}" end end |
#inspect ⇒ Object
Provide a programmer-friendly representation of this collection.
83 84 85 |
# File 'lib/right_git/git/branch_collection.rb', line 83 def inspect '#<%s:%s>' % [self.class.name, @branches.inspect] end |
#local ⇒ BranchCollection
Return another collection that contains only the local branches in this collection.
110 111 112 113 114 115 116 117 118 |
# File 'lib/right_git/git/branch_collection.rb', line 110 def local local = [] @branches.each do |branch| local << branch unless branch.remote? end BranchCollection.new(@repo, local) end |
#merged(revision) ⇒ BranchCollection
Queries and filters on branches reachable from the given revision, if any.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/right_git/git/branch_collection.rb', line 138 def merged(revision) # By hand, build a list of all branches known to be merged into master git_args = ['branch', '-a', '--merged', revision] all_merged = [] @repo.git_output(git_args).lines.each do |line| line.strip! all_merged << Branch.new(@repo, line) end # Filter the contents of this collection according to the big list merged = [] @branches.each do |candidate| # For some reason Set#include? does not play nice with our overridden comparison operators # for branches, so we need to do this the hard way :( merged << candidate if all_merged.detect { |b| candidate == b } end BranchCollection.new(@repo, merged) end |
#remote ⇒ BranchCollection
Return another collection that contains only the local branches in this collection.
123 124 125 126 127 128 129 130 131 |
# File 'lib/right_git/git/branch_collection.rb', line 123 def remote remote = [] @branches.each do |branch| remote << branch if branch.remote? end BranchCollection.new(@repo, remote) end |
#respond_to?(meth) ⇒ Boolean
Polite implementation of #respond_to that honors our #method_missing.
186 187 188 |
# File 'lib/right_git/git/branch_collection.rb', line 186 def respond_to?(meth) super || @branches.respond_to?(meth) end |
#to_s ⇒ Object
Provide a String representation of this collection, depicting it as a comma-separated list of branch names.
78 79 80 |
# File 'lib/right_git/git/branch_collection.rb', line 78 def to_s @branches.join(',') end |