public
Description: The Git TextMate Bundle
Homepage: http://tim.theenchanter.com/
Clone URL: git://github.com/timcharper/git-tmbundle.git
git-tmbundle / Support / lib / commands / submodule.rb
100644 84 lines (71 sloc) 2.129 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
84
require 'md5'
require 'fileutils'
 
class SCM::Git::Submodule < SCM::Git::CommandProxyBase
  def init_and_update
    output = @base.command("submodule", "init")
    output << @base.command("submodule", "update")
    output
  end
  
  def all
    list.map do |sm|
      SubmoduleProxy.new(@base, self, sm)
    end
  end
  
  def add(repository, path)
    path = @base.make_local_path(path)
    @base.popen_command("submodule", "add", "--", repository, path)
  end
  
  protected
    def list
      @base.command("submodule").split("\n").map do |line|
        next unless line.match(/^([ \-\+])*([a-f0-9]+) ([^ ]+)( \((.+)\)){0,1}/)
        {
          :state => {" " => 0, "-" => -1, "+" => 1}[$1],
          :revision => $2,
          :path => $3,
          :tag => ($5 == "undefined" ? nil : $5)
        }
      end.compact
    end
    
  class SubmoduleProxy
    attr_reader :revision, :path, :tag, :state
  
    def initialize(base, parent, options = {})
      @base, @parent, @tag = base, parent, tag
      options.each do |key, value|
        instance_variable_set("@#{key}", value)
      end
    end
    
    def url
      @url ||= @base.command("config", "--file", File.join(@base.git_base, ".gitmodules"), "submodule.#{path}.url").strip
    end
    
    def name
      path
    end
    
    def abs_cache_path
      @abs_cache_path ||= File.join(@base.git_base, ".git/submodule_cache", MD5.hexdigest(path + "\n" + url))
    end
    
    def abs_path
      @abs_path ||= File.join(@base.git_base, @path)
    end
    
    def cache
      if File.exist?(abs_path)
        FileUtils.rm_rf(abs_cache_path)
        FileUtils.mkdir_p(File.dirname(abs_cache_path))
        FileUtils.mv(abs_path, abs_cache_path, :force => true)
        true
      end
    end
    
    def restore
      if File.exist?(abs_cache_path) && ! Dir.has_a_file?(abs_path)
        FileUtils.rm_rf(abs_path)
        FileUtils.mkdir_p(File.dirname(abs_path))
        FileUtils.mv(abs_cache_path, abs_path, :force => true)
      end
    end
  end
end
 
class Dir
  def self.has_a_file?(abs_path)
    Dir[abs_path + "/**/*"].any? {|f| File.file?(f) }
  end
end