Solo projects, or projects where you are the sole developer. You are using version control to track your own changes, and perhaps are looking to expand your team and want to implement some structure now so that it's easier to work with others. It is assumed that no one else is working on your published repository, and that you don't need to worry about rebasing your work after it's been published.
- Commit messages are descriptive, and never repeated. If you are working on a problem which has a few follow-up commits to fix minor issues, squash these minor changes into a single commit using
git rebase -i
. - You tag releases according to when code was published, or shared with a client so that you may easily review highlights using
git tag -a "tagname" -m "reason for tag"
. - If you are extending another probject, keep your own changes in a separate branch so that you can easily pull changes from the main project into your own work using
git branch <branchname>
. - You use standards for everything that is arbitrary. For example: structure of a commit message; granularity of a commit; branch names; tag names. Document your standards in a README file which is embedded in the project.
- Where possible, use external, automated review tools. For example, Drupal has the coder module to check code against Drupal standards.
As soon as you start collaborating on a project, you will begin building on the best practice rules. Determine ahead of time how trust will be determined. Do you have test coverage? Peer review? Who is responsible for QA?
- All changes are documented first via a ticketing system of some kind. Each change is implemented in its own branch. Branches are named according to the ticket number, and a brief description. for example:
231-add_thumbnail_blog_posts
. - The first word of a commit message always references the ticket number in square brackets. For example:
[#231] Added thumbnails to blog posts
. The square brackets prevent the commit message from being interpreted as a comment (and thus hidden fromgit log
).
As soon as you introduce a review process, you introduce the concept of a gate keeper. This gate keeper might be automated (Jenkins running test suites), or manual (a QA team, or peer review). You may have several review points: e.g. peer review before the ticket is closed, and the a second QA review of all tickets completed in a given sprint. Each time you delay a change from being deployed, you are introducing a potential for code to get out of sync as other developers continue to work on new problems.
How you deal with the review and collation process will inform your branching strategy.
This is completely subjective. I think in increments, therefore I commit in increments, I want to be able to track how I thought through a problem. I do not necessarily want to be able to roll back to every single commit in my time line. This also means that I'm willing to sacrifice the tool git bisect
when debugging work as a single commit may not actually bit a coherent point in the code base where the build compiled. HOWEVER, the title of this section is actually about the best-ever PUBLISHED commit, i.e. one that is shared with others.
- Contains only related code. No scope creep, no "just fixing whitespace issues too".
- Conforms to coding standards for your project, including in-code documentation.
- Is just the right size. Perhaps this is 100 lines of code. Or perhaps it's a mega refactoring where a function name changed and 1000 lines of code were affected.
- Is described in the best-ever commit message (see the next section).
My friend Joe Shindelar writes the best-ever commit messages. His general rule is "Whatever it takes to make future me not get pissed off at past me for being lazy."
- Use a standard format to make it easy to scan logs.
- Answer the question: Why is this change necessary?
- Describe, at a high level, how the change addresses the issue identified.
- Outline the potential side effects the change may have.
- Give a summary of the changes made, so that reading the diff of the code confirms the commit message, but reading the diff is not guesswork on what / why something has changed.
- Is there test coverage for our code?
- Will our customers download a product binary to receive new updates?
- Do we work with a timed sprint or date-based release schedule?
- Are the individual developers responsible for monitoring the pushed changes on each release? (vs. a separate, dedicated ops team)
- Are new features collated into a demo for review before they are released?
- Do your developers have areas of responsibility? (vs. levels of senority)
- Will team members share work in progress?
- When debugging a problem, do you want to be able to roll the code back to a specific commit? (vs. always moving forward)
- Is your team willing to enforce tidy commit messages?
- Will your team be able to reach concensus on the granularity of a commit?
- When tracing a problem, are you likely to use gitk?
- Do the origins of a problem matter? (or does it simply matter that you find the piece of code that's broken)