1 class Commit < ActiveRecord::Base
4 def self.find_commit_range(current_user, repository, minimum, maximum, exclude)
5 # disallow starting with '-' so verision strings can't be interpreted as command line options
6 valid_pattern = /[A-Za-z0-9_][A-Za-z0-9_-]/
7 if (minimum and !minimum.match valid_pattern) or !maximum.match valid_pattern
8 logger.warn "find_commit_range called with string containing invalid characters: '#{minimum}', '#{maximum}'"
12 if minimum and minimum.empty?
20 # Get list of actual repository directories under management
21 on_disk_repos = repositories
23 # Get list of repository objects readable by user
24 readable = Repository.readable_by(current_user)
26 # filter repository objects on requested repository name
28 readable = readable.where(name: repository)
31 #puts "min #{minimum}"
32 #puts "max #{maximum}"
33 #puts "rep #{repository}"
37 if on_disk_repos[r.name]
38 ENV['GIT_DIR'] = on_disk_repos[r.name][:git_dir]
40 #puts "dir #{on_disk_repos[r.name][:git_dir]}"
42 # We've filtered for invalid characters, so we can pass the contents of
43 # minimum and maximum safely on the command line
45 #puts "git rev-list --max-count=1 #{maximum}"
47 # Get the commit hash for the upper bound
49 IO.foreach("|git rev-list --max-count=1 #{maximum}") do |line|
53 # If not found or string is invalid, nothing else to do
54 next if !max_hash or !max_hash.match valid_pattern
56 resolved_exclude = nil
60 if e.match valid_pattern
61 IO.foreach("|git rev-list --max-count=1 #{e}") do |line|
62 resolved_exclude.push(line.strip)
69 # Get the commit hash for the lower bound
71 IO.foreach("|git rev-list --max-count=1 #{minimum}") do |line|
75 # If not found or string is invalid, nothing else to do
76 next if !min_hash or !min_hash.match valid_pattern
78 # Now find all commits between them
79 #puts "git rev-list #{min_hash}..#{max_hash}"
80 IO.foreach("|git rev-list #{min_hash}..#{max_hash}") do |line|
82 commits.push(hash) if !resolved_exclude or !resolved_exclude.include? hash
85 commits.push(min_hash) if !resolved_exclude or !resolved_exclude.include? min_hash
87 commits.push(max_hash) if !resolved_exclude or !resolved_exclude.include? max_hash
92 if !commits or commits.empty?
99 # Import all commits from configured git directory into the commits
103 repositories.each do |repo_name, repo|
104 stat = { true => 0, false => 0 }
105 ENV['GIT_DIR'] = repo[:git_dir]
106 IO.foreach("|git rev-list --format=oneline --all") do |line|
107 sha1, message = line.strip.split " ", 2
109 Commit.find_or_create_by_repository_name_and_sha1_and_message(repo_name, sha1, message[0..254]) do
112 stat[!!imported] += 1
113 if (stat[true] + stat[false]) % 100 == 0
114 if $stdout.tty? or ARGV[0] == '-v'
115 puts "#{$0} #{$$}: repo #{repo_name} add #{stat[true]} skip #{stat[false]}"
119 if $stdout.tty? or ARGV[0] == '-v'
120 puts "#{$0} #{$$}: repo #{repo_name} add #{stat[true]} skip #{stat[false]}"
125 def self.refresh_repositories
131 def self.repositories
132 return @repositories if @repositories
135 @gitdirbase = Rails.configuration.git_repositories_dir
136 Dir.foreach @gitdirbase do |repo|
137 next if repo.match /^\./
138 git_dir = File.join(@gitdirbase,
139 repo.match(/\.git$/) ? repo : File.join(repo, '.git'))
140 repo_name = repo.sub(/\.git$/, '')
141 @repositories[repo_name] = {git_dir: git_dir}