Created
June 6, 2012 07:51
-
-
Save rstacruz/2880525 to your computer and use it in GitHub Desktop.
Git changelog helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Usage: | |
# git clog # prints | |
# git clog -w # writes | |
# | |
# https://gist.github.com/2880525 | |
# | |
# Put me in a bin path with the filename `git-clog`, thank you. | |
module Clog | |
extend self | |
# Returns the latest tag (assumed to be the current version). | |
def version | |
v = `git tag | tail -n 1`.strip | |
v.empty? ? nil : v | |
end | |
# Returns the history file of the repo. | |
def history_file | |
Dir['*HISTORY*'].first || Dir['*CHANGE*'].first | |
end | |
# Returns a list of git tags. | |
def tags | |
`git tag`.strip.split("\n") | |
end | |
# Returns the first parent commit SHA1. | |
def tail | |
`git rev-list HEAD | tail -n 1`.strip | |
end | |
# List of possible ranges | |
def all_ranges | |
arr = Array.new | |
['HEAD', tags.reverse, tail].flatten.each_cons(2) { |to, from| arr << [to, from] } | |
arr | |
end | |
# Returns a list of changesets for the given tags. | |
# @return Array of hashes. | |
def changesets(range=:all) | |
case range | |
when :latest | |
[ { name: 'HEAD', changes: categories(changes(version, 'HEAD')) } ] | |
when :all | |
all_ranges.map do |(to, from)| | |
{ name: to, changes: categories(changes(from, to)) } | |
end | |
end | |
end | |
# Returns an array of commit messages. | |
def changes(from=version, to=nil) | |
log = `git log --pretty="format:%s" #{from||tail}..#{to}` | |
log.strip.split("\n").sort | |
end | |
# From a list of commit messages -> categories | |
def categories(list=changes) | |
cats = Hash.new { |h, k| h[k] = Array.new } | |
list.each { |line| | |
case line | |
when /^Merge branch/i then nil | |
when /^Add(?:ed)? (.*)$/i then cats['Added'] << $1 | |
when /^Fix(?:ed)? (.*)$/i then cats['Fixed'] << $1 | |
when /^Change(?:d)? (.*)$/i then cats['Changed'] << $1 | |
when /^(?:Remove|Delete)(?:d)? (.*)$/i then cats['Removed'] << $1 | |
when /^\+ (.*)$/i then cats['Added'] << $1 | |
when /^\! (.*)$/ then cats['Fixed'] << $1 | |
when /^\- (.*)$/i then cats['Removed'] << $1 | |
when /^\~ (.*)$/i then cats['Changed'] << $1 | |
when /^\. (.*)$/i then cats['Misc'] << $1 | |
else cats['Changed'] << line | |
end | |
} | |
cats | |
end | |
def log(sets) | |
sets.map do |set| | |
# Heading name | |
h = set[:name] | |
h = "Latest version - #{Time.now.strftime('%b %d, %Y')}" if h == 'HEAD' | |
h + "\n" + '-'*h.size + "\n\n" + | |
set[:changes].map { |category, list| | |
"### #{category}:\n" + | |
list.map { |item| " * #{item}" }.join("\n") | |
}.join("\n\n") | |
end.join("\n\n") | |
end | |
def log_old | |
h = "Since #{version || 'the beginning'} - #{Time.now.strftime('%b %d, %Y')}" | |
"#{h}\n#{'-'*h.size}\n\n" + | |
categories.map { |category, list| | |
"### #{category}:\n" + | |
list.map { |item| " * #{item}" }.join("\n") | |
}.join("\n\n") | |
end | |
end | |
options = { | |
:all => (ARGV.delete('-a') || ARGV.delete('--all')) | |
} | |
if ARGV == ['--help'] || ARGV == ['-h'] | |
puts "Usage: git clog [-a] [-w]" | |
puts | |
puts " -a, --all: See the changelog since time immemorial" | |
puts " -w, --write: Write to a history file" | |
exit | |
end | |
unless File.directory?('.git') | |
puts "Try this command inside a repo's root path." | |
exit | |
end | |
sets = if options[:all] | |
Clog.changesets(:all) | |
else | |
Clog.changesets(:latest) | |
end | |
if ARGV == [] | |
puts Clog.log(sets) | |
$stderr << "\nUse 'git clog -w' to write.\n" | |
elsif ARGV == ['-w'] || ARGV == ['--write'] | |
# Create the history file | |
system 'touch HISTORY.md' if Clog.history_file.nil? | |
# Concat | |
history = File.open(Clog.history_file) { |f| f.read } | |
output = Clog.log(sets) | |
output += "\n\n#{'-'*80}\n\n" + history unless history.empty? | |
# Write | |
File.open(Clog.history_file, 'w') { |f| f.write output } | |
if ENV['EDITOR'] | |
exec "#{ENV['EDITOR']} #{Clog.history_file}" | |
else | |
puts "Done writing to #{Clog.history_file}." | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Usage: | |
# git clog # prints | |
# git clog -w # writes | |
# | |
# https://gist.github.com/2880525 | |
module Clog | |
extend self | |
# Returns the latest tag (assumed to be the current version). | |
def version | |
v = `git tag | tail -n 1`.strip | |
v.empty? ? nil : v | |
end | |
# Returns the history file of the repo. | |
def history_file | |
Dir['*HISTORY*'].first || Dir['*CHANGE*'].first | |
end | |
# Returns a list of git tags. | |
def tags | |
`git tag`.strip.split("\n") | |
end | |
# Returns the first parent commit SHA1. | |
def tail | |
`git rev-list HEAD | tail -n 1`.strip | |
end | |
# List of possible ranges | |
def all_ranges | |
arr = Array.new | |
['HEAD', tags.reverse, tail].flatten.each_cons(2) { |to, from| arr << [to, from] } | |
arr | |
end | |
# Returns a list of changesets for the given tags. | |
# @return Array of hashes. | |
def changesets(range=:all) | |
case range | |
when :latest | |
[ { name: 'HEAD', changes: categories(changes(version, 'HEAD')) } ] | |
when :all | |
all_ranges.map do |(to, from)| | |
{ name: to, changes: categories(changes(from, to)) } | |
end | |
end | |
end | |
# Returns an array of commit messages. | |
def changes(from=version, to=nil) | |
log = `git log --pretty="format:%s" #{from||tail}..#{to}` | |
log.strip.split("\n").sort | |
end | |
# From a list of commit messages -> categories | |
def categories(list=changes) | |
cats = Hash.new { |h, k| h[k] = Array.new } | |
list.each { |line| | |
case line | |
when /^Merge branch/i then nil | |
when /^Add(?:ed)? (.*)$/i then cats['Added'] << $1 | |
when /^Fix(?:ed)? (.*)$/i then cats['Fixed'] << $1 | |
when /^Change(?:d)? (.*)$/i then cats['Changed'] << $1 | |
when /^(?:Remove|Delete)(?:d)? (.*)$/i then cats['Removed'] << $1 | |
when /^\+ (.*)$/i then cats['Added'] << $1 | |
when /^\! (.*)$/ then cats['Fixed'] << $1 | |
when /^\- (.*)$/i then cats['Removed'] << $1 | |
when /^\~ (.*)$/i then cats['Changed'] << $1 | |
when /^\. (.*)$/i then cats['Misc'] << $1 | |
else cats['Changed'] << line | |
end | |
} | |
cats | |
end | |
def log(sets) | |
sets.map do |set| | |
# Heading name | |
h = set[:name] | |
h = "Latest version - #{Time.now.strftime('%b %d, %Y')}" if h == 'HEAD' | |
h + "\n" + '-'*h.size + "\n\n" + | |
set[:changes].map { |category, list| | |
"### #{category}:\n" + | |
list.map { |item| " * #{item}" }.join("\n") | |
}.join("\n\n") | |
end.join("\n\n") | |
end | |
def log_old | |
h = "Since #{version || 'the beginning'} - #{Time.now.strftime('%b %d, %Y')}" | |
"#{h}\n#{'-'*h.size}\n\n" + | |
categories.map { |category, list| | |
"### #{category}:\n" + | |
list.map { |item| " * #{item}" }.join("\n") | |
}.join("\n\n") | |
end | |
end | |
options = { | |
:all => (ARGV.delete('-a') || ARGV.delete('--all')) | |
} | |
if ARGV == ['--help'] || ARGV == ['-h'] | |
puts "Usage: git clog [-a] [-w]" | |
puts | |
puts " -a, --all: See the changelog since time immemorial" | |
puts " -w, --write: Write to a history file" | |
exit | |
end | |
unless File.directory?('.git') | |
puts "Try this command inside a repo's root path." | |
exit | |
end | |
sets = if options[:all] | |
Clog.changesets(:all) | |
else | |
Clog.changesets(:latest) | |
end | |
if ARGV == [] | |
puts Clog.log(sets) | |
$stderr << "\nUse 'git clog -w' to write.\n" | |
elsif ARGV == ['-w'] || ARGV == ['--write'] | |
# Create the history file | |
system 'touch HISTORY.md' if Clog.history_file.nil? | |
# Concat | |
history = File.open(Clog.history_file) { |f| f.read } | |
output = Clog.log(sets) | |
output += "\n\n#{'-'*80}\n\n" + history unless history.empty? | |
# Write | |
File.open(Clog.history_file, 'w') { |f| f.write output } | |
if ENV['EDITOR'] | |
exec "#{ENV['EDITOR']} #{Clog.history_file}" | |
else | |
puts "Done writing to #{Clog.history_file}." | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment