Skip to content

Instantly share code, notes, and snippets.

@ScreamingDev
Last active August 29, 2015 13:57
Show Gist options
  • Save ScreamingDev/9629666 to your computer and use it in GitHub Desktop.
Save ScreamingDev/9629666 to your computer and use it in GitHub Desktop.
Semantic commits described with ABNF

Semantic commits

Writing commits is a fast and simple process which we do all day. Imagine them becoming powerful for us which finally give them some attention. The following semantic commits will do so and have the aim to:

  • Generate a changelog with commits for end-user
  • Generate a speaking summary for customer
  • Generate a easy to read list of changes for developer
  • In general: Make commits parseable by some script

This is solved by the easy trick to use a well known structure (esp. PHP):

  • Class names and Methods can be detected by using their semantic.
  • Functions have a leading "()" which is obvious to detect.
  • More fuzzy commits without one particular target can get a "tag".

Please leave a comment below if you are missing something in this prequel or in the ABNF.

Example

I just thought this would be nice as a commit message (almost full example):

\Foo_Class::barMethod() can now print a baz (#123)

In order to work as a human, I need to move in any SITUATION.
But this meant a big load of work for humanity, which is a PROBLEM.
As a human, I want to have a SOLUTION so that I can be lazy again.

- funcPrint42() has been deleted
- \Meh\Output has been extended for that purpose
- \Foo_Class::barMethod() will pass "baz" to the output
  if it is in a good mood
- /url/path has no need for human interaction till that
- humanity: is no longer disturbed by work
  because we all like to be lazy
- Except writing these lines one time

The header describes in general where the change is, what and give some reference. After that follows an optional short text about the situation before (which can be a user story), the problems with that and what the solution now is (also possible user story) - feel free to add the pros and cons. In the end follows a list of changes that can be extended by describing if-clauses or the matter (because) why the change needed to happen. You might note that functions, classes, methods and URLs can be referenced as well as tags (followed by colon) and non-referencing simple sentences. It is very flexible because an user story can be the classic ones from Connextra, the simpler ones by Mike Cohn, the "Feature Injection Stories" by Chris Matts or a user story that would answer the proven "Five Ws".

Benefit

Imagine a parser running through your code, mapping the references to according sections in an documentation and generating whole diff or manuals for developers. It can fetch the "long descriptions" / "paper questions part" to give your customer a brief text of what has been done to his website or application. For the most out there the heading is enough to gather text for a changelog.

Mapping

You can output the "tags" directly or filter them like this:

[
  '\Class_Foo'               => 'Usability',
  '\Class_Foo::someMethod()' => 'Hints for customer',
  'humanity'                 => 'Human interaction'
]

Generate changelogs for end-user

With appropriate commits that follow the "Semantic Commits" as described you can generate this:

# Usability

- Customer can now login more easily

## Hints for customer

- Reseller get a security question when kicking customer
- Customer get a notice via mail when they have been kicked

This was the example of three commits getting together through some tool generating a changelog or feature list for end-user.

Give your client a text he understands

The client you service the application for might want to see the problem and how it has been solved:

# Usability

As a customer five steps are too much for logging in.
Therefore we put everything on one page and eliminate the obvious.

# Hints for customer

Reseller may accidentally kick customer from their list.
To avoid that a security question is nagging before.

Kicked customer won't recognize that they have no account any more.
As a customer who got deleted from the system,
I receive an E-Mail because I want to be informed.

Still the same three commits as before but a total different view of things for a total different person with other needs.

Have fun writing ad-hoc documentations, changelog, feature lists, comments on user stories ..........

Technical part

Recent commits to the Repository of the VCS GIT brought me the idea and had big influence on the structure. If you find something in capital letters not defined here then it's probably part of ABNF: http://tools.ietf.org/html/rfc2234

; # Semantic commits
;
; Writing commits is a fast and simple process which we do all day.
; Imagine them becoming powerful for us which finally give them some attention.
; The following semantic commits will do so and have the aim to:
;
; - Generate a changelog with commits for end-user
; - Generate a speaking summary for customer
; - Generate a easy to read list of changes for developer
; - In general: Make commits parseable by some script
;
; This is solved by the easy trick to use a well known structure (esp. PHP):
;
; - Class names and Methods can be detected by using their semantic.
; - Functions have a leading "()" which is obvious to detect.
; - More fuzzy commits without one particular target can get a "tag".
;
; Please leave a comment below if you are missing something in this prequel or in the ABNF.
;
;
; ## Example
;
; I just thought this would be nice as a commit message (almost full example):
;
; \Foo_Class::barMethod() can now print a baz (#123)
;
; In order to work as a human, I need to move in any SITUATION.
; But this meant a big load of work for humanity, which is a PROBLEM.
; As a human, I want to have a SOLUTION so that I can be lazy again.
;
; - funcPrint42() has been deleted
; - \Meh\Output has been extended for that purpose
; - \Foo_Class::barMethod() will pass "baz" to the output
; if it is in a good mood
; - /url/path has no need for human interaction till that
; - humanity: is no longer disturbed by work
; because we all like to be lazy
; - Except writing these lines one time
;
; The header describes in general where the change is, what and give some reference.
; After that follows an optional short text
; about the situation before (which can be a user story),
; the problems with that and what the solution now is
; (also possible user story) - feel free to add the pros and cons.
; In the end follows a list of changes that can be extended by describing if-clauses
; or the matter (because) why the change needed to happen.
; You might note that functions, classes, methods and URLs can be referenced as well as
; tags (followed by colon) and non-referencing simple sentences.
; It is very flexible because an user story can be
; the classic ones from Connextra,
; the simpler ones by Mike Cohn,
; the "Feature Injection Stories" by Chris Matts
; or a user story that would answer the proven "Five Ws".
;
;
;
; # Benefit
;
; Imagine a parser running through your code, mapping the references to according sections
; in an documentation and generating whole diff or manuals for developers.
; It can fetch the "long descriptions" / "paper questions part" to give your customer
; a brief text of what has been done to his website or application.
; For the most out there the heading is enough to gather text for a changelog.
;
;
; ## Mapping
;
; You can output the "tags" directly or filter them like this:
;
; [
; '\Class_Foo' => 'Usability',
; '\Class_Foo::someMethod()' => 'Hints for customer',
; 'humanity' => 'Human interaction'
; ]
;
;
; ## Generate changelogs for end-user
;
; With appropriate commits that follow the "Semantic Commits" as described you can generate this:
;
; # Usability
;
; - Customer can now login more easily
;
; ## Hints for customer
;
; - Reseller get a security question when kicking customer
; - Customer get a notice via mail when they have been kicked
;
; This was the example of three commits getting together through some tool
; generating a changelog or feature list for end-user.
;
;
; ## Give your client a text he understands
;
; The client you service the application for might want to see the problem
; and how it has been solved:
;
; # Usability
;
; As a customer five steps are too much for logging in.
; Therefore we put everything on one page and eliminate the obvious.
;
; # Hints for customer
;
; Reseller may accidentally kick customer from their list.
; To avoid that a security question is nagging before.
;
; Kicked customer won't recognize that they have no account any more.
; As a customer who got deleted from the system,
; I receive an E-Mail because I want to be informed.
;
; Still the same three commits as before but a total different view of things
; for a total different person with other needs.
;
; Have fun writing ad-hoc documentations, changelog,
; feature lists, comments on user stories ..........
;
;
; # Technical part
;
; Recent commits to the Repository of the VCS GIT brought me the idea
; and had big influence on the structure.
; If you find something in capital letters not defined here
; then it's probably part of ABNF: http://tools.ietf.org/html/rfc2234
;
; Special:
;
; - VCHAR means all of them except LF and CR
; - SP are not explicit written
; - If SP is written then only those SP count in that line
;
;
; Let's start with the technical part here.
commit = headline,
[2LF paper_questions]
[2LF notes]
;
; The commit
headline = title [tracking_code]
paper_questions = [situation LF] [problem LF] solution
notes = 1*20enumeration_item
;
; The headline
title = prefix[":"] short_message
tracking_code = "(" *VCHAR [SP "-" SP tracking_system] ")"
;
; The paper_questions - living text describing the issue (for the commit)
; How it was / is solved before the commit and what alternatives you had:
; What the problem of this was
; And how you solved it
situation = (*160VCHAR / user_story) "."
problem = *160VCHAR "."
solution = (*160VCHAR / user_story ) "."
;
; The notes
enumeration_item = *indent "-" SP title [LF *indent addendum] LF
;
; The title
prefix = class_name / method_name / function_name / url_path / descriptive_word
short_message = *VCHAR
;
; The tracking_code
tracking_system = *VCHAR
;
; The user_story
user_story = connextra_story / mike_cohn_story
;
; The enumeration_item
indent = 4SP
; explain on what it depends or why this particular change happened
addendum = ("if") / ("because" / "due to") *VCHAR
;
; The prefix
; Goes hand in hand with the PEAR Coding Standard where classes are Upper_Snake_Case
; or with a "\" for namespaces in between.
; It starts with a slash to show parser the presence of a class here
class_name = "\"(ALPHA / "_" / "\")
; method names are like "\Class_Name::methodName_123()"
method_name = class_name"::"function_name
; function names are like "methodName_123()"
; the trailing "()" is the indicator for parser that it's a function
function_name = ["\"]*(ALPHA / "_" / DIGIT / "\")"()"
; url paths are the relative link to a page callable in the browser
; so the changes will change the behaviour of that page in general
; the trailing "/" shows parser the presence of an URL
url_path = "/"*VCHAR
; descriptive words help if your commit has grown to big and is to fuzzy
; the end of it is marked with a ":" for the parser
descriptive_word = *VCHAR":"
;
; The user_story
connextra_story = mike_cohn_story " so that " benefit
mike_cohn_story = "As a " role ", I want " goal_desire
chris_matts_story = "In order to " benefit " as a " role ", I want " goal_desire
five_w_story = "As " fw_who SP fw_when SP fw_where ", I " fw_what " because " fw_why
role = *VCHAR
goal_desire = *VCHAR
benefit = *VCHAR
fw_who = *VCHAR
fw_when = *VCHAR
fw_where = *VCHAR
fw_what = *VCHAR
fw_why = *VCHAR
; Version History
;
; 0.1.0 - First thoughts in dirty BNF
; 0.2.0 - Some scribbled extensions
; 0.3.0 - More likely the way in proper ABNF
; - ABNF has been chosen as it is good for defining documentation and protocols
; - Big text has been added to describe the situation, the target and the solution to it
; 0.3.1 - The paper_questions changed
; - As the solution is the only one of interest to a customer the situation has become optional.
; The interest in general is: solution > situation > problem, which shall be documented.
; 0.4.0 - The enumeration_item gets keywords to introduce the reason of a change or its conditions (called `addendum`).
; 0.4.1 - Typos fixed, paper_questions have a better delimiter,
; indent is 4SP long because some MD-Parser had problems with 2SP lists
; 0.5.0 - Compatibility with user stories and issue systems
; - Connextra user stories added
; - User stories by Mike Cohn added
; - User stories like Feature Injection by Chris Matts added
; - User stories in form if the "Five Ws" added
; - Issue tracking changed from HEX to VCHAR
; and big change in syntax of tracking_code
; - Enhanced documentation by new user stories
;
; Issues
; - Document the interest "solution > situation > problem" with the how and why
; - It's not known if the addendum needs different words to introduce a condition
; - The brace for the issue-number does not support magic commits like "(github #2 fixed)"
;
@NewbiZ
Copy link

NewbiZ commented Mar 21, 2014

This kind of convention already exists, and is used for GNU Changelogs (which are then pasted as commit messages).
There are also tens of editor plugins and tools to parse this format.

See: http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html

i.e. let's take the last GCC commit as an example. Thanks to the format described below, it will be in the changelog, parsed by emacs to jump on edits / news, etc

2014-03-21  Martin Jambor  <mjambor@suse.cz>

PR ipa/59176
* cgraph.h (symtab_node): New flag body_removed.
* ipa.c (symtab_remove_unreachable_nodes): Set body_removed flag
when removing bodies.
* symtab.c (dump_symtab_base): Dump body_removed flag.
* cgraph.c (verify_edge_corresponds_to_fndecl): Skip nodes which
had their bodies removed.

testsuite/
        * g++.dg/torture/pr59176.C: New test.

@seanjensengrey
Copy link

It would be nice if there were sparklines that showed number of files touched, lines added/removed.

@ScreamingDev
Copy link
Author

Thanks for this @NewbiZ. Never took a look at those but it's quiet interesting. It is way much better than usual commits and tells more about it. I think especially the reference to an author is missing in my proposal.

@seanjensengrey that would be up to the tool I guess :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment