Created
June 6, 2012 07:51
-
-
Save rstacruz/2880525 to your computer and use it in GitHub Desktop.
Revisions
-
rstacruz revised this gist
Jun 10, 2012 . 1 changed file with 152 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,152 @@ #!/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 -
rstacruz created this gist
Jun 6, 2012 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,150 @@ #!/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