Category Archives: 08 – Reference

Commit Message Standards

Welcome to the NZRT Wiki Podcast. Today we’re looking at 💬 Commit Message Standards.

If you’ve ever looked back through a project’s git history and had no idea what anyone was actually doing, this episode is for you. At NZRT, we follow a format called Conventional Commits, and once you get used to it, you’ll wonder how you ever lived without it. It makes your history scannable, your changelogs automatable, and your teammates much happier.

So let’s start with the structure. Every commit message you write follows the same basic shape. You open with a type, then optionally a scope in parentheses, then a colon and a short subject line. Below that, separated by a blank line, you can add a body. And below that, a footer for referencing issues or flagging breaking changes. Think of it as: what kind of change, where it happened, what it does, why it was needed, and what it affects.

Let’s talk about types first. There are ten of them. “feat” is for a new feature. “fix” is a bug fix. “docs” means you’re only touching documentation. “style” is for code formatting changes with no logic impact. “refactor” means you restructured code without changing its behaviour or fixing a bug. “perf” is a performance improvement. “test” is for adding or updating tests. “chore” covers maintenance work like updating dependencies or build config. “ci” is for changes to your continuous integration or deployment setup. And “revert” is for undoing a previous commit.

Now for scope. The scope is optional, but recommended. It goes inside parentheses right after the type, and it tells you which part of the codebase was touched. At NZRT, the approved scopes are: wp-sync for the WordPress and Dolibarr sync module, dolibarr for the ERP integration, api for the REST API, db for database work and migrations, sync for product or data sync, deploy for deployment processes, test for testing infrastructure, and docs for documentation.

Your subject line is the short description that follows the colon. Keep it under fifty characters, write it in imperative mood — so “add” not “added” or “adds” — start it lowercase, and don’t put a period at the end. So you’d write something like: feat wp-sync, colon, add product comparison widget.

The body is where you explain the why. Not what the code does — the code shows that. But why this change was necessary, what problem it solves, or what decision was made. Wrap each line at around seventy-two characters, and leave that blank line between the subject and body.

The footer is for linking to issues. You use “Closes” followed by a hash and issue number to auto-close that issue when the commit merges. “Refs” references an issue without closing it. And if your change breaks something for existing users — like renaming a field in an API response — you add a line starting with BREAKING CHANGE followed by a colon and an explanation. That signals a major version bump is needed.

Let me walk you through a few examples in plain language.

The first example is a feature commit for the wp-sync scope. The subject says “add product comparison widget.” The body explains that a side-by-side comparison feature was implemented for customers, introduces a new shortcode and page template, and includes styling and interactivity. The footer closes issue 42.

The second is a bug fix in the sync scope. The subject is “prevent duplicate product sync.” The body explains that a webhook was firing twice because there was no idempotency check, and that the fix adds signature validation and idempotency key tracking. It closes issue 89 and references issue 87.

There’s also a performance example in the db scope. The subject is “optimize product list query.” The body explains that indexed lookups replace a full table scan for category filtering, cutting query time from five hundred milliseconds down to fifty milliseconds on large catalogs.

And a breaking change example in the api scope. The subject includes an exclamation mark after the scope to flag it as breaking. The footer uses BREAKING CHANGE to explain that a field called product underscore id has been renamed to just id in the response, and tells clients exactly what to update.

Before you commit, run through a quick checklist. Is the type one of the ten approved types? Is the scope lowercase and from the approved list? Is the subject in imperative mood? Is it under fifty characters with no trailing period? Does the body explain why, not what? Are issues referenced properly? And are breaking changes called out in the footer?

Finally, you can enforce all of this automatically with a git hook. You’d create a file called commit-msg inside your dot git hooks folder. The script reads your commit message and checks it against a pattern matching the type, scope, and subject format. If the message doesn’t match, it prints an error, shows you what the expected format looks like, and blocks the commit from going through. You then make the file executable with a chmod command. One-time setup, saves a lot of back-and-forth in code review.

That’s it for this episode of the NZRT Wiki Podcast. Thanks for listening.

Git Commands Cheatsheet

