Class: Greenhouse::Projects::Repository

Inherits:
Object
  • Object
show all
Defined in:
lib/greenhouse/projects/repository.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object



7
8
9
10
# File 'lib/greenhouse/projects/repository.rb', line 7

def method_missing(meth, *args)
  return git.send(meth, *args) if git.respond_to?(meth)
  super
end

Instance Attribute Details

#localObject Also known as: path

Returns the value of attribute local.



4
5
6
# File 'lib/greenhouse/projects/repository.rb', line 4

def local
  @local
end

#remoteObject

Returns the value of attribute remote.



4
5
6
# File 'lib/greenhouse/projects/repository.rb', line 4

def remote
  @remote
end

Instance Method Details

#aheadObject

Return any unpushed local changes on all branches/remotes



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/greenhouse/projects/repository.rb', line 117

def ahead
  unsynced.select do |branch|
    lbranch = git.object(branch[0].name)
    begin
      rbranch = git.object("#{branch[1].name}/#{branch[0].name}")
      lcommit = lbranch.log.first
      rcommit = rbranch.log.first
    
      !rbranch.log.map(&:sha).include?(lcommit.sha) && lbranch.log.map(&:sha).include?(rcommit.sha)
    rescue
      true
    end
    
    #lcommit.date <= rcommit.date
  end
end

#ahead?Boolean

Check whether there are unpushed local changes on all branches/remotes

Returns:

  • (Boolean)


112
113
114
# File 'lib/greenhouse/projects/repository.rb', line 112

def ahead?
  !ahead.empty?
end

#behindObject

Return any unpulled changes on all branches/remotes



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/greenhouse/projects/repository.rb', line 140

def behind
  unsynced.select do |branch|
    lbranch = git.object(branch[0].name)
    begin
      rbranch = git.object("#{branch[1].name}/#{branch[0].name}")
      lcommit = lbranch.log.first
      rcommit = rbranch.log.first
      
      rbranch.log.map(&:sha).include?(lcommit.sha) && !lbranch.log.map(&:sha).include?(rcommit.sha)
    rescue
      false
    end
    
    #lcommit.date >= rcommit.date
  end
end

#behind?Boolean

Check if there are any unpulled changes on all branches/remotes

Returns:

  • (Boolean)


135
136
137
# File 'lib/greenhouse/projects/repository.rb', line 135

def behind?
  !behind.empty?
end

#changedObject



42
43
44
# File 'lib/greenhouse/projects/repository.rb', line 42

def changed
  git.status.changed.select { |name,file| !git.diff('HEAD', '--').path(name).to_s.empty? }
end

#changed?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/greenhouse/projects/repository.rb', line 38

def changed?
  !changed.empty?
end

#changes(include_untracked = true) ⇒ Object

Get a list of all local changes (modified, added, deleted & untracked)



31
32
33
34
35
36
# File 'lib/greenhouse/projects/repository.rb', line 31

def changes(include_untracked=true)
  raise "Repository does not exist: #{@local}" unless cloned?
  changes = changed.merge(git.status.added).merge(git.status.deleted)
  changes.merge!(untracked) if include_untracked
  changes
end

#changes?(untracked = true) ⇒ Boolean

Check whether there are any uncommited local changes

Returns:

  • (Boolean)


25
26
27
28
# File 'lib/greenhouse/projects/repository.rb', line 25

def changes?(untracked=true)
  raise "Repository does not exist: #{@local}" unless cloned?
  !changes(untracked).empty?
end

#cloneObject

Clone the remote into the local path



13
14
15
16
# File 'lib/greenhouse/projects/repository.rb', line 13

def clone
  raise "Repository already exists: #{@local}" if cloned?
  Git.clone(@remote, @local.split("/").last)
end

#cloned?Boolean Also known as: exists?

Check if the remote has been cloned locally

Returns:

  • (Boolean)


19
20
21
# File 'lib/greenhouse/projects/repository.rb', line 19

def cloned?
  File.exists?(@local) && @git ||= Git.open(@local)
end

#destroyObject

Remove the local repository



209
210
211
# File 'lib/greenhouse/projects/repository.rb', line 209

def destroy
  FileUtils.rm_rf @local
end

#divergedObject



161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/greenhouse/projects/repository.rb', line 161

