summaryrefslogtreecommitdiffstats
path: root/lib/git/diff.rb
diff options
context:
space:
mode:
authorscott Chacon <schacon@agadorsparticus.(none)>2007-11-10 12:43:33 -0800
committerscott Chacon <schacon@agadorsparticus.(none)>2007-11-10 12:43:33 -0800
commitfde3263abc5c7866aa7dce7aef28eacaa33d7664 (patch)
treec9911ac92e9770c7bfea3e79269f8e7dcf7f6982 /lib/git/diff.rb
parent9d59d2965184964ab6662282ef5f9ceac2c58552 (diff)
downloadthird_party-ruby-git-fde3263abc5c7866aa7dce7aef28eacaa33d7664.tar.gz
third_party-ruby-git-fde3263abc5c7866aa7dce7aef28eacaa33d7664.tar.xz
third_party-ruby-git-fde3263abc5c7866aa7dce7aef28eacaa33d7664.zip
few hours work - diff is done
Diffstat (limited to 'lib/git/diff.rb')
-rw-r--r--lib/git/diff.rb124
1 files changed, 115 insertions, 9 deletions
diff --git a/lib/git/diff.rb b/lib/git/diff.rb
index 3686edb..b43ecd9 100644
--- a/lib/git/diff.rb
+++ b/lib/git/diff.rb
@@ -7,31 +7,137 @@ module Git
@base = nil
@from = nil
@to = nil
+ @path = nil
@full_diff = nil
+ @full_diff_files = nil
+ @stats = nil
def initialize(base, from = nil, to = nil)
- dirty_log
@base = base
- @from = from
- @to = to
+ @from = from.to_s
+ @to = to.to_s
end
- def
+ def path(path)
+ @path = path
+ return self
+ end
+
+ def size
+ cache_stats
+ @stats[:total][:files]
+ end
+
+ def lines
+ cache_stats
+ @stats[:total][:lines]
+ end
+
+ def deletions
+ cache_stats
+ @stats[:total][:deletions]
+ end
+
+ def insertions
+ cache_stats
+ @stats[:total][:insertions]
+ end
+
+ def stats
+ cache_stats
+ @stats
+ end
+
+ # if file is provided and is writable, it will write the patch into the file
+ def patch(file = nil)
+ cache_full
+ @full_diff
+ end
+ alias_method :to_s, :patch
+
# enumerable methods
+ def [](key)
+ process_full
+ @full_diff_files.assoc(key)[1]
+ end
+
def each
- cache_diff
- @full_diff.each do |file|
- yield file
+ process_full
+ @full_diff_files.each do |file|
+ yield file[1]
+ end
+ end
+
+ class DiffFile
+ attr_accessor :patch, :path, :mode, :src, :dst, :type
+ @base = nil
+
+ def initialize(base, hash)
+ @base = base
+ @patch = hash[:patch]
+ @path = hash[:path]
+ @mode = hash[:mode]
+ @src = hash[:src]
+ @dst = hash[:dst]
+ @type = hash[:type]
+ end
+
+ def blob(type = :dst)
+ if type == :src
+ @base.object(@src) if @src != '0000000'
+ else
+ @base.object(@dst) if @dst != '0000000'
+ end
end
end
private
- def cache_diff
+ def cache_full
if !@full_diff
- @full_diff = @base.lib.diff_files(@from, @to)
+ @full_diff = @base.lib.diff_full(@from, @to, {:path_limiter => @path})
+ end
+ end
+
+ def process_full
+ if !@full_diff_files
+ cache_full
+ @full_diff_files = process_full_diff
+ end
+ end
+
+ def cache_stats
+ if !@stats
+ @stats = @base.lib.diff_stats(@from, @to, {:path_limiter => @path})
+ end
+ end
+
+ # break up @diff_full
+ def process_full_diff
+ final = {}
+ current_file = nil
+ @full_diff.split("\n").each do |line|
+ if m = /diff --git a\/(.*?) b\/(.*?)/.match(line)
+ current_file = m[1]
+ final[current_file] = {:patch => line, :path => current_file,
+ :mode => '', :src => '', :dst => '', :type => 'modified'}
+ else
+ if m = /index (.......)\.\.(.......)( ......)*/.match(line)
+ final[current_file][:src] = m[1]
+ final[current_file][:dst] = m[2]
+ final[current_file][:mode] = m[3].strip if m[3]
+ end
+ if m = /(.*?) file mode (......)/.match(line)
+ final[current_file][:type] = m[1]
+ final[current_file][:mode] = m[2]
+ end
+ final[current_file][:patch] << "\n" + line
+ end
end
+ final.map { |e| [e[0], DiffFile.new(@base, e[1])] }
end
+
+ end
end \ No newline at end of file