mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-20 04:35:32 +00:00
189 lines
7.7 KiB
Ruby
Executable File
189 lines
7.7 KiB
Ruby
Executable File
#!/usr/bin/env ruby -w
|
|
require 'set'
|
|
|
|
$display_branches = ARGV
|
|
|
|
if $display_branches.empty?
|
|
puts "You need to specify a branch name or ALL for all branches. Make sure to have at least git >=1.8 and be warned that processing one branch takes several minutes!"
|
|
exit
|
|
end
|
|
|
|
$branches = {}
|
|
$big_files = {}
|
|
$dependable_blob_shas = Set.new
|
|
$packed_blobs = {}
|
|
|
|
class PackedBlob
|
|
attr_accessor :sha, :type, :size, :packed_size, :offset, :depth, :base_sha, :is_shared, :branch
|
|
def initialize(sha, type, size, packed_size, offset, depth, base_sha)
|
|
@sha = sha
|
|
@type = type
|
|
@size = size
|
|
@packed_size = packed_size
|
|
@offset = offset
|
|
@depth = depth
|
|
@base_sha = base_sha
|
|
@is_shared = false
|
|
@branch = nil
|
|
end
|
|
end
|
|
|
|
class Branch
|
|
attr_accessor :name, :blobs, :non_shared_size, :non_shared_packed_size, :shared_size, :shared_packed_size, :non_shared_dependable_size, :non_shared_dependable_packed_size
|
|
def initialize(name)
|
|
@name = name
|
|
@blobs = Set.new
|
|
@non_shared_size = 0
|
|
@non_shared_packed_size = 0
|
|
@shared_size = 0
|
|
@shared_packed_size = 0
|
|
@non_shared_dependable_size = 0
|
|
@non_shared_dependable_packed_size = 0
|
|
end
|
|
end
|
|
|
|
if not File.exists?('packed_blobs.bin')
|
|
|
|
# Collect every packed blobs information
|
|
for pack_idx in Dir[".git/objects/pack/pack-*.idx"]
|
|
puts pack_idx
|
|
pack_counter = 0
|
|
IO.popen("git verify-pack -v #{pack_idx}", 'r') do |pack_list|
|
|
pack_list.each_line do |pack_line|
|
|
pack_counter += 1
|
|
pack_line.chomp!
|
|
if not pack_line.include? "delta"
|
|
$stdout.write "\r #{pack_counter} packs"; $stdout.flush;
|
|
sha, type, size, packed_size, offset, depth, base_sha = pack_line.split(/\s+/, 7)
|
|
size = size.to_i
|
|
packed_size = packed_size.to_i
|
|
$packed_blobs[sha] = PackedBlob.new(sha, type, size, packed_size, offset, depth, base_sha)
|
|
$dependable_blob_shas.add(base_sha) if base_sha != nil
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
puts " "
|
|
end
|
|
|
|
puts "Writing packed blobs..."
|
|
File.open('packed_blobs.bin','wb') do |f|
|
|
f.write Marshal.dump($packed_blobs)
|
|
end
|
|
|
|
puts "Writing dependable blob SHAs..."
|
|
File.open('dependable_blob_shas.bin','wb') do |f|
|
|
f.write Marshal.dump($dependable_blob_shas)
|
|
end
|
|
|
|
else
|
|
puts "Reading packed blobs from file! This means that information won't be up 2 date but process is faster!"
|
|
$packed_blobs = Marshal.load(File.open('packed_blobs.bin', 'rb'))
|
|
$dependable_blob_shas = Marshal.load(File.open('dependable_blob_shas.bin', 'rb'))
|
|
puts "Read #{$packed_blobs.size()} packed blobs and #{$dependable_blob_shas.size()} SHAs..."
|
|
end
|
|
|
|
def compute_branch(branch_name)
|
|
if $display_branches.include?(branch_name) or $display_branches.include?("ALL")
|
|
puts "* #{branch_name}"
|
|
if not File.exists?("#{branch_name}.bin")
|
|
puts "\tFile #{branch_name}.bin does not exist - reading data from repository"
|
|
branch = Branch.new(branch_name)
|
|
$branches[branch_name] = branch
|
|
commit_counter = 0; obj_counter = 0
|
|
IO.popen("git rev-list #{branch_name}", 'r') do |rev_list|
|
|
all_commit_lines = rev_list.readlines
|
|
all_commit_lines.each do |commit|
|
|
commit_all_count = all_commit_lines.count
|
|
old_obj_counter = obj_counter
|
|
commit_counter += 1
|
|
obj_counter = 0;
|
|
size_count = 0
|
|
# Look into each commit in order to collect all the blobs used
|
|
blobs_all = `git ls-tree -zrl #{commit}`.split("\0")
|
|
for object in blobs_all
|
|
obj_counter += 1
|
|
bits, type, sha, size, path = object.split(/\s+/, 5)
|
|
if type == 'blob'
|
|
blob = $packed_blobs[sha]
|
|
if blob != nil
|
|
size_count += blob.size
|
|
branch.blobs.add(blob)
|
|
if not blob.is_shared
|
|
if blob.branch != nil and blob.branch != branch
|
|
# this blob has been used in another branch, let's set it to "shared"
|
|
blob.is_shared = true
|
|
blob.branch = nil
|
|
else
|
|
blob.branch = branch
|
|
end
|
|
end
|
|
end
|
|
else
|
|
print "F"
|
|
end
|
|
end
|
|
if old_obj_counter < obj_counter
|
|
obj_changes = "%04d" % (obj_counter - old_obj_counter)
|
|
change_mode = "++"
|
|
else
|
|
obj_changes = "%04d" % (old_obj_counter - obj_counter)
|
|
change_mode = "--"
|
|
end
|
|
size_count = "%10d" % (size_count / 1000)
|
|
$stdout.write "\r\tProcessed commit #{commit_counter} of #{commit_all_count} (Objects:\t#{obj_counter}\t#{obj_changes}\t#{change_mode}\t#{size_count} kb)"; $stdout.flush;
|
|
end
|
|
end
|
|
print "\n\tWriting branch data to file..."
|
|
File.open("#{branch_name}.bin",'wb') do |f|
|
|
f.write Marshal.dump(branch)
|
|
end
|
|
puts "OK"
|
|
else
|
|
print "\n\tLoading branch data from file #{branch_name}. Remove this file to get new data..."
|
|
$branches[branch_name] = Marshal.load(File.open("#{branch_name}.bin", 'rb'))
|
|
branch = $branches[branch_name]
|
|
puts "OK"
|
|
end
|
|
branch.blobs.each do |blob|
|
|
if blob.is_shared
|
|
branch.shared_size += blob.size
|
|
branch.shared_packed_size += blob.packed_size
|
|
else
|
|
if $dependable_blob_shas.include?(blob.sha)
|
|
branch.non_shared_dependable_size += blob.size
|
|
branch.non_shared_dependable_packed_size += blob.packed_size
|
|
else
|
|
branch.non_shared_size += blob.size
|
|
branch.non_shared_packed_size += blob.packed_size
|
|
end
|
|
end
|
|
end
|
|
puts "\tbranch: %s" % branch_name
|
|
puts "\tblobs: %s" % branch.blobs.count
|
|
puts "\tnon shared:"
|
|
puts "\t\tpacked: %s kb" % (branch.non_shared_packed_size / 1000)
|
|
puts "\t\tnon packed: %s kb" % (branch.non_shared_size / 1000)
|
|
puts "\t\tall: %s kb" % ((branch.non_shared_packed_size + branch.non_shared_size) / 1000)
|
|
puts "\tnon shared but with dependencies on it:"
|
|
puts "\t\tpacked: %s kb" % (branch.non_shared_dependable_packed_size / 1000)
|
|
puts "\t\tnon packed: %s kb" % (branch.non_shared_dependable_size / 1000)
|
|
puts "\tshared:"
|
|
puts "\t\tpacked: %s kb" % (branch.shared_packed_size / 1000)
|
|
puts "\t\tnon packed: %s kb" % (branch.shared_size / 1000), ""
|
|
end
|
|
end
|
|
|
|
# Now check all blobs for every branches in order to determine whether it's shared between branches or not
|
|
threads = []
|
|
IO.popen("git branch --list", 'r') do |branch_list|
|
|
branches_all = branch_list.readlines
|
|
puts "Loaded #{branches_all.count} branches..."
|
|
branches_all.each do |branch_line|
|
|
# For each branch
|
|
branch_name = branch_line[2..-1].chomp
|
|
compute_branch(branch_name)
|
|
end
|
|
end
|