summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscott Chacon <schacon@agadorsparticus.(none)>2007-11-11 10:04:26 -0800
committerscott Chacon <schacon@agadorsparticus.(none)>2007-11-11 10:04:26 -0800
commita1237671ba3ec38f5b123ee6600e4352dc03196b (patch)
tree71bc13cb36799e778237097b343a4d4fa9189b3f
parentefcce7fc123b9e64fb9d93224e4e78d09144af3d (diff)
downloadthird_party-ruby-git-a1237671ba3ec38f5b123ee6600e4352dc03196b.zip
third_party-ruby-git-a1237671ba3ec38f5b123ee6600e4352dc03196b.tar.gz
third_party-ruby-git-a1237671ba3ec38f5b123ee6600e4352dc03196b.tar.xz
git add working, git status object working
-rw-r--r--EXAMPLES6
-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
-rw-r--r--tests/units/test_config.rb7
-rw-r--r--tests/units/test_index.rb48
-rw-r--r--tests/units/test_init.rb1
8 files changed, 247 insertions, 28 deletions
diff --git a/EXAMPLES b/EXAMPLES
index 864db8d..b454a32 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -81,12 +81,12 @@ g = Git.init
g = Git.clone(URI, :name => 'name', :path => '/tmp/checkout'
(git_dir, index_file)
+g.config('user.name', 'Scott Chacon')
+g.config('user.email', 'email@email.com')
+
***** IMPLEMENTED *****
-
-g.config('user.name', 'Scott Chacon')
-g.config('user.email', 'email@email.com')
g.add('.')
g.add([file1, file2])
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
diff --git a/tests/units/test_config.rb b/tests/units/test_config.rb
index 5adb391..66dc9ff 100644
--- a/tests/units/test_config.rb
+++ b/tests/units/test_config.rb
@@ -20,7 +20,12 @@ class TestBranch < Test::Unit::TestCase
end
def test_set_config
- # !! TODO !!
+ in_temp_dir do |path|
+ g = Git.clone(@wbare, 'bare')
+ assert_equal('scott Chacon', g.config('user.name'))
+ g.config('user.name', 'bully')
+ assert_equal('bully', g.config('user.name'))
+ end
end
end \ No newline at end of file
diff --git a/tests/units/test_index.rb b/tests/units/test_index.rb
new file mode 100644
index 0000000..cf20eaf
--- /dev/null
+++ b/tests/units/test_index.rb
@@ -0,0 +1,48 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class TestIndex< Test::Unit::TestCase
+
+ def setup
+ set_file_paths
+ @git = Git.open(@wdir)
+ end
+
+ def test_add
+ in_temp_dir do |path|
+ #puts path
+ g = Git.clone(@wbare, 'new')
+ Dir.chdir('new') do
+ assert_equal('100644', g.status['example.txt'].mode_index)
+ new_file('test-file', 'blahblahblah')
+ assert(g.status.untracked.assoc('test-file'))
+ g.add
+ assert(g.status.added.assoc('test-file'))
+ assert(!g.status.untracked.assoc('test-file'))
+ assert(!g.status.changed.assoc('example.txt'))
+ append_file('example.txt', 'hahahaha')
+ assert(g.status.changed.assoc('example.txt'))
+ g.add
+ assert(g.status.changed.assoc('example.txt'))
+ g.commit('my message')
+ assert(!g.status.changed.assoc('example.txt'))
+ assert(!g.status.added.assoc('test-file'))
+ assert(!g.status.untracked.assoc('test-file'))
+ end
+ end
+ end
+
+ def new_file(name, contents)
+ File.open(name, 'w') do |f|
+ f.puts contents
+ end
+ end
+
+ def append_file(name, contents)
+ File.open(name, 'a') do |f|
+ f.puts contents
+ end
+ end
+
+end \ No newline at end of file
diff --git a/tests/units/test_init.rb b/tests/units/test_init.rb
index 4681ba0..c192dc0 100644
--- a/tests/units/test_init.rb
+++ b/tests/units/test_init.rb
@@ -53,6 +53,7 @@ class TestInit < Test::Unit::TestCase
in_temp_dir do |path|
g = Git.clone(@wbare, 'bare-co')
assert(File.exists?(File.join(g.repo.path, 'config')))
+ assert(g.dir)
end
end