redmine_git_branches2.diff

Git branches support in the browse and diff views - Alban Browaeys, 2009-02-19 12:23

Download (10.4 KB)

View differences:

redmine_argos_gitbranches/lib/redmine/scm/adapters/git_adapter.rb 2009-02-19 12:13:59.000000000 +0100
26 26
        GIT_BIN = "git"
27 27

  
28 28
        # Get the revision of a particuliar file
29
        def get_rev (rev,path)
30
        
31
          if rev != 'latest' && !rev.nil?
32
            cmd="#{GIT_BIN} --git-dir #{target('')} show --date=iso --pretty=fuller #{shell_quote rev} -- #{shell_quote path}" 
33
          else
34
            @branch ||= shellout("#{GIT_BIN} --git-dir #{target('')} branch") { |io| io.grep(/\*/)[0].strip.match(/\* (.*)/)[1] }
35
            cmd="#{GIT_BIN} --git-dir #{target('')} log --date=iso --pretty=fuller -1 #{@branch} -- #{shell_quote path}" 
36
          end
37
          rev=[]
38
          i=0
39
          shellout(cmd) do |io|
40
            files=[]
41
            changeset = {}
42
            parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
29
        def get_rev (rev,treepath)
30
	    if treepath =~ /^refs\/([^\/]+)\/([^\/]+)\/(.*)$/
31
	      type = $1
32
	      tree = $2
33
	      path = $3
34
	      type_tree = "#{type}/#{tree}"
35
	    else
36
	      path ||= ''
37
	      type_tree ||= '' 
38
	      #return nil
39
	    end
40
	    if rev != 'latest' && !rev.nil?
41
	      #cmd="#{GIT_BIN} --git-dir #{target('')} show --raw --date=iso --pretty=fuller  #{shell_quote rev} #{shell_quote type_tree} -- #{shell_quote path}" 
42
	      cmd="#{GIT_BIN} --git-dir #{target('')} show --raw --date=iso --pretty=fuller -1 #{shell_quote rev} -- #{shell_quote path}" 
43
	    else
44
	      #@branch ||= shellout("#{GIT_BIN} --git-dir #{target('')} branch") { |io| io.grep(/\*/)[0].strip.match(/\* (.*)/)[1] }
45
	      cmd="#{GIT_BIN} --git-dir #{target('')} log --raw --date=iso --pretty=fuller -1 #{type_tree} -- #{shell_quote path}" 
46
	    end
47
	    rev=[]
48
	    i=0
49
	    shellout(cmd) do |io|
50
	      files=[]
51
	      changeset = {}
52
	      parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
53

  
54
	      io.each_line do |line|
55
		if line =~ /^commit ([0-9a-f]{40})$/
56
		  key = "commit"
57
		  value = $1
58
		  if (parsing_descr == 1 || parsing_descr == 2)
59
		    parsing_descr = 0
60
		    rev = Revision.new({:identifier => changeset[:commit],
61
					:scmid => changeset[:commit],
62
					:author => changeset[:author],
63
					:time => Time.parse(changeset[:date]),
64
					:message => changeset[:description],
65
					:paths => files
66
				       })
67
		    changeset = {}
68
		    files = []
69
		  end
70
		  changeset[:commit] = $1
71
		elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
72
		  key = $1
73
		  value = $2
74
		  if key == "Author"
75
		    changeset[:author] = value
76
		  elsif key == "CommitDate"
77
		    changeset[:date] = value
78
		  end
79
		elsif (parsing_descr == 0) && line.chomp.to_s == ""
80
		  parsing_descr = 1
81
		  changeset[:description] = ""
82
		elsif (parsing_descr == 1 || parsing_descr == 2) && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\s+(.+)$/
83
		  parsing_descr = 2
84
		  fileaction = $1
85
		  filepath = $2
86
		  files << {:action => fileaction, :path => filepath}
87
		elsif (parsing_descr == 1) && line.chomp.to_s == ""
88
		  parsing_descr = 2
89
		elsif (parsing_descr == 1)
90
		  changeset[:description] << line
91
		end
92
	      end	
93
	      rev = Revision.new({:identifier => changeset[:commit],
94
				  :scmid => changeset[:commit],
95
				  :author => changeset[:author],
96
				  :time => (changeset[:date] ? Time.parse(changeset[:date]) : nil),
97
				  :message => changeset[:description],
98
				  :paths => files
99
				 })
43 100

  
44
            io.each_line do |line|
45
              if line =~ /^commit ([0-9a-f]{40})$/
46
                key = "commit"
47
                value = $1
48
                if (parsing_descr == 1 || parsing_descr == 2)
49
                  parsing_descr = 0
50
                  rev = Revision.new({:identifier => changeset[:commit],
51
                                      :scmid => changeset[:commit],
52
                                      :author => changeset[:author],
53
                                      :time => Time.parse(changeset[:date]),
54
                                      :message => changeset[:description],
55
                                      :paths => files
56
                                     })
57
                  changeset = {}
58
                  files = []
59
                end
60
                changeset[:commit] = $1
61
              elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
62
                key = $1
63
                value = $2
64
                if key == "Author"
65
                  changeset[:author] = value
66
                elsif key == "CommitDate"
67
                  changeset[:date] = value
68
                end
69
              elsif (parsing_descr == 0) && line.chomp.to_s == ""
70
                parsing_descr = 1
71
                changeset[:description] = ""
72
              elsif (parsing_descr == 1 || parsing_descr == 2) && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\s+(.+)$/
73
                parsing_descr = 2
74
                fileaction = $1
75
                filepath = $2
76
                files << {:action => fileaction, :path => filepath}
77
              elsif (parsing_descr == 1) && line.chomp.to_s == ""
78
                parsing_descr = 2
79
              elsif (parsing_descr == 1)
