git format-patch and git am

# format-patch creates a patch file
# the -1 $COMMIT arguments take the last commit and put it into the file
git format-patch -1 14ab6d…..

#Applies the commits in the patch file onto the current branch
git am ../folder/2019-10-17/0001-SLEDGE-32

#This git log command pulls the history of a file into one patch
git log --pretty=email --patch-with-stat --reverse -- path/file_or_dir 
git am <  path/to/file_or_dir 

Always squash before opening Pull requests

When you are working on a feature it makes sense to make incremental commits as you proceed with the work. Then when you are done you want to just open a Pull Request and wait for approvals. But it is important to squash your commits into a single commit before merging  into the master branch. The reason is if you need to revert your code change, you can revert a single commit and move on. You don’t want to be in a position where you have a serious bug in production, and you are trying to figure out if you reverted all of the commits. Save yourself the panic and trouble by squashing before you commit to your master branch. Some services like github will automatically squash for you, use that feature if you have it. 

Useful git commands for squashing

# git --amend amends your last git commit 
git commit --amend

# rebase is the command used to actually squash commits 

# git rebase -i HEAD~4 rebases the last 4 commits including the head commit
# the -i toggles interactive mode which opens an editor
git rebase -i HEAD~4

When you run the command git will open a text editor that asks you to choose what to do with each commit.

Example screen when you start an interactive rebase. All commits are picked by default.

The default is the vi or vim editor. In this window you want to change the command for the commits you want to squash. 

Interactive rebase menu

Then the next window will give you a chance to modify the commit message for your new combined commits.

Update the commit message for the squashed commits
Final commit after rebase

Prettier: Automatic code formatting for the Javascript ecosystem

I do most of my work in the Go ecosystem and rely heavily on the go fmt tool to maintain style consistency across the team. But the javascript language does not have a formatter built in so we have been relying on jslint to enforce consistent styles.  I found a auto-formatter for javascript prettier, which could make frontend formatting much easier you can find it at https://prettier.io. Prettier supports JSX which is key for us since we work on a single page application with a react.js frontend. I have added prettier to my crypto-exchange application https://github.com/Sevii/pepper-exchange to evaluate how well it works.

I dislike using linters to address code formatting and style questions because they basically nag developers into formatting things correctly.  Code formatting is low value work, I would much rather have a machine do it in 250ms  than have a developer spend 60 seconds addressing linter issues. 

Prettier should let us eliminate formatting nagware, and limit our use of jslint to semantic and correctness issues.

You can use prettier as follows. 

yarn add prettier --dev --exact

# or globally

yarn global add prettier

prettier --write "src/**/*.js"    # This command will format any .js files in your src folder.

Git hooks for Go fmt

A common problem when reviewing pull requests is large diffs of formatting changes. You end up with pages of formatting changes that people waste time looking at when in reality it was just a 3 line PR. Go has a tool called fmt which can format any Go code into the standard Go format. What happens in my project is that some of the team has their IDE configured to automatically run go fmt when they save a file, while the rest do not. So our codebase is in an inconsistently formatted state. What I am attempting to do is to setup a git-hook that will run go fmt before any commits.

The .git/hooks directory contains samples of git hooks that can be triggered on various git actions like pre-commit, post-commit, post-receive, etc. The files need to be executable, with no extension and named after the appropriate hook. This digital ocean link has a table of the available hooks if you scroll down a bit https://www.digitalocean.com/community/tutorials/how-to-use-git-hooks-to-automate-development-and-deployment-tasks#basic-idea-with-git-hooks. 

The hooks are just executable files and it may be possible to run compiled binaries as well as shell scripts. Here is my working go fmt pre-commit hook. I edited the example script in .git/hooks/pre-commit.sample to run go fmt and renamed it to pre-commit.

 

#!/bin/sh
#
# A  hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
# This hook runs 'go fmt ./...' on the project
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
        against=HEAD
else
        # Initial commit: diff against an empty tree object
        against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

echo "Running go fmt"
go fmt -x ./...

 

 

Here are some further references.

An Example Git-Enforced Policy

https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy#_an_example_git_enforced_policy

Pre-Commit    NPM based git-hook installer https://github.com/observing/pre-commit

Githooks 

https://githooks.com