I was thinking of making my git logs more readable for a long time. Sometimes merge log can help to seperate a set of commits as a feature, but how can we get more info from the sequential log messages inside a set of commits?
After doing a little research, I’ve found rangzen’s answer on Stack Exchange sounds reasonable.
With Add, Mod(ify), Ref(actoring), Fix, Rem(ove) and Rea(dability) then it’s easy to extract logfile.
Example :
+ Add: New function to rule the world.
+ Mod: Add women factor in Domination.ruleTheWorld().
+ Ref: Extract empathy stuff to an abstract class.
+ Fix: RUL-42 or #42 Starvation need to be initialised before Energy to avoid the nullpointer in People.
+ Rem: freeSpeech is not used anymore.
+ Rea: Removed old TODO and extra space in header.
And I want to give it a try by,
Setting git config commit.template to my customized commit template.
Using git commit-msg hook to enforce the pattern, validating on commit message.
Here is the details.
Customize Commit Template
Write a .gitmessage template.
12345678910111213141516171819
# = Rule 1, use meta operation
# Add: new function to rule the world
# Mod: query_date logic
# Rem: user.rake is not used anymore
# Ren: hello-world to hell-world
# Fix: #1900, stupid typo
# Ref: extract to an abstract class.
# Opt: cache in get_active_table
# = Rule 2, leave a "*" at the end to flag folding
# Mod: query_date logic*
#
# Use chronic to guess date.
#
# Chronic.parse('may 27th', :guess => false)
# #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
$ git touch README && git commit
# = Rule 1, use meta operation# Add: new function to rule the world# Mod: query_date logic# Rem: user.rake is not used anymore# Ren: hello-world to hell-world# Fix: #1900, stupid typo# Ref: extract to an abstract class.# Opt: cache in get_active_table# = Rule 2, leave a "*" at the end to flag folding# Mod: query_date logic*## Use chronic to guess date.## Chronic.parse('may 27th', :guess => false)# #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# On branch master# Changes to be committed:# new file: README#
Validate on Rules
Write a Ruby script, naming commit-msg under .git/hooks, and make it executable.
12345678910111213141516
#!/usr/bin/env ruby# Init repoexit0if`git log --oneline -1 2>/dev/null`.empty?message_file=ARGV[0]lines=File.readlines(message_file).reject{|l|l=~/^#/}.map(&:strip).reject(&:empty?)subject_regex='[Add|Mod|Rem|Ren|Fix|Ref|Opt]:\s\S+'regex=lines.count>1?/#{subject_regex}\*$/:/#{subject_regex}/unlesslines[0]=~regexputs"[POLICY] Your message is not formatted correctly"puts"[POLICY] Please check ~/.gitmessage.txt"exit1end