Skip to content

Instantly share code, notes, and snippets.

@mschuerig
Last active January 31, 2022 10:13
Show Gist options
  • Save mschuerig/250f2a45561cd53e5475121ee3931b46 to your computer and use it in GitHub Desktop.
Save mschuerig/250f2a45561cd53e5475121ee3931b46 to your computer and use it in GitHub Desktop.
What did I do?
#! /usr/bin/ruby -w
require 'date'
require 'find'
# TODO
# - make work with -p option
def main
logopts = "--color=always --since=#{Date.today - 3} #{ARGV.join(' ')}"
puts merged_commits('.', logopts: logopts).join("\n")
end
def usage
puts 'git amnesia --author=me@example.com --since=yyyy-mm-dd'
end
def repositories(path)
Enumerator.new do |yielder|
Find.find(path) do |f|
if File.basename(f) == '.git'
yielder.yield File.dirname(f)
Find.prune
end
end
end
end
def commits(repo, options = {})
Dir.chdir(repo) do
`git log -z --stat #{options[:logopts]}`.split("\0").tap do
st = $?.exitstatus
raise "git error: #{st}" unless st == 0
end
end
end
def commits_by_date(repo, options = {})
Hash.new { |h, d| h[d] = [] }.tap do |by_date|
commits(repo, options).each do |commit|
date = DateTime.parse(commit[/^Date:\s*(.+)$/, 1])
by_date[date] << commit
end
end
end
def insert_prefix(enum, prefix)
enum.map { |e| prefix + e }
end
def merged_commits(path, options = {})
merged = Hash.new { |h, d| h[d] = [] }
repositories(path).each do |repo|
banner = "\e[01;34mRepository: #{repo}\e[0m\n"
commits_by_date(repo, options).each do |date, commits|
merged[date] += insert_prefix(commits, banner)
end
end
merged.sort_by(&:first).map(&:last).reverse
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment