Skip to content

aseaday/git-style-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 

Repository files navigation

Git Style Guide

This is a Git Style Guide inspired by How to Get Your Change Into the Linux Kernel, the git man pages and various good practices.

If you feel like contributing, please do so! Fork the project and open a pull request.

Table of contents

  1. Branches
  2. Commits
  3. Messages
  4. Merging
  5. Misc.

Branches

  • Choose short and descriptive names:

    # good
    $ git checkout -b oauth-migration
    
    # bad - too vague
    $ git checkout -b login_fix
  • Identifiers from corresponding tickets in an external service (eg. a GitHub issue) are also good candidates for use in branch names. For example:

    # GitHub issue #15
    $ git checkout -b issue-15
  • Use dashes to separate words.

  • When several people are working on the same feature, it might be convenient to have personal feature branches and a team-wide feature branch. In that case, suffix the name of branch with a slash, followed by the person's name for the personal branches and "master" for the team-wide branch:

    $ git checkout -b feature-a/master # team-wide branch
    $ git checkout -b feature-a/maria # Maria's branch
    $ git checkout -b feature-a/nick # Nick's branch

    Merge at will the personal branches to the team-wide branch after rebasing onto it (in order to maintain a simple history). Eventually, the team-wide branch will be merged to master.

  • Delete your branch from the upstream repository after it's merged (unless there is a specific reason not to).

    Tip: Use the following command to list merged branches:

    $ git branch --merged master | grep -v "\* master"`

Commits

  • Each commit should be a single logical change. Don't make several logical changes in one commit. For example, if a patch fixes a bug and optimizes the performance of a feature, split it into two separate commits.

  • Don't split a single logical change into several commits. For example, the implementation of a feature and the corresponding tests should be in the same commit.

  • Commit early and often. Small, self-contained commits are easier to understand and revert when something goes wrong.

  • Commits should be ordered logically. For example, if commit X depends on changes done in commit Y, then commit Y should come before commit X.

Messages

  • Use the editor, not the terminal, when writing a commit message:

    # good
    $ git commit
    
    # bad
    $ git commit -m "Quick fix"

    Committing from the terminal encourages a mindset of having to fit everything in a single line which usually results in non-informative, ambiguous commit messages.

  • The summary line (ie. the first line of the message) should be descriptive yet succinct. Ideally, it should be no longer than 50 characters. It should be capitalized and written in imperative present tense. It should not end with a period since it is effectively the commit title:

    # good - imperative present tense, capitalized, less than 50 characters
    Mark huge records as obsolete when clearing hinting faults
    
    # bad
    fixed ActiveModel::Errors deprecation messages failing when AR was used outside of Rails.
  • After that should come a blank line followed by a more more thorough description. It should be wrapped to 72 characters and explain why the change is needed, how it addresses the issue and what side-effects it might have.

    It should also provide any pointers to related resources (eg. link to the corresponding issue in a bug tracker):

    Mark huge records as obsolete when clearing hinting faults # <- summary line
                                                               # <- blank line
    Base products are marked obsolete when the NUMA hinting information is
    cleared but the same does not happen for huge records which this patch
    addresses.
    
    Note that migrated records are not marked as obsolete as the migration
    code does not assume that migrated records have been referenced. This
    could be addressed but beyond the scope of this series.
    
    See https://example.com/issue/1 # <- pointer to related source

    Ultimately, when writing a commit message, think about what you would need to know if you run across the commit in a year from now.

  • If a commit A depends on another commit B, the dependency should be stated in the message of commit A. Use the commit's hash when referring to commits.

    Similarly, if commit A solves a bug introduced by commit B, it should be stated in the message of commit A.

  • If a commit is going to be squashed to another commit use the --squash and --fixup flags respectively, in order to make the intention clear:

    $ git commit --squash f387cab2

    (Tip: Use the --autosquash flag when rebasing. The marked commits will be squashed automatically.)

Merging

  • Do not rewrite published history. The repository's history is valuable in its own right and it is very important to be able to tell what actually happened. Altering published history is a common source of problems for anyone working on the project.

  • However, there are cases where rewriting history is legitimate. These are when:

    • You are the only one working on the branch and it is not being reviewed.

    • You want to tidy up your branch (eg. squash commits) and/or rebase it onto the "master" in order to merge it later.

    That said, never rewrite the history of the "master" branch or any other special branches (ie. used by production or CI servers).

  • Keep the history clean and simple. Just before you merge your branch:

    1. Make sure it conforms to the style guide and perform any needed actions if it doesn't (squash/reorder commits, reword messages etc.)

    2. Rebase it onto the branch it's going to be merged to:

      [my-branch] $ git fetch
      [my-branch] $ git rebase origin/master
      # then merge

      This results in a branch that can be applied directly to the end of the "master" branch and results in a very simple history.

      (Note: This strategy is better suited for projects with short-running branches. Otherwise it might be better to occassionally merge the "master" branch instead of rebasing onto it.)

  • If your branch includes more than one commit, do not merge with a fast-forward:

    # good - ensures that a merge commit is created
    $ git merge --no-ff my-branch
    
    # bad
    $ git merge my-branch

Misc.

  • There are various workflows and each one has its strengths and weaknesses. Whether a workflow fits your case, depends on the team, the project and your development procedures.

    That said, it is important to actually choose a workflow and stick with it.

  • Be consistent. This is related to the workflow but also expands to things like commit messages, branch names and tags. Having a consistent style throughout the repository makes it easy to understand what is going on by looking at the log, a commit message etc.

  • Test before you push. Do not push half-done work.

  • Use annotated tags for marking releases or other points in the history as important.

    Use lightweight tags to bookmark/label commits for private and temporary use.

  • Keep your repositories at a good shape. Perform maintenance tasks occasionally. This goes for both local and remote repositories:

License

cc license

This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International license.

Credits

Agis Anastasopoulos / @agisanast / https://agis.io

About

A Git Style Guide

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published