80
                changeset[:description] << line
81
              end
82
            end	
83
            rev = Revision.new({:identifier => changeset[:commit],
84
                                :scmid => changeset[:commit],
85
                                :author => changeset[:author],
86
                                :time => (changeset[:date] ? Time.parse(changeset[:date]) : nil),
87
                                :message => changeset[:description],
88
                                :paths => files
89
                               })
90

  
91
          end
101
	    end
92 102

  
93
          get_rev('latest',path) if rev == []
103
	    get_rev('latest',treepath) if rev == []
94 104

  
95
          return nil if $? && $?.exitstatus != 0
96
          return rev
105
	    return nil if $? && $?.exitstatus != 0
106
	    return rev
97 107
        end
98 108

  
99 109
        def info
......
107 117
          return nil
108 118
        end
109 119
        
110
        def entries(path=nil, identifier=nil)
111
          path ||= ''
112
          entries = Entries.new
113
          cmd = "#{GIT_BIN} --git-dir #{target('')} ls-tree -l "
114
          cmd << shell_quote("HEAD:" + path) if identifier.nil?
115
          cmd << shell_quote(identifier + ":" + path) if identifier
116
          shellout(cmd)  do |io|
117
            io.each_line do |line|
118
              e = line.chomp.to_s
119
              if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\s+(.+)$/
120
                type = $1
121
                sha = $2
122
                size = $3
123
                name = $4
124
                entries << Entry.new({:name => name,
125
                                       :path => (path.empty? ? name : "#{path}/#{name}"),
126
                                       :kind => ((type == "tree") ? 'dir' : 'file'),
127
                                       :size => ((type == "tree") ? nil : size),
128
                                       :lastrev => get_rev(identifier,(path.empty? ? name : "#{path}/#{name}")) 
129
                                                                  
130
                                     }) unless entries.detect{|entry| entry.name == name}
131
              end
132
            end
133
          end
134
          return nil if $? && $?.exitstatus != 0
135
          entries.sort_by_name
120
        def entries(treepath=nil, identifier=nil)
121
	  treepath ||= ''
122
	    if treepath =~ /^refs\/([^\/]+)\/([^\/]+)\/(.*)$/
123
	      type = $1
124
	      tree = $2
125
	      path = $3
126
	    else
127
	      type = "heads"
128
	      tree = "master"
129
	      path = '' 
130
	    end
131
	    path ||= ''
132
	    entries = Entries.new
133
	    if !treepath.empty?
134
	      type_tree = "#{type}/#{tree}"
135
	      cmd = "#{GIT_BIN} --git-dir #{target('')} ls-tree -l "
136
	      cmd << shell_quote(type_tree + ":" + path + (path.empty? ? "" : "/")) if identifier.nil?
137
	      cmd << shell_quote(identifier + ":" + path + (path.empty? ? "" : "/")) if identifier
138
	      shellout(cmd)  do |io|
139
		io.each_line do |line|
140
		  e = line.chomp.to_s
141
		  if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\s+(.+)$/
142
		    type = $1
143
		    sha = $2
144
		    size = $3
145
		    name = $4
146
		    entries << Entry.new({:name => name,
147
					   :path => (treepath.empty? ? name : "#{treepath}/#{name}"),
148
					   :kind => ((type == "tree") ? 'dir' : 'file'),
149
					   :size => ((type == "tree") ? nil : size),
150
					   #:lastrev => get_rev(identifier,(path.empty? ? name : "#{path}/#{name}")) 
151
					   :lastrev => get_rev(identifier,(treepath.empty? ? name : "#{treepath}/#{name}")) 
152
								      
153
					 }) unless entries.detect{|entry| entry.name == name}
154
		  end
155
		end
156
	      end
157
	    else
158
	      cmd = "#{GIT_BIN} --git-dir #{target('')} for-each-ref --format='%(objectname) %(objecttype) %(refname)' refs"
159
	      shellout(cmd)  do |io|
160
		io.each_line do |line|
161
		  e = line.chomp.to_s
162
		  if e =~ /^([0-9a-f]{40})\s+\w+\s+(.+)$/
163
		    sha = $1
164
		    refname = $2
165
		    entries << Entry.new({:name => refname,
166
					   :path => refname,
167
					   #:path => (path.empty? ? refname : "#{path}/#{refname}"),
168
					   :kind => 'dir',
169
					   :size => nil,
170
					   :lastrev => get_rev(sha,(path.empty? ? refname : "#{path}/#{refname}")) 
171
								      
172
					 }) unless entries.detect{|entry| entry.name == refname}
173
		  end
174
		end
175
	      end
176
	    end
177
	    return nil if $? && $?.exitstatus != 0
178
	    entries.sort_by_name
136 179
        end
137 180
        
138
        def revisions(path, identifier_from, identifier_to, options={})
181
        def revisions(treepath, identifier_from, identifier_to, options={})
139 182
          revisions = Revisions.new
183
	  treepath ||= ''
184
	    if treepath =~ /^refs\/([^\/]+)\/([^\/]+)(.*)$/
185
	      type = $1
186
	      tree = $2
187
	      path = $3
188
	    else
189
	      type = "heads"
190
	      tree = "master"
191
	      path = '' 
192
	    end
140 193
          cmd = "#{GIT_BIN} --git-dir #{target('')} log --raw --date=iso --pretty=fuller"
141 194
          cmd << " --reverse" if options[:reverse]
142 195
          cmd << " -n #{options[:limit].to_i} " if (!options.nil?) && options[:limit]
143 196
          cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from
144 197
          cmd << " #{shell_quote identifier_to} " if identifier_to
198
	  cmd << " heads/master-v1"
145 199
          shellout(cmd) do |io|
146 200
            files=[]
147 201
            changeset = {}