Class: Git::Trac::Patch

Inherits:
Object
  • Object
show all
Defined in:
lib/git/trac/patch.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repository, body) ⇒ Patch

Returns a new instance of Patch.



8
9
10
# File 'lib/git/trac/patch.rb', line 8

def initialize(repository, body)
  @repository, @body = repository, body
end

Instance Attribute Details

#repositoryObject (readonly)

Returns the value of attribute repository.



6
7
8
# File 'lib/git/trac/patch.rb', line 6

def repository
  @repository
end

Instance Method Details

#apply(options = {}) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/git/trac/patch.rb', line 44

def apply(options = {})
  command = %W(git apply -p#{git? ? 1 : 0} --whitespace=nowarn)
  command << "--cached" if options[:cached]
  repository.popen3(*command) do |inn,out,err|
    inn.puts with_root(options[:root])
    inn.close
    if err.read.empty?
      if options[:root]
        return options[:root].sub(%r{((?:^\.\.|/\.\.)+)/([^.].*)},'\\2/\\1')
      else
        return "."
      end
    end
  end
  if options[:depth].to_i > 0 && !git?
    repository.in_work_tree do
      last_roots = [options[:root]]
      opts = options.dup
      1.upto(opts.delete(:depth).to_i) do |d|
        parent = File.join(*(%w(..)*d+[opts[:root]]).compact)
        result = apply(opts.merge(:root => parent)) and return result
        roots = []
        last_roots.each do |root|
          Dir.entries(root || ".").each do |dir|
            path = File.join(*[root,dir].compact)
            next if dir =~ /\A\./ || !File.directory?(path)
            roots << path
            result = apply(opts.merge(:root => path)) and return result
          end
        end
        last_roots = roots
      end
    end
  end
  if body.include?("\r")
    Patch.new(@repository, body.delete("\r")).apply(options)
  else
    false
  end
end

#bodyObject Also known as: to_s



12
13
14
# File 'lib/git/trac/patch.rb', line 12

def body
  @body.respond_to?(:call) ? @body.call : @body
end

#git?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/git/trac/patch.rb', line 18

def git?
  body[0,1024] =~ /^diff --git / || body[0,6] == "--- a/"
end

#with_root(root = nil) ⇒ Object

Rewrite filenames in a patch to be relative to root. For each .. at the end of root, a path is stripped off the original filename. The rewritten patch is returned as a string.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/git/trac/patch.rb', line 25

def with_root(root = nil)
  if root && !root.empty? && !git?
    patch = ""
    body.each_line do |line|
      line.sub!(/^([+-]{3} |Index: )(?!\/dev\/null)(.*)$/) do
        head = $1
        original = File.join(root, $2)
        while original.sub!(%r{(.*/|^)\.\./[^/]*/},'\\1')
        end
        head + original
      end
      patch << line
    end
    patch
  else
    body
  end
end