Class: GitRepo

Inherits:
Object show all
Defined in:
lib/git-smart/git_repo.rb

Instance Method Summary collapse

Constructor Details

#initialize(dir) ⇒ GitRepo

Returns a new instance of GitRepo.



2
3
4
5
6
7
# File 'lib/git-smart/git_repo.rb', line 2

def initialize(dir)
  @dir = dir
  if !File.exists? File.join(@dir, ".git")
    raise GitSmart::RunFailed.new("You need to run this from within a git directory")
  end
end

Instance Method Details

#config(name) ⇒ Object



130
131
132
133
# File 'lib/git-smart/git_repo.rb', line 130

def config(name)
  remote = git('config', name).chomp
  remote.empty? ? nil : remote
end

#current_branchObject



9
10
11
# File 'lib/git-smart/git_repo.rb', line 9

def current_branch
  File.read(File.join(@dir, ".git", "HEAD")).strip.sub(/^.*refs\/heads\//, '')
end

#dirty?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/git-smart/git_repo.rb', line 72

def dirty?
  status.any? { |k,v| k != :untracked && v.any? }
end

#exists?(ref) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
# File 'lib/git-smart/git_repo.rb', line 42

def exists?(ref)
  git('rev-parse', ref)
  $?.success?
end

#fast_forward!(upstream) ⇒ Object



76
77
78
# File 'lib/git-smart/git_repo.rb', line 76

def fast_forward!(upstream)
  git!('merge', '--ff-only', upstream)
end

#fetch!(remote) ⇒ Object



34
35
36
# File 'lib/git-smart/git_repo.rb', line 34

def fetch!(remote)
  git!('fetch', remote)
end

#git(*args) ⇒ Object

helper methods, left public in case other commands want to use them directly



110
111
112
113
# File 'lib/git-smart/git_repo.rb', line 110

def git(*args)
  output = exec_git(*args)
  $?.success? ? output : ''
end

#git!(*args) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/git-smart/git_repo.rb', line 115

def git!(*args)
  puts "Executing: #{['git', *args].join(" ")}"
  output = exec_git(*args)
  to_display = output.split("\n").map { |l| "  #{l}" }.join("\n")
  $?.success? ? puts(to_display) : raise(GitSmart::UnexpectedOutput.new(to_display))
  output
end

#git_shell(*args) ⇒ Object



123
124
125
126
127
128
# File 'lib/git-smart/git_repo.rb', line 123

def git_shell(*args)
  puts "Executing: #{['git', *args].join(" ")}"
  Dir.chdir(@dir) {
    system('git', *args)
  }
end

#last_commit_messages(nr) ⇒ Object



96
97
98
# File 'lib/git-smart/git_repo.rb', line 96

def last_commit_messages(nr)
  read_log(nr).map(&:last)
end

#log_to_shell(*args) ⇒ Object



100
101
102
# File 'lib/git-smart/git_repo.rb', line 100

def log_to_shell(*args)
  git_shell('log', *args)
end

#merge_base(ref_a, ref_b) ⇒ Object



38
39
40
# File 'lib/git-smart/git_repo.rb', line 38

def merge_base(ref_a, ref_b)
  git('merge-base', ref_a, ref_b).chomp
end

#merge_no_ff!(target) ⇒ Object



104
105
106
# File 'lib/git-smart/git_repo.rb', line 104

def merge_no_ff!(target)
  git!('merge', '--no-ff', target)
end

#raw_statusObject



51
52
53
# File 'lib/git-smart/git_repo.rb', line 51

def raw_status
  git('status', '-s')
end

#read_log(nr) ⇒ Object



92
93
94
# File 'lib/git-smart/git_repo.rb', line 92

def read_log(nr)
  git('log', '--oneline', '-n', nr.to_s).split("\n").map { |l| l.split(" ",2) }
end

#rebase_preserving_merges!(upstream) ⇒ Object



88
89
90
# File 'lib/git-smart/git_repo.rb', line 88

def rebase_preserving_merges!(upstream)
  git!('rebase', '-p', upstream)
end

#rev_list(ref_a, ref_b) ⇒ Object



47
48
49
# File 'lib/git-smart/git_repo.rb', line 47

def rev_list(ref_a, ref_b)
  git('rev-list', "#{ref_a}..#{ref_b}").split("\n")
end

#sha(ref) ⇒ Object



13
14
15
16
# File 'lib/git-smart/git_repo.rb', line 13

def sha(ref)
  sha = git('rev-parse', ref).chomp
  sha.empty? ? nil : sha
end

#stash!Object



80
81
82
# File 'lib/git-smart/git_repo.rb', line 80

def stash!
  git!('stash')
end

#stash_pop!Object



84
85
86
# File 'lib/git-smart/git_repo.rb', line 84

def stash_pop!
  git!('stash', 'pop')
end

#statusObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/git-smart/git_repo.rb', line 55

def status
  raw_status.
    split("\n").
    map { |l| l.split(" ") }.
    group_by(&:first).
    map_values { |lines| lines.map(&:last) }.
    map_keys { |status|
      case status
        when /^[^ ]*M/; :modified
        when /^[^ ]*A/; :added
        when /^[^ ]*\?\?/; :untracked
        when /^[^ ]*UU/; :conflicted
        else raise GitSmart::UnexpectedOutput.new("Expected the output of git status to only have lines starting with A,M, or ??. Got: \n#{raw_status}")
      end
    }
end

#tracking_branchObject



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/git-smart/git_repo.rb', line 22

def tracking_branch
  key   = "branch.#{current_branch}.merge"
  value = config(key)
  if value.nil?
    value
  elsif value =~ /^refs\/heads\/(.*)$/
    $1
  else
    raise GitSmart::UnexpectedOutput.new("Expected the config of '#{key}' to be /refs/heads/branchname, got '#{value}'")
  end
end

#tracking_remoteObject



18
19
20
# File 'lib/git-smart/git_repo.rb', line 18

def tracking_remote
  config("branch.#{current_branch}.remote")
end