Welcome to the NZRT Wiki Podcast. Today we’re looking at the Git Commands Cheatsheet.

Git is the version control system we use across all NZRT repositories, and this cheatsheet covers everything from first-time setup through to advanced recovery operations. Let’s walk through it section by section.

Starting with initial setup. Before you do anything else, you tell Git who you are. There are commands to set your global username, your email address, your preferred text editor, and to switch on coloured output in the terminal. Once those are set, you can list your current configuration at any time to confirm everything looks right.

Next up, creating and cloning repositories. If you’re starting from scratch on a local folder, you initialise Git in that directory, optionally giving the project a name. If you’re pulling down an existing NZRT repo from GitHub, you clone it using its URL. You can also clone into a custom-named folder, or do what’s called a shallow clone, which grabs only the most recent snapshot rather than the full history — useful when you just need the code fast and don’t need every past commit.

Moving on to checking status and history. This is where you spend a lot of your daily Git time. You can check what’s changed right now with the status command, including a short compact version that also shows your branch. For history, you can view the full commit log, or a condensed one-line-per-commit version, limit it to the last five commits, or draw a visual graph showing how branches have diverged and merged. You can filter history by author, by date range, by keywords in commit messages, or even view the actual code changes alongside each commit. You can also view differences — between your working files and the last commit, between staged changes and the last commit, or between any two branches or specific commits.

Branching is next, and it’s one of Git’s most powerful features. You can list all your local branches, all remote branches, or both together. You can create a new branch, switch to an existing one, or create and switch in a single step. Newer versions of Git introduced a cleaner switch command that does the same thing. You can rename branches and delete them — either safely, where Git stops you if the branch hasn’t been merged yet, or forcefully if you’re sure you want it gone. You can also delete branches that exist on the remote server.

Then there’s staging and committing — the core of your daily workflow. You check what’s changed, stage individual files or everything at once, or use interactive mode to choose exactly which chunks of changes to include. You can unstage things if you change your mind. When you commit, you write a short message describing what changed. You can amend your last commit if you forgot something, or add to it without even changing the message. If you want to throw away local changes entirely, there are restore commands that discard them from your working directory.

Merging and rebasing handle bringing branches back together. You can merge a feature branch into your current branch, with options to always create a merge commit or to squash all the feature branch’s commits into one clean commit. Rebasing replays your commits on top of another branch, keeping history linear. Interactive rebase lets you reorder, squash, or edit individual commits — very handy before pushing. Cherry-pick lets you grab one specific commit from anywhere and apply it to your current branch.

Pushing and pulling covers syncing with the remote. You push your local commits up to GitHub, specifying a branch name or using your current branch. The first time you push a new branch, you set the upstream tracking reference at the same time. Force pushing is available but flagged as dangerous — use it carefully. Pulling downloads and merges remote changes in one step, or you can use pull with rebase to keep history cleaner. Fetching downloads changes without merging them, giving you a chance to review before integrating.

Undoing changes is something you’ll need eventually. You can discard file changes, unstage files, or undo entire commits. Revert creates a new commit that cancels out a previous one — the safe option for shared branches. Reset lets you move your branch pointer back one or more commits, with three modes: soft keeps your changes staged, mixed unstages them but keeps the files, and hard discards everything. There’s also a clean command to remove untracked files, with a dry-run option to preview what would be deleted before you commit to it.

Stashing gives you a temporary holding area. If you need to switch context mid-work, you stash your changes, switch branch, do the other work, come back and pop the stash to restore where you were. You can name stashes, list them, apply specific ones, and clear them all at once.

Tags mark release points. Lightweight tags are just pointers to commits. Annotated tags include a message and are the recommended type for releases. You can push individual tags or all tags to the remote, and delete them locally or remotely.

Remote management lets you list, add, rename, or remove the remote servers your repo points to. You can also inspect a remote to see exactly what branches it’s tracking.

Finally, advanced operations. There’s bisect, which helps you find the exact commit that introduced a bug by binary-searching through history. Blame shows you who wrote each line of a file and when. Reflog is your safety net — it records every position your branch pointer has been, so you can recover from almost any mistake. There are also commands to search commit history for specific text, verify signed commits and tags, and view the full change history of a single file.

