summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/git.rb1
-rw-r--r--lib/git/base.rb12
-rw-r--r--lib/git/lib.rb97
-rw-r--r--lib/git/status.rb103
4 files changed, 189 insertions, 24 deletions
diff --git a/lib/git.rb b/lib/git.rb
index bb68388..cfcbc8c 100644
--- a/lib/git.rb
+++ b/lib/git.rb
@@ -20,6 +20,7 @@ require 'git/branch'
require 'git/remote'
require 'git/diff'
+require 'git/status'
=begin
require 'git/author'
require 'git/file'
diff --git a/lib/git/base.rb b/lib/git/base.rb
index 00495c7..eded12d 100644
--- a/lib/git/base.rb
+++ b/lib/git/base.rb
@@ -92,6 +92,7 @@ module Git
def config(name = nil, value = nil)
if(name && value)
# set value
+ lib.config_set(name, value)
elsif (name)
# return value
lib.config_get(name)
@@ -114,7 +115,11 @@ module Git
def log(count = 30)
Git::Log.new(self, count)
end
-
+
+ def status
+ Git::Status.new(self)
+ end
+
def branches
Git::Branches.new(self)
end
@@ -131,6 +136,11 @@ module Git
Git::Diff.new(self, objectish, obj2)
end
+ # adds files from the working directory to the git repository
+ def add(path = '.')
+ self.lib.add(path)
+ end
+
# convenience methods
def revparse(objectish)
diff --git a/lib/git/lib.rb b/lib/git/lib.rb
index 9fa3986..ec65e55 100644
--- a/lib/git/lib.rb
+++ b/lib/git/lib.rb
@@ -52,6 +52,10 @@ module Git
opts[:bare] ? {:repository => clone_dir} : {:working_directory => clone_dir}
end
+
+ ## READ COMMANDS ##
+
+
def log_commits(opts = {})
arr_opts = ['--pretty=oneline']
arr_opts << "-#{opts[:count]}" if opts[:count]
@@ -89,28 +93,6 @@ module Git
arr
end
- def config_get(name)
- command('config', ['--get', name])
- end
-
- def config_list
- hsh = {}
- command_lines('config', ['--list']).each do |line|
- (key, value) = line.split('=')
- hsh[key] = value
- end
- hsh
- end
-
- def config_remote(name)
- hsh = {}
- command_lines('config', ['--get-regexp', "remote.#{name}"]).each do |line|
- (key, value) = line.split
- hsh[key.gsub("remote.#{name}.", '')] = value
- end
- hsh
- end
-
# returns hash
# [tree-ish] = [[line_no, match], [line_no, match2]]
# [tree-ish] = [[line_no, match], [line_no, match2]]
@@ -161,10 +143,78 @@ module Git
hsh
end
+
+ # compares the index and the working directory
+ def diff_files
+ hsh = {}
+ command_lines('diff-files').each do |line|
+ (info, file) = line.split("\t")
+ (mode_src, mode_dest, sha_src, sha_dest, type) = info.split
+ hsh[file] = {:path => file, :mode_file => mode_src, :mode_index => mode_dest,
+ :sha_file => sha_src, :sha_index => sha_dest, :type => type}
+ end
+ hsh
+ end
+
+ # compares the index and the repository
+ def diff_index(treeish)
+ hsh = {}
+ command_lines('diff-index', treeish).each do |line|
+ (info, file) = line.split("\t")
+ (mode_src, mode_dest, sha_src, sha_dest, type) = info.split
+ hsh[file] = {:path => file, :mode_repo => mode_src, :mode_index => mode_dest,
+ :sha_repo => sha_src, :sha_index => sha_dest, :type => type}
+ end
+ hsh
+ end
+
+ def ls_files
+ hsh = {}
+ command_lines('ls-files', '--stage').each do |line|
+ (info, file) = line.split("\t")
+ (mode, sha, stage) = info.split
+ hsh[file] = {:path => file, :mode_index => mode, :sha_index => sha, :stage => stage}
+ end
+ hsh
+ end
+
+
+ def config_remote(name)
+ hsh = {}
+ command_lines('config', ['--get-regexp', "remote.#{name}"]).each do |line|
+ (key, value) = line.split
+ hsh[key.gsub("remote.#{name}.", '')] = value
+ end
+ hsh
+ end
+
+ def config_get(name)
+ command('config', ['--get', name])
+ end
+
+ def config_list
+ hsh = {}
+ command_lines('config', ['--list']).each do |line|
+ (key, value) = line.split('=')
+ hsh[key] = value
+ end
+ hsh
+ end
+
+ ## WRITE COMMANDS ##
+
+ def config_set(name, value)
+ command('config', [name, "'#{value}'"])
+ end
+
+ def add(path = '.')
+ command('add', path)
+ end
+
private
- def command_lines(cmd, opts)
+ def command_lines(cmd, opts = {})
command(cmd, opts).split("\n")
end
@@ -177,6 +227,7 @@ module Git
#puts "git #{cmd} #{opts}"
out = `git #{cmd} #{opts} 2>&1`.chomp
#puts out
+ #puts
if $?.exitstatus > 1
raise Git::GitExecuteError.new(out)
end
diff --git a/lib/git/status.rb b/lib/git/status.rb
new file mode 100644
index 0000000..24fd98d
--- /dev/null
+++ b/lib/git/status.rb
@@ -0,0 +1,103 @@
+module Git
+
+ class Status
+ include Enumerable
+
+ @base = nil
+ @files = nil
+
+ def initialize(base)
+ @base = base
+ construct_status
+ end
+
+ def changed
+ @files.select { |k, f| f.type == 'M' }
+ end
+
+ def added
+ @files.select { |k, f| f.type == 'A' }
+ end
+
+ def untracked
+ @files.select { |k, f| f.untracked }
+ end
+
+ def pretty
+ out = ''
+ self.each do |file|
+ out << file.path
+ out << "\n\tsha(r) " + file.sha_repo.to_s
+ out << "\n\tsha(i) " + file.sha_index.to_s
+ out << "\n\ttype " + file.type.to_s
+ out << "\n\tstage " + file.stage.to_s
+ out << "\n\tuntrac " + file.untracked.to_s
+ out << "\n"
+ end
+ out << "\n"
+ out
+ end
+
+ # enumerable method
+
+ def [](file)
+ @files[file]
+ end
+
+ def each
+ @files.each do |k, file|
+ yield file
+ end
+ end
+
+ class StatusFile
+ attr_accessor :path, :type, :stage, :untracked
+ attr_accessor :mode_index, :mode_repo
+ attr_accessor :sha_index, :sha_repo
+
+ def initialize(hash)
+ @path = hash[:path]
+ @type = hash[:type]
+ @stage = hash[:stage]
+ @mode_index = hash[:mode_index]
+ @mode_repo = hash[:mode_repo]
+ @sha_index = hash[:sha_index]
+ @sha_repo = hash[:sha_repo]
+ @untracked = hash[:untracked]
+ end
+
+
+ end
+
+ private
+
+ def construct_status
+ @files = @base.lib.ls_files
+
+ # find untracked in working dir
+ Dir.chdir(@base.dir.path) do
+ Dir.glob('**/*') do |file|
+ if !@files[file]
+ @files[file] = {:path => file, :untracked => true} if !File.directory?(file)
+ end
+ end
+ end
+
+ # find modified in tree
+ @base.lib.diff_files.each do |path, data|
+ @files[path].merge!(data)
+ end
+
+ # find added but not committed - new files
+ @base.lib.diff_index('HEAD').each do |path, data|
+ @files[path].merge!(data)
+ end
+
+ @files.each do |k, file_hash|
+ @files[k] = StatusFile.new(file_hash)
+ end
+ end
+
+ end
+
+end \ No newline at end of file