Module: Git

Defined in:
lib/git/branch/stray.rb,
lib/git/branch/stray/gemspec.rb,
lib/git/branch/stray/version.rb

Defined Under Namespace

Modules: Branch

Class Method Summary collapse

Class Method Details

.branch_name_from(symbolic_ref) ⇒ Object



46
47
48
49
50
51
# File 'lib/git/branch/stray.rb', line 46

def branch_name_from(symbolic_ref)
  # extract the branch name from a given symbolic ref
  # local:  e.g. "refs/heads/master"
  # remote: e.g. "refs/remotes/origin/master"
  symbolic_ref.sub(%r{\Arefs/(heads|remotes/[^/]+)/}, '')
end

.delete_stray_branchesObject



70
71
72
73
74
75
76
77
78
79
# File 'lib/git/branch/stray.rb', line 70

def delete_stray_branches
  stray_branches.each_consented('Delete stray branch "%s"') do |stray|
    system("git branch -d #{stray}")
    next if $CHILD_STATUS.success?

    Array(stray).each_consented('Delete unmerged branch "%s"') do |unmerged|
      system("git branch -D #{unmerged}")
    end
  end
end

.head_refs_for(remote) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/git/branch/stray.rb', line 20

def head_refs_for(remote)
  # alternative implementation that requires
  # access to the remote tracking repository
  #
  # git("ls-remote --quiet --refs --heads #{remote}")
  #   .map { |sha_and_ref| sha_and_ref.split(/\s+/).last }
  #
  # but we assume that this utility will mainly be
  # used as part of a "git workflow" that includes
  # regular pruning of remote tracking references,
  # which means we don't have to go over the wire!
  git("for-each-ref --format='%(refname)' refs/remotes/#{remote}")
end

.list_stray_branchesObject



81
82
83
84
85
# File 'lib/git/branch/stray.rb', line 81

def list_stray_branches
  stray_branches.each do |stray|
    system("git --no-pager branch -vv --list #{stray}")
  end
end

.local_head_refsObject



16
17
18
# File 'lib/git/branch/stray.rb', line 16

def local_head_refs
  git("for-each-ref --format='%(refname)' refs/heads")
end

.merge_ref_for(branch) ⇒ Object



42
43
44
# File 'lib/git/branch/stray.rb', line 42

def merge_ref_for(branch)
  git("config --local --get branch.#{branch}.merge").first
end

.remote_for(branch) ⇒ Object



38
39
40
# File 'lib/git/branch/stray.rb', line 38

def remote_for(branch)
  git("config --local --get branch.#{branch}.remote").first
end

.stray_branchesObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/git/branch/stray.rb', line 53

def stray_branches
  to_branch_name = method(:branch_name_from)

  local_branch_names = local_head_refs.map(&to_branch_name)

  remote_branch_names = Hash.new { |branch_names, remote|
    branch_names[remote] = head_refs_for(remote).map(&to_branch_name)
  }

  local_branch_names.find_all { |local_branch|
    (remote = remote_for(local_branch)) &&
    (merge_ref = merge_ref_for(local_branch)) &&
    (upstream_branch = to_branch_name[merge_ref]) &&
    !remote_branch_names[remote].include?(upstream_branch)
  }
end

.upstream_reference_for(branch) ⇒ Object



34
35
36
# File 'lib/git/branch/stray.rb', line 34

def upstream_reference_for(branch)
  git("rev-parse --verify --abbrev-ref #{branch}@{upstream}").first
end