The cheatsheet ends with a set of useful aliases you can add to your Git configuration — shortcuts like using the letters s t for status, c o for checkout, and a visual alias that draws the full branch graph in one command.

That’s it for this episode of the NZRT Wiki Podcast. Thanks for listening.

Github Cli Cheatsheet

Welcome to the NZRT Wiki Podcast. Today we’re looking at 🖥️ GitHub CLI Cheatsheet.

If you’ve ever wished you could do everything GitHub-related without leaving your terminal, the GitHub CLI tool, known as gh, is exactly what you need. It lets you manage repositories, pull requests, issues, releases, and more, all from the command line.

Let’s start with getting it installed. On Windows, you can install it using either Chocolatey or winget by running the install command for GitHub dot cli. On a Mac, Homebrew handles it with a simple brew install. On Linux, you can use apt. Once installed, you can verify everything worked by checking the version. Then you authenticate by running gh auth login, which walks you through an interactive setup where you choose GitHub dot com, pick SSH or HTTPS, and generate an access token. If you already have a token in a file, you can pipe that file directly into the login command to skip the prompts.

To check your current login state, you run gh auth status. To log out, gh auth logout. Simple.

Now, working with repositories. You can clone any repo by passing the owner and repo name to gh repo clone. You can even specify a destination folder as a second argument. To view information about a repo, you use gh repo view, either for your current directory or by naming the owner and repo. Tacking on the web flag opens it straight in your browser. You can list all repos under an organisation, filter for archived ones, or cap the results with a limit flag. Creating a new repo is just gh repo create, with options to make it private and add a description. Forking works similarly with gh repo fork, and adding the clone flag pulls it down to your machine at the same time.

Pull requests are where the CLI really shines. You create one with gh pr create, and you can specify a title, a body description, a base branch, a head branch, or mark it as a draft, all as flags on that same command. To see what’s open, gh pr list, filtered by state, author, or base branch as needed. You can view a specific PR by number, check its CI status with gh pr checks, request a review, approve it, request changes with a comment, or leave a comment yourself. Merging is flexible too: you can squash, rebase, or create a standard merge commit, and you can automatically delete the branch after merging. Closing or reopening a PR is just one command each.

Issues follow the same pattern. You create them with a title, body, and labels. You list them filtered by state, assignee, or label. You view, close with an optional comment, reopen, comment on, or edit them to change titles or add and remove labels.

For GitHub Actions, gh run list shows your recent workflow runs. You can view details and logs for a specific run by its ID, download artifacts, trigger a workflow manually if it supports that, and list all available workflows in your repository.

Releases are just as straightforward. You can list them, view a specific one by tag, create a new release with a title, or let GitHub auto-generate release notes from your merged pull requests. You can mark a release as a draft or a pre-release, upload assets like zip files to an existing release, edit it later, or delete it entirely.

Branch operations in the CLI lean on the gh api command, which lets you talk directly to the GitHub REST API. You can list branches, create one by passing a reference name and a commit hash, or delete one by sending a delete request to the reference endpoint.

For discussions, you can create one with a title, body, and category, then list discussions filtering for answered or unanswered ones, or view a specific discussion by its ID.

Label management is clean: list labels, create one with a name, a hex colour code, and a description, edit an existing label, or delete it.

You can also set up aliases in your git config to shortcut common gh commands. For example, mapping pr-create to gh pr create, or status to gh pr checks, so your muscle memory works even faster.

Finally, a few handy one-liners worth knowing. You can open your current repo in the browser with a single command. You can push a branch and immediately create a pull request in one chained command. You can merge and delete the branch in one go. You can create a release from your latest git tag and auto-generate the notes. And you can list all pull requests waiting specifically for your review by searching for your username in the reviewer-requested filter.

That covers the full GitHub CLI toolkit, from setup and authentication through to repos, pull requests, issues, actions, releases, branches, labels, and discussions.

That’s it for this episode of the NZRT Wiki Podcast. Thanks for listening.