def diverged
  unsynced.select do |branch|
    lbranch = git.object(branch[0].name)
    begin
      rbranch = git.object("#{branch[1].name}/#{branch[0].name}")
      lcommit = lbranch.log.first
      rcommit = rbranch.log.first
    
      !rbranch.log.map(&:sha).include?(lcommit.sha) && !lbranch.log.map(&:sha).include?(rcommit.sha)
    rescue
      false
    end
  end
end

#diverged?Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/greenhouse/projects/repository.rb', line 157

def diverged?
  !diverged.empty?
end

#gitObject



213
214
215
216
# File 'lib/greenhouse/projects/repository.rb', line 213

def git
  @git ||= Git.open(@local)
  @git
end

#not_checked_outObject

Remote branches that aren’t checked out locally



82
83
84
85
86
# File 'lib/greenhouse/projects/repository.rb', line 82

def not_checked_out
  git.branches.remote.select do |branch|
    !branch.full.match(/HEAD/) && !git.branches.local.map(&:name).include?(branch.full.split("/").last)
  end
end

#not_checked_out?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/greenhouse/projects/repository.rb', line 77

def not_checked_out?
  !not_checked_out.empty?
end

#othersObject

Return the results of ‘ls-files –others` to list ignored/untracked files



71
72
73
74
75
# File 'lib/greenhouse/projects/repository.rb', line 71

def others
  git.chdir do
    return `git ls-files --others`.split("\n")
  end
end

#out_of_syncObject



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/greenhouse/projects/repository.rb', line 184

def out_of_sync
  unsynced.select do |branch|
    lbranch = git.object(branch[0].name)
    begin
      rbranch = git.object("#{branch[1].name}/#{branch[0].name}")
      lcommit = lbranch.log.first
      rcommit = rbranch.log.first
    
      (rbranch.log.map(&:sha).include?(lcommit.sha) && !lbranch.log.map(&:sha).include?(rcommit.sha)) ||
      (!rbranch.log.map(&:sha).include?(lcommit.sha) && !lbranch.log.map(&:sha).include?(rcommit.sha))
    rescue
      true
    end
  end
end

#out_of_sync?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/greenhouse/projects/repository.rb', line 180

def out_of_sync?
  behind? || diverged?
end

#pop_stashObject



204
205
206
# File 'lib/greenhouse/projects/repository.rb', line 204

def pop_stash
  git.chdir { `git stash pop 2>&1` }
end

#stagedObject



54
55
56
# File 'lib/greenhouse/projects/repository.rb', line 54

def staged
  changed.merge(git.status.added).merge(git.status.deleted).delete_if { |name,file| file.sha_index.empty? || file.sha_index == '0000000000000000000000000000000000000000' }
end

#staged?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/greenhouse/projects/repository.rb', line 58

def staged?
  !staged.empty?
end

#stashObject



200
201
202
# File 'lib/greenhouse/projects/repository.rb', line 200

def stash
  git.chdir { `git stash 2>&1` }
end

#synced?Boolean

Check whether local branches are synced with the remotes

Returns:

  • (Boolean)


89
90
91
# File 'lib/greenhouse/projects/repository.rb', line 89

def synced?
  unsynced.empty?
end

#unstagedObject



62
63
64
# File 'lib/greenhouse/projects/repository.rb', line 62

def unstaged
  changed.merge(untracked).select { |name,file| file.sha_index.empty? || file.sha_index == '0000000000000000000000000000000000000000' }
end

#unstaged?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/greenhouse/projects/repository.rb', line 66

def unstaged?
  !unstaged.empty?
end

#unsyncedObject

Return any unsynced branches for all remotes



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/greenhouse/projects/repository.rb', line 94

def unsynced
  branches = []
  git.branches.local.each do |branch|
    git.remotes.each do |remote|
      lcommit = git.object(branch.name).log.first
      begin
        rcommit = git.object("#{remote.name}/#{branch.name}").log.first
        next if lcommit.sha == rcommit.sha
        branches << [branch, remote]
      rescue # can this just be an ensure? will the next still work without ensuring?
        branches << [branch, remote]
      end
    end
  end
  branches
end

#untrackedObject



46
47
48
# File 'lib/greenhouse/projects/repository.rb', line 46

def untracked
  git.status.untracked.select { |name,file| !name.match(/\Atmp\/.*\Z/) } # temporary hack to avoid untracked tmp files, since they're not being properly ignored(?)
end

#untracked?Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/greenhouse/projects/repository.rb', line 50

def untracked?
  !untracked.empty?
end

#up_to_date?Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/greenhouse/projects/repository.rb', line 176

def up_to_date?
  !out_of_sync?
end