PrefaceThis week, I decided to improve my Git workflow by completing the TODO items that I had been putting off for a week because of work. In order to carry as much context as possible when committing, we make the commit message include the JIRA number that we are working on. This way, if someone returns to the source code that we are currently committing to in the future and types Including this information in every commit can be a bit tedious (if you’re using something like TDD[1], you’ll commit more often), and, while git clients like Tower[2] make this easier, you still have to manually copy and paste the issue number into the commit message, and remembering to do so is my biggest pain point 😅. For this reason, I started looking into git hooks to try to automate this task. My idea was to be able to get the JIRA number from the git branch (we have a branch naming convention like: story/ISSUE-1234_branch-name) and then change the commit message to be prefixed with the JIRA number, resulting in the final result message: ISSUE-1234-other-original-commit-message. Automatically generate commit messages with git hooksGit Hooks[3] provide a way to trigger custom actions when running certain important git commands, such as performing some operations before a commit or push. In this example, I used the commit-msg hook, which is able to modify the current commit message before it takes effect. The hook is called with one argument, which is the path to a file containing the commit message entered by the user. This means that in order to change the commit message, we only need to read from the file, modify its contents, and then write back to the file that called the hook. To create a git hook, we need to provide an executable script under the .git/hooks path. My hook is placed under the .git/hooks/commit-msg path. Why do I use Swift?Git hooks can be written in any scripting language you are familiar with and for which an interpreter is installed on the host (specified via shebang). Although there are many more popular options like bash, ruby, etc., I decided to use Swift because I am more familiar with it, because I use it every day, and I really like its strongly typed syntax and low memory footprint. Let’s get startedYou can write Swift scripts in any IDE you like. But if you want proper code completion and debugging capabilities, you can create an Xcode project for it. To do this, create a new project in macOS by selecting Command Line Tool. Add the Swift shebang at the top of the created file to import the Foundation library. # ! / usr / bin / swift This way when git executes the file, the shebang will ensure that the /usr/bin/swift binary is called with the file as input data. Writing git hooksThe project is all set up, so now it's time to write the git hook. Let's walk through the steps. Retrieving commit messagesThe first thing to do is to retrieve the path to the temporary commit file from the arguments passed to the script and then read the file contents. let commitMessageFile = CommandLine .arguments [ 1 ] In the above code snippet, we first get the path to the commit file (which git passes to the script), and then read the file contents through the FileManagerAPI. If the retrieval fails for some reason, we exit the script and return status code 1, which tells git to abort the commit. Notice: According to the git hooks documentation, if any hook script returns a status code greater than Search issue numberNow that the commit message string is available, we need to find the current branch and retrieve the issue number from it. As mentioned earlier in this article, this is only possible because the team has a strict format for naming branches, which always includes the JIRA number in its name (for example, story/ISSUE-1234_some-awesome-feature-work). To achieve this, we have to retrieve the current working branch and then use a regular expression to retrieve the issue number from it. Let's start by adding the ability for a script to call zsh shell commands. By using the Process API, a script can interact with the git command line interface. func shell ( _ command : String ) -> String { Now that we have the shell command implemented, we can use it to ask git what the current branch is, and then extract the issue number from it if possible. let gitBranchName = shell ( "git rev-parse --abbrev-ref HEAD" ) Note that if there is no match (i.e. the branch name does not contain a JIRA issue number), the script will exit with a status of 0, allowing commits to proceed without making any changes. This is to not disrupt workflow in branches such as main or other testing/investigation branches. Modify the commit messageIn order to change the commit message, the contents of the file read at the beginning of the script (containing the commit message) must be written back to the same path. In this case, the only change you need to make is to prepend the JIRA number and a (-) to the front of the commit message to separate it nicely from the rest of the commit message. You must also make sure that you check the commit message string and only add the number if it is not already present: if ! commitMessage .contains ( ticketNumber ) { Setting up git hooksNow that the script is ready, it's time to put it somewhere git can find it. Git hooks can be set globally or on a per-repo basis. My personal preference for these kinds of scripts is to set them up on a per-repo basis, as this gives you more control and visibility when things go wrong, and if the hook starts failing it will fail in the repo it's set up in, rather than globally. To set them up, we just need to make the file executable, rename it and copy it to the .git/hooks/ path of the repo we want to set up: chmod + x main.swift Test ResultsNow that the repo is all set up, all that's left is to test the deployment script. In the screenshot below, two branches are created, one with an issue number and one without, and they have the same commit message. You can see that the script works fine and only changes the commit message when needed! References[1] TDD: https://en.wikipedia.org/wiki/Test-driven_development. [2] Tower: https://www.git-tower.com/mac. [3] Git Hooks: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks. |
<<: iOS 16 update fixes a lot of issues
>>: JD.com 618 Advertising Ranking Percentile AUC Improvement Technical Solution
On December 9, Apple's vice president of glob...
There are three articles in the series "Touc...
Chinese Academy of Sciences releases blue book on...
"We can't book a venue there." The ...
If a product with good ASO is like a famous celeb...
iOS 9 has been released, and everyone has to expe...
From computers to mobile phones, no matter how th...
Generally speaking, new systems and new hardware ...
On June 21, 2024, Gao Jianwei, senior engineer of...
Startup companies are generally in a state of hav...
As an important part of the marketing process, co...
Training course content: Teacher Xiaojing’s gramm...
Review expert: Yin Tielun, deputy chief physician...
Attracting new users does not mean activating new...
A weird black hole is spewing plasma into a nearb...