Gitignore Templates

Welcome to the NZRT Wiki Podcast. Today we’re looking at .gitignore Templates.

So, what is a .gitignore file? Put simply, it is a file you place in your Git repository that tells Git which files and folders to leave alone — to never track, never commit, and never push. At NZRT, every repository uses a .gitignore tailored to the language or framework being used, and today we are going to walk through all of them.

Let us start with WordPress. The WordPress .gitignore is one of the more detailed ones, because WordPress installations have a lot of moving parts you do not want in version control. It excludes the WordPress core folders and files — the admin panel, the includes directory, and the main PHP files — since those are installed separately. It also excludes your WordPress configuration files, including any environment files, because those contain sensitive local settings. User uploads are excluded too, since binary media files have no place in a code repository. Here is the interesting part: all plugins and all themes are excluded by default, except for the ones NZRT actually builds and maintains — the custom sync plugin and the custom NZRT theme are specifically allowed back in. Third-party packages, IDE configuration folders, and common operating system files like the Mac finder metadata file and the Windows thumbnail database file are also excluded.

Next up is PHP. The PHP template is simpler. It excludes your vendor dependencies folder, environment files, IDE settings, test coverage reports, log files, temporary files, and your build output folders. If you are building a standalone PHP project or a Dolibarr module, this is your starting point.

For Node.js and JavaScript projects, the template covers the node modules folder — which you never want in Git because it can contain thousands of files — along with lock files for npm, Yarn, and pnpm. Build output directories, test coverage, log files, caches, and framework-specific folders like the Next.js output directory are all excluded.

For Python, the list is longer because Python generates quite a few artefacts. Virtual environment folders are excluded — these are your isolated Python installations and should never be committed. Compiled Python files and bytecode caches are excluded. Distribution and packaging folders are excluded. Test tooling outputs, IDE settings, environment files, log files, and local database files like SQLite databases round out the list.

The Docker template is short and focused. It excludes Docker secret files, any override files for Docker Compose — which are typically used for local development overrides — and log files.

There are also two cross-language sections. One covers compiled binaries and executables: things like Windows DLL files, Mac dynamic libraries, Linux shared object files, and compiled object files. These are outputs of a build process and should never live in source control. The other covers database exports: SQL dump files, compressed SQL files, and SQLite database files. Importantly, there is an exception carved out — SQL files inside a migrations folder are allowed, because those are intentional schema version files you do want to track.

The secrets and credentials section is one of the most important. It excludes entire folders like a secrets directory or private directory, SSH key files and certificate files, credential JSON files, token files, and all environment configuration files. There is one deliberate exception: files named with the word example are allowed through, so you can commit an example key file as a template for other developers to follow.

All of these patterns are combined into the NZRT Standard .gitignore, which is the catch-all template used across repositories. It brings together environment and secrets exclusions, dependency folders for both PHP and Node, build and distribution output, logs, test coverage, IDE files, operating system noise, WordPress-specific paths, Python virtual environments, and temporary files. If you are starting a new NZRT repository and you are not sure which template to use, start here.

Finally, let us talk about verifying and maintaining your .gitignore. There are a few commands worth knowing. You can ask Git to explain exactly why a particular file is being ignored, and it will tell you which rule in which .gitignore file is responsible. You can also do a dry run that lists everything Git would remove if you cleaned untracked files — useful for checking your rules are working without actually deleting anything. If you need to force-add a file that is being ignored, you can override the ignore rule for that one file. And if a file is already being ignored but it is already tracked by Git — meaning it was committed before the rule existed — you can remove it from Git’s tracking without deleting it from disk.

On that last point: if you add new rules to an existing repository, files that were already committed will not automatically be excluded. You need to remove everything from Git’s cache, re-add all files so Git picks up the new rules, and then commit that change. A commit message like “chore: update .gitignore” is the conventional way to label that housekeeping commit.

That covers the full set of .gitignore templates NZRT uses across its repositories, why each section exists, and how to verify things are working correctly.

That’s it for this episode of the NZRT Wiki Podcast. Thanks for listening.