Class: GithubPivotalFlow::Git

Inherits:
Object
  • Object
show all
Defined in:
lib/github_pivotal_flow/git.rb

Class Method Summary collapse

Class Method Details

.add_hook(name, source, overwrite = false) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/github_pivotal_flow/git.rb', line 155

def self.add_hook(name, source, overwrite = false)
  hooks_directory =  File.join repository_root, '.git', 'hooks'
  hook = File.join hooks_directory, name
  if overwrite || !File.exist?(hook)
    print "Creating Git hook #{name}...  "

    FileUtils.mkdir_p hooks_directory
    File.open(source, 'r') do |input|
      File.open(hook, 'w') do |output|
        output.write(input.read)
        output.chmod(0755)
      end
    end

    puts 'OK'
  end
end

.branch_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/github_pivotal_flow/git.rb', line 39

def self.branch_exists?(name)
  system "git show-ref --quiet --verify refs/heads/#{name}"
end

.checkout(branch_name) ⇒ Object



7
8
9
# File 'lib/github_pivotal_flow/git.rb', line 7

def self.checkout(branch_name)
  exec "git checkout --quiet #{branch_name}" unless branch_name == self.current_branch
end

.clean_working_tree?Boolean

Returns:

  • (Boolean)


173
174
175
176
177
178
179
# File 'lib/github_pivotal_flow/git.rb', line 173

def self.clean_working_tree?
  system("git diff --no-ext-diff --ignore-submodules --quiet --exit-code")
  fail("fatal: Working tree contains unstaged changes. Aborting.") if $?.exitstatus != 0
  system("git diff-index --cached --quiet --ignore-submodules HEAD --")
  fail("fatal: Index contains uncommited changes. Aborting.") if $?.exitstatus != 0
  return true
end

.commit(options = {}) ⇒ Object



65
66
67
68
69
70
# File 'lib/github_pivotal_flow/git.rb', line 65

def self.commit(options = {})
  command = "git commit --quiet"
  command << " --allow-empty" if options[:allow_empty]
  command << " -m \"#{options[:commit_message]}\"" unless options[:commit_message].blank?
  exec command
end

.create_branch(branch_name, start_point = nil, options = {}) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/github_pivotal_flow/git.rb', line 30

def self.create_branch(branch_name, start_point = nil, options = {})
  return if branch_exists?(branch_name)
  command = "git branch --quiet"
  command << " --track" if options[:track]
  command << " --set-upstream" if options[:set_upstream]
  exec "#{command} #{[branch_name, start_point].compact.join(' ')}"
  puts 'OK'
end

.current_branchObject



3
4
5
# File 'lib/github_pivotal_flow/git.rb', line 3

def self.current_branch
  exec('git branch').scan(/\* (.*)/)[0][0]
end

.delete_branch(branch_name, options = {}) ⇒ Object



80
81
82
83
84
85
# File 'lib/github_pivotal_flow/git.rb', line 80

def self.delete_branch(branch_name, options = {})
  command = "git branch"
  command << (options[:force] ? " -D" : " -d")
  exec "#{command} #{branch_name}"
  puts 'OK'
end

.delete_config(key, scope = :local) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
# File 'lib/github_pivotal_flow/git.rb', line 132

def self.delete_config(key, scope = :local)
  if :branch == scope
    exec "git config --local --unset branch.#{self.current_branch}.#{key}"
  elsif :global == scope
    exec "git config --global --unset #{key}"
  elsif :local == scope
    exec "git config --local --unset #{key}"
  else
    raise "Unable to delete Git configuration for scope '#{scope}'"
  end
end

.delete_remote_branch(branch_name) ⇒ Object



87
88
89
# File 'lib/github_pivotal_flow/git.rb', line 87

def self.delete_remote_branch(branch_name)
  exec "git push #{Git.get_remote} --delete #{branch_name}"
end

.ensure_branch_exists(branch_name) ⇒ Object



43
44
45
46
# File 'lib/github_pivotal_flow/git.rb', line 43

