v 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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