v 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/.watchr +24 -0
  4. data/.yardoc +0 -0
  5. data/LICENSE +20 -0
  6. data/README.markdown +146 -0
  7. data/Rakefile +56 -0
  8. data/VERSION +1 -0
  9. data/auto_commit.rb +131 -0
  10. data/lib/v/adapters/git/branches.rb +115 -0
  11. data/lib/v/adapters/git/commits.rb +55 -0
  12. data/lib/v/adapters/git/environment.rb +99 -0
  13. data/lib/v/adapters/git/index.rb +63 -0
  14. data/lib/v/adapters/git/object.rb +104 -0
  15. data/lib/v/adapters/git/object_types/blob.rb +24 -0
  16. data/lib/v/adapters/git/object_types/commit.rb +124 -0
  17. data/lib/v/adapters/git/object_types/tag.rb +23 -0
  18. data/lib/v/adapters/git/object_types/tree.rb +51 -0
  19. data/lib/v/adapters/git/operations/add_to_index.rb +30 -0
  20. data/lib/v/adapters/git/operations/branch.rb +42 -0
  21. data/lib/v/adapters/git/operations/commit_index.rb +39 -0
  22. data/lib/v/adapters/git/operations/diff_index.rb +20 -0
  23. data/lib/v/adapters/git/operations/initialize_repository.rb +21 -0
  24. data/lib/v/adapters/git/operations/list_files.rb +38 -0
  25. data/lib/v/adapters/git/operations/list_tree.rb +30 -0
  26. data/lib/v/adapters/git/operations/push_references_to_remote.rb +25 -0
  27. data/lib/v/adapters/git/operations/remove_from_index.rb +25 -0
  28. data/lib/v/adapters/git/operations/reset_index.rb +25 -0
  29. data/lib/v/adapters/git/operations/show_log.rb +23 -0
  30. data/lib/v/adapters/git/operations/show_object.rb +21 -0
  31. data/lib/v/adapters/git/operations/tag.rb +29 -0
  32. data/lib/v/adapters/git/participation.rb +18 -0
  33. data/lib/v/adapters/git/remotes.rb +19 -0
  34. data/lib/v/adapters/git/status.rb +60 -0
  35. data/lib/v/adapters/git.rb +27 -0
  36. data/lib/v/adapters.rb +25 -0
  37. data/lib/v/arguments.rb +102 -0
  38. data/lib/v/errors.rb +39 -0
  39. data/lib/v/future.rb +46 -0
  40. data/lib/v/operation.rb +94 -0
  41. data/lib/v/worker.rb +73 -0
  42. data/lib/v.rb +29 -0
  43. data/test/teststrap.rb +4 -0
  44. data/test/v_test.rb +32 -0
  45. data/test/work_tree/file +1 -0
  46. data/v.gemspec +97 -0
  47. metadata +131 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.markdown
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+
23
+ commit_message
data/.watchr ADDED
@@ -0,0 +1,24 @@
1
+ require 'open3'
2
+
3
+ Dir.chdir File.dirname(__FILE__)
4
+ File.open('commit_message', 'a').close
5
+
6
+ watch(/(?:commit_message)/) { |*|
7
+
8
+ puts 'Running syntax checks...'
9
+ Dir['lib/**/*.rb'].inject(true) do |check, path|
10
+ Open3.popen3('ruby', '-c', path) { |_, o, stderr|
11
+ errors = stderr.read
12
+
13
+ if errors.empty? then check
14
+ else
15
+ puts errors
16
+ false
17
+ end
18
+ }
19
+ end and begin
20
+ puts 'Running integration tests and release...'
21
+ system('ruby', 'auto_commit.rb')
22
+ end
23
+
24
+ }
data/.yardoc ADDED
Binary file
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Florian Aßmann, Fork Unstable Medie, Oniversus Media
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,146 @@
1
+ v
2
+ =
3
+
4
+ v is for versioned. It's is currently only a threaded wrapper for the git
5
+ commands or procedures. In the future it should provide a generic interface
6
+ for diverse VCSs.
7
+
8
+ This Project does not have a separate test suite. This projects version-tracks
9
+ itself when everything works as expected.
10
+
11
+ All operations are designed to be reimplemented as pure ruby version and their
12
+ interface is almost 1:1 mapped to their ruby derivate.
13
+
14
+ Install
15
+ -------
16
+
17
+ gem install v
18
+
19
+ or unless you installed gemcutter
20
+
21
+ gem install gemcutter
22
+ gem tumble
23
+ gem install v
24
+
25
+ Interface
26
+ ---------
27
+
28
+ require 'v'
29
+
30
+ V.git do
31
+ add '.'
32
+ commit 'Initial commit!'
33
+ end
34
+
35
+ Git::Environment uses git returned by `which git` by default (\*n\*ix).
36
+
37
+ ### Change the git executable globally
38
+
39
+ V::Adapters::Git::Environment.which_git = '/usr/local/bin/git'
40
+
41
+ ### Change the git executable locally
42
+
43
+ env = V.git :which_git => '/usr/local/bin/git'
44
+
45
+ # or
46
+
47
+ V.git do
48
+ @which_git = '/usr/local/bin/git'
49
+ # ...
50
+ end
51
+
52
+ ### Working with futures...
53
+
54
+ V.git do
55
+ # initialize repository and return environment (as future)
56
+ init == self
57
+
58
+ # add root to index return a index future
59
+ proxy = add '.'
60
+ # wait for result and return index
61
+ proxy.value == index
62
+ # shortcut for add '.'
63
+ index == index << '.'
64
+
65
+ # commit index and return commit future
66
+ proxy = commit 'initial commit'
67
+ # wait for result and return commit
68
+ commit = proxy.value
69
+
70
+ # Queries:
71
+ init.add('.').commit 'First argument is always the message!'
72
+ end
73
+
74
+ _See auto\_commit.rb for more examples._
75
+
76
+ Supported Operations
77
+ --------------------
78
+
79
+ * add
80
+ * branch
81
+ * commit
82
+ * diff-index => diff\_index (partially)
83
+ * init
84
+ * ls-files => ls\_files (what does -v mean?)
85
+ * ls-tree => ls\_tree (alias for args)
86
+ * push
87
+ * rm
88
+ * reset
89
+ * log (partially)
90
+ * show
91
+ * tag
92
+
93
+ Git Objects
94
+ -----------
95
+
96
+ * normal git objects
97
+ * Blob
98
+ * Commit
99
+ * Tag
100
+ * Tree
101
+ * convenience objects
102
+ * Head
103
+ * Index
104
+ * Branch
105
+ * Branches
106
+ * Commits
107
+
108
+ TODO
109
+ ----
110
+
111
+ * implement global cache / branch && git\_dir flag expired by branch mtime
112
+ * implement non-blocking queries
113
+ * implement all git operations
114
+ * ALL operations should return raw results which can be used by the convenience objects
115
+ * implement Convenience objects (git objects call commands with arguments set, ...)
116
+ * add Documentation and Examples
117
+ * Long-Term: reimplement all ops in ruby, starting with plumbing
118
+
119
+ Note on Patches/Pull Requests
120
+ -----------------------------
121
+
122
+ * Fork the project.
123
+ * Make your feature addition or bug fix.
124
+ * Add tests for it. This is important so I don't break it in a
125
+ future version unintentionally.
126
+ * Commit, do not mess with rakefile, version, or history.
127
+ (if you want to have your own version, that is fine but
128
+ bump version in a commit by itself I can ignore when I pull)
129
+ * Send me a pull request. Bonus points for topic branches.
130
+
131
+ Required
132
+ --------
133
+
134
+ * git 1.6+
135
+ * fastthread
136
+
137
+ Thanks
138
+ ------
139
+
140
+ Linus, matz and mojombo.
141
+
142
+ Copyright
143
+ ---------
144
+
145
+ Copyright (c) 2009 Florian Aßmann, Fork Unstable Medie, Oniversus Media.
146
+ See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ # coding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "v"
10
+ gem.summary = %Q{'florian' says: v is talking git.}
11
+ gem.description = %Q{v is for versioned. It's is currently only a threaded wrapper for the git commands or procedures. In the future it should provide a generic interface for diverse VCSs.}
12
+ gem.email = "florian.assmann@email.de"
13
+ gem.requirements << "fastthread"
14
+ gem.homepage = "http://github.com/boof/v"
15
+ gem.authors = ["Florian Aßmann"]
16
+ gem.add_development_dependency "riot", ">= 0"
17
+ gem.add_development_dependency "yard", ">= 0"
18
+ gem.add_dependency 'fastthread', '>= 1.0.7'
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/*_test.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ begin
33
+ require 'rcov/rcovtask'
34
+ Rcov::RcovTask.new do |test|
35
+ test.libs << 'test'
36
+ test.pattern = 'test/**/*_test.rb'
37
+ test.verbose = true
38
+ end
39
+ rescue LoadError
40
+ task :rcov do
41
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
42
+ end
43
+ end
44
+
45
+ task :test => :check_dependencies
46
+
47
+ task :default => :test
48
+
49
+ begin
50
+ require 'yard'
51
+ YARD::Rake::YardocTask.new
52
+ rescue LoadError
53
+ task :yardoc do
54
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
55
+ end
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
data/auto_commit.rb ADDED
@@ -0,0 +1,131 @@
1
+ require 'rubygems'
2
+ require 'lib/v.rb'
3
+ require 'benchmark'
4
+ Thread.abort_on_exception = true
5
+
6
+ Benchmark.bm do |results|
7
+ results.report "Auto-Commit\n" do
8
+ # TODO: check bare repository
9
+ # V.git 'test.git' do ...
10
+
11
+ V.git do
12
+ # write version
13
+ File.open('VERSION', 'w') { |f| f << "#{ V::VERSION * '.' }" }
14
+
15
+ # add all files and reset those that should not appear in tree
16
+ add 'lib'
17
+ index.add 'VERSION', 'LICENSE', 'auto_commit.rb'
18
+ index << '.' # << is like: add '.'
19
+ index.reset 'commit_message', 'test.git', '*.gem*'
20
+
21
+ not index.include? 'v.gemspec' or
22
+ raise 'expected index not to include gem specific files'
23
+
24
+ not index.include? 'commit_message' or
25
+ raise 'expected index not to include commit_message'
26
+
27
+ # check for new version
28
+ new_version = (index - head).modified? 'VERSION'
29
+
30
+ # build subject
31
+ subject = "'#{ ENV['USER'] }' says: "
32
+ subject += ARGV.first || File.read('commit_message')
33
+
34
+ # tip of current branch for later use (this is a future)
35
+ parent = head.commit
36
+
37
+ parent == parent or raise 'expected == to work'
38
+
39
+ # raises IndexError if path does not exist
40
+ head.tree / 'lib/v/adapters/git.rb'
41
+
42
+ # initialize a test branch
43
+ test_branch = branches['test']
44
+ test_branch.destroy
45
+
46
+ test_branch.create
47
+ test_branch.exists? or
48
+ raise 'expected branch to exist after being created'
49
+
50
+ first_two_commits = commits.first 2
51
+ first_two_commits.last.parents.member? first_two_commits.first.name or
52
+ raise 'expected first to be correctly ordered'
53
+
54
+ last_two_commits = commits.last 2
55
+ last_two_commits.last.parents.member? last_two_commits.first.name or
56
+ raise 'expected last to be correctly ordered'
57
+
58
+ # commit changes, returns commit future but schedules after head.commit
59
+ head_commit = commit subject
60
+
61
+ commits.include? parent or
62
+ raise 'expected commits to include parent'
63
+ commits.last == head_commit or
64
+ raise 'expected last commit to be head_commit'
65
+
66
+ commits.all? { |commit| commit.is_a? V::Adapters::Git::Object } or
67
+ raise ' expected all commits to be kind of Git::Object'
68
+
69
+ # raises an exception if commits.last.to_s is not a String.
70
+ String(commits.last)
71
+
72
+ head_commit.parents[parent.name] or begin
73
+ p parent, head_commit, head_commit.parents
74
+ raise 'expected parents to include previous'
75
+ end
76
+
77
+ head_commit == head.commit or
78
+ raise 'expected head to represent current state'
79
+
80
+ head_commit.tree.content.keys.
81
+ all? { |basename| basename != 'commit_message' } or
82
+ raise 'expected content not to include commit_message'
83
+
84
+ test_branch.update head.commit
85
+ test_branch.head == head or
86
+ raise 'expected branch start at head after update'
87
+
88
+ head_commit.subject == subject.split("\n").first or begin
89
+ p subject.split("\n").first, head_commit, head_commit.subject
90
+ raise 'expected subject to be correctly quoted'
91
+ end
92
+
93
+ head_commit.committer.role == :committer or
94
+ raise 'expected role to be :committer'
95
+
96
+ test_branch.destroy
97
+ not test_branch.exists? and
98
+ raise 'expected branch not to exist after being destroyed'
99
+
100
+ if new_version
101
+ tag "v#{ V::VERSION * '.' }"
102
+ push :tags => true
103
+ # remotes[:origin].push :all
104
+ # build gem and push it to gemcutter
105
+ else
106
+ # remotes[:origin].branches["#{ head.branch }"].commits
107
+ # remotes[:origin].branches[ head.branch.name ].commits
108
+ # remotes[:origin].commits
109
+ # origin.commits
110
+
111
+ # push if commits.size - origin.commits.size > 6
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ __END__
118
+ if __FILE__ == $0
119
+ begin
120
+ test_path = "#{ __DIR__ }/../test.git"
121
+ V.git :work_tree => test_path do
122
+ bare == true or raise TypeError, 'test.git should be bare'
123
+ init and add('config').value
124
+ end
125
+ rescue V::ENOTWTREE
126
+ # and here we bam'ed :D
127
+ ensure
128
+ FileUtils.rm_r test_path if File.directory? test_path
129
+ raise if $!
130
+ end
131
+ end; end
@@ -0,0 +1,115 @@
1
+ module V
2
+ module Adapters
3
+ module Git
4
+
5
+ # The head behaves like a commit.
6
+ class Head
7
+ instance_methods.each { |m| m =~ /^__/ or undef_method m }
8
+ attr_reader :branch, :path
9
+
10
+ def initialize(env, branch)
11
+ @environment, @branch = env, branch
12
+ @path = File.join env.git_dir, %W[ refs heads #{ branch } ]
13
+ end
14
+
15
+ # Returns the tip of the branch.
16
+ def commit
17
+ @environment.schedule do
18
+ raise V::EUNREV unless File.readable? @path
19
+ Commit.with @environment, :name => File.read(@path).chomp
20
+ end
21
+ end
22
+
23
+ # Delegates to commit.
24
+ def method_missing(meth, *args, &block)
25
+ commit.send meth, *args, &block
26
+ end
27
+
28
+ end
29
+
30
+ class Branch
31
+ attr_reader :name
32
+ alias_method :to_s, :name
33
+
34
+ def initialize(environment, name)
35
+ @environment, @name = environment, name
36
+ end
37
+
38
+ def create(*args)
39
+ @environment.branch @name, *args
40
+ return self
41
+ end
42
+
43
+ # Returns commits for this branch.
44
+ def commits(path = '.')
45
+ @commits ||= Commits.new @environment, self, path
46
+ end
47
+ # Returns head for this branch.
48
+ def head
49
+ @head ||= Head.new @environment, self
50
+ end
51
+
52
+ # Returns true if this branch has a startpoint, false otherwise.
53
+ def exists?
54
+ head.commit
55
+ rescue V::EUNREV
56
+ return false
57
+ end
58
+
59
+ # Returns the tip of this branch.
60
+ def tip
61
+ head.commit
62
+ end
63
+
64
+ def update(*args)
65
+ @environment.branch @name, *args.dup << { :force => true }
66
+ return self
67
+ end
68
+ def destroy(opts = {})
69
+ arguments = {}
70
+ arguments[ opts[:force] ? :D : :d ] = true
71
+ arguments[:r] = true if opts[:remote]
72
+
73
+ @environment.branch @name, arguments
74
+
75
+ return self
76
+ end
77
+
78
+ end
79
+
80
+ class Branches
81
+ include Enumerable
82
+ def initialize(environment)
83
+ @environment = environment
84
+ root = File.join environment.git_dir, %w[ refs heads ]
85
+ @glob, @offset = File.join(root, %w[ ** * ]), root.length + 1
86
+ end
87
+
88
+ # Returns current branch.
89
+ def current
90
+ @environment.schedule do
91
+ head = File.read File.join(@environment.git_dir, 'HEAD')
92
+ name = head.split(':', 2).last.split('/', 3).last.strip
93
+
94
+ Branch.new @environment, name
95
+ end
96
+ end
97
+
98
+
99
+ # Returns the branch with the given <tt>name</tt>.
100
+ def [](name)
101
+ Branch.new @environment, name
102
+ end
103
+
104
+ # Yields instance of Branch for each branch found in refs/heads.
105
+ def each
106
+ @environment.schedule do
107
+ Dir[ @glob ].each do |path|
108
+ yield Branch.new(@environment, path[ @offset.. -1 ])
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,55 @@
1
+ module V
2
+ module Adapters
3
+ module Git
4
+ class Commits
5
+ include Enumerable
6
+
7
+ def initialize(environment, branch, path)
8
+ @environment, @branch, @path = environment, branch, path
9
+ end
10
+
11
+ def first(*n)
12
+ to_commit names_reversed.last(*n)
13
+ end
14
+ def last(*n)
15
+ to_commit names_reversed.first(*n)
16
+ end
17
+
18
+ # TODO: work with chunks (see --max-count and --skip).
19
+ def each
20
+ commits = to_commit names_reversed
21
+ commits.each { |commit| yield commit } if block_given?
22
+
23
+ commits
24
+ end
25
+
26
+ # Returns true if name of commit is included in names of commits.
27
+ def include?(commit)
28
+ names_reversed.include? commit.name
29
+ end
30
+
31
+ # Returns the number of commits.
32
+ def size
33
+ names_reversed.size
34
+ end
35
+ alias_method :length, :size
36
+
37
+ protected
38
+
39
+ # Returns object names in reverse order.
40
+ def names_reversed
41
+ @environment.log(@path, :pretty => '%H').split "\n"
42
+ end
43
+
44
+ def to_commit(result)
45
+ Array === result or
46
+ return Commit.with(@environment, :name => result)
47
+
48
+ result.reverse!
49
+ result.map! { |name| Commit.with @environment, :name => name }
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,99 @@
1
+ module V
2
+ module Adapters
3
+ module Git
4
+ class Environment
5
+ include Operations
6
+
7
+ attr_reader :to_s, :bare, :work_tree, :git_dir, :branches, :index
8
+
9
+ def self.which_git=(path) @@which_git = path end
10
+ self.which_git = `which git`
11
+
12
+ def initialize(attrs = {})
13
+ assign attrs
14
+
15
+ assign_directories
16
+ assign_git
17
+ assign_string
18
+ assign_worker
19
+ end
20
+
21
+ def new?
22
+ schedule {
23
+ path = File.join @git_dir, 'refs', 'heads'
24
+ entries = Dir.entries(path) - %w[ . .. ]
25
+
26
+ entries.size == 0
27
+ }
28
+ end
29
+
30
+ # Tries to schedule an operation.
31
+ def method_missing(op_sym, *args, &callback)
32
+ schedule Operations.new(op_sym, *args, &callback)
33
+ end
34
+
35
+ # Schedules operation or proc for execution.
36
+ def schedule(op = nil, &block)
37
+ @worker.enq block || op, self
38
+ end
39
+
40
+ def inspect
41
+ @git_dir
42
+ end
43
+
44
+ ### Convenience
45
+
46
+ def remotes
47
+ @remotes
48
+ end
49
+ def origin
50
+ @remotes['origin']
51
+ end
52
+ # Returns collection of commits for current branch.
53
+ def commits(path = '.')
54
+ @branches.current.commits path
55
+ end
56
+ # Returns head for current branch. This is a moving target.
57
+ def head
58
+ @branches.current.head
59
+ end
60
+
61
+ protected
62
+
63
+ def assign(attrs)
64
+ attrs.each { |k, v| instance_variable_set :"@#{ k }", v }
65
+ end
66
+ def assign_directories
67
+ @work_tree ||= ENV['GIT_WORK_TREE'] || Dir.getwd
68
+ @work_tree = File.expand_path @work_tree
69
+
70
+ @bare = @work_tree[-4..-1] == '.git' unless defined? @bare
71
+
72
+ @git_dir ||= ENV['GIT_DIR']
73
+ @git_dir ||= @bare ? @work_tree : File.join(@work_tree, '.git')
74
+ @git_dir = File.expand_path @git_dir
75
+ end
76
+ def assign_git
77
+ @which_git ||= @@which_git
78
+ @which_git.strip!
79
+
80
+ raise V::ECMDNOFO, 'git' if @which_git.empty?
81
+
82
+ @branches = Branches.new self
83
+ @index = Index.new self
84
+ end
85
+ def assign_string
86
+ args = ["--no-pager"]
87
+ args.push @bare ? "--bare" : "--work-tree='#{ @work_tree }'"
88
+ args << "--git-dir='#{ @git_dir }'"
89
+
90
+ @to_s = "#{ @which_git } #{ args * ' ' }"
91
+ end
92
+ def assign_worker
93
+ @worker = Worker.new(@git_dir)
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end