def self.ensure_branch_exists(branch_name)
  return if branch_name == current_branch || self.branch_exists?(branch_name)
  exec "git branch --quiet #{branch_name}", false
end

.get_config(key, scope = :inherited) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/github_pivotal_flow/git.rb', line 109

def self.get_config(key, scope = :inherited)
  if :branch == scope
    exec("git config --get branch.#{self.current_branch}.#{key}", false).strip
  elsif :inherited == scope
    exec("git config --get #{key}", false).strip
  else
    raise "Unable to get Git configuration for scope '#{scope}'"
  end
end

.get_remoteObject



15
16
17
18
19
# File 'lib/github_pivotal_flow/git.rb', line 15

def self.get_remote
  remote = get_config('remote', :branch).strip
  return exec('git remote').strip if remote.blank?
  remote
end

.merge(branch_name, options = {}) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/github_pivotal_flow/git.rb', line 48

def self.merge(branch_name, options = {})
  command = "git merge --quiet"
  command << " --no-ff" if options[:no_ff]
  command << " --ff" if options[:ff] && !options[:no_ff]
  command << " -m \"#{options[:commit_message]}\"" unless options[:commit_message].blank?
  exec "#{command} #{branch_name}"
  puts 'OK'
end

.publish(branch_name, options = {}) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/github_pivotal_flow/git.rb', line 57

def self.publish(branch_name, options = {})
  branch_name ||= self.current_branch
  exec "git checkout --quiet #{branch_name}" unless branch_name == self.current_branch
  command = "git push"

  exec "#{command} #{self.get_remote} #{branch_name}"
end

.pull(ref, origin) ⇒ Object



11
12
13
# File 'lib/github_pivotal_flow/git.rb', line 11

def self.pull(ref, origin)
  exec "git pull --quiet #{[origin, ref].compact.join(' ')}"
end

.pull_remote(branch_name = nil) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/github_pivotal_flow/git.rb', line 21

def self.pull_remote(branch_name = nil)
  prev_branch = self.current_branch
  branch_name ||= self.current_branch
  self.checkout(branch_name)
  remote = self.get_remote
  self.pull(branch_name, remote) unless remote.blank?
  self.checkout(prev_branch)
end

.push(*refs) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/github_pivotal_flow/git.rb', line 91

def self.push(*refs)
  options = {}
  if refs.last.is_a?(Hash)
    options = refs.delete_at(-1)
  end
  remote = self.get_remote

  print "Pushing to #{remote}... "
  command = "git push --quiet"
  command << " --set-upstream" if options[:set_upstream]
  exec "#{command} #{remote} " + refs.join(' ')
  puts 'OK'
end

.push_tagsObject



105
106
107
# File 'lib/github_pivotal_flow/git.rb', line 105

def self.push_tags
  exec "git push --tags #{self.get_remote}"
end

.repository_rootObject



144
145
146
147
148
149
150
151
152
153
# File 'lib/github_pivotal_flow/git.rb', line 144

def self.repository_root
  repository_root = Dir.pwd

  until Dir.entries(repository_root).any? { |child| File.directory?(child) && (child =~ /^.git$/) }
    next_repository_root = File.expand_path('..', repository_root)
    abort('Current working directory is not in a Git repository') unless repository_root != next_repository_root
    repository_root =  next_repository_root
  end
  repository_root
end

.set_config(key, value, scope = :local) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/github_pivotal_flow/git.rb', line 119

def self.set_config(key, value, scope = :local)
  if :branch == scope
    exec "git config --local branch.#{self.current_branch}.#{key} #{value}"
  elsif :global == scope
    exec "git config --global #{key} #{value}"
  elsif :local == scope
    exec "git config --local #{key} #{value}"
  else
    raise "Unable to set Git configuration for scope '#{scope}'"
  end
  return value
end

.tag(tag_name, options = {}) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/github_pivotal_flow/git.rb', line 72

def self.tag(tag_name, options = {})
  command = "git tag"
  command << " -a" if options[:annotated]
  command << " -m \"#{options[:message]}\"" unless options[:message].blank?
  command << " #{tag_name}" if tag_name
  exec command
end