Created
August 31, 2022 02:22
-
-
Save mkasberg/18e1c3fcf5081ee747cc3d4cd41bf233 to your computer and use it in GitHub Desktop.
Commit Message Ratio - a made up ratio defined as the ratio of the number of words in the message body to the lines of code changed
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 | |
# Define the "commit message ratio" as (commit_body_words / commit_lines_changed). | |
# | |
# With no args, this script will find the commit message ratio of all commits in | |
# the git repo in the pwd, and will sort them by that ratio. | |
# (Commits with a high commit message ratio tend to be interesting commits!) | |
# | |
# With a commit hash as the only arg, provide the commit message ratio of that commit. | |
# | |
# Runs using git in the PWD. | |
def all_ratios | |
# Adapted from | |
# https://gist.github.com/samvrlewis/a4545386adb99556e7ff629d377e1769 | |
msg_wc_out = `git rev-list --no-merges "${1:-HEAD}" | while read rev; do echo "$(git show -s --format='%b' $rev | wc -w) words: $rev"; done` | |
msg_wc_hash = msg_wc_out.lines.map { |line| | |
parts = line.split(":").map(&:strip) | |
words = parts.first.match(/(\d+) words/)[1].to_i | |
[parts.last, words] | |
}.to_h | |
# Adapted from | |
# https://stackoverflow.com/questions/21137477/how-to-get-git-log-with-short-stat-in-one-line | |
loc_out = `git log --oneline --pretty="@%H" --stat | grep -v \\| | tr "\\n" " " | tr "@" "\\n"` | |
loc_hash = loc_out.lines.map { |line| | |
line.match(/(?'commit'[0-9a-z]+) \d+ files? changed(?:, (?'ins'\d+) insertions?\(\+\))?(?:, (?'del'\d+) deletions?\(\-\))?/) | |
}.select { |m| !m.nil? }.map { |matches| | |
insertions = matches.named_captures['ins'].to_i || 0 | |
deletions = matches.named_captures['del'].to_i || 0 | |
[matches['commit'], insertions + deletions] | |
}.select { |_, lines| lines > 0 }.to_h | |
subject_out = `git log --pretty="%H::::%s"` | |
subjects = subject_out.lines.map { |line| | |
parts = line.split("::::").map(&:strip) | |
[parts.first, parts.last] | |
}.to_h | |
ratios = loc_hash.map { |commit, lines_changed| | |
msg_wc = msg_wc_hash[commit] | |
{commit: commit, ratio: (msg_wc.to_f / lines_changed).round(2), subject: subjects[commit]} | |
} | |
pp ratios.sort_by { |data| - data[:ratio] } | |
end | |
def single_ratio(commit) | |
msg_wc = `git show -s --format='%b' #{commit} | wc -w`.to_i | |
loc_out = `git log --oneline --pretty="@%H" --stat #{commit} ^#{commit}^ | grep -v \\| | tr "\\n" " " | tr "@" "\\n"`.strip | |
matches = loc_out.match(/(?'commit'[0-9a-z]+) \d+ files? changed(?:, (?'ins'\d+) insertions?\(\+\))?(?:, (?'del'\d+) deletions?\(\-\))?/) | |
insertions = matches.named_captures['ins'].to_i || 0 | |
deletions = matches.named_captures['del'].to_i || 0 | |
loc = insertions + deletions | |
puts " Word Count: #{msg_wc}" | |
puts " LOC: #{loc}" | |
puts "Commit Message Ratio: #{msg_wc.to_f / loc}" | |
end | |
if ARGV.size == 0 | |
all_ratios | |
else | |
single_ratio(ARGV.first) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment