How I Git

🗞
Published on

September 23, 2019

Reading time

5 minutes

Word Count

810 words

Technologies Logo Git

I've been slinging code for nearly 20 years now. I've navigated the murky waters of version control, starting with CVS, Subversion, Perforce, and Git; with the latter being my de-facto since around 2010.

Mild Rant About Git

Git isn't the version control system I want, but it is the version control system I have. I won't complain too much, but why does Git require an email address to identify authors and why can't a commit have multiple authors? Pfft.

firmly believe that we're stuck with Git. The only company that can change that is GitHub; providing a newer better VCS that would allow interoperability with Git while we all migrate over.

Will that ever happen? Doubtful 😞

Cloning Repositories

Clone to Where?

First, we'll start with the simplest of concerns: I clone all my repositories to ~/Code/src. This is also my GOPATH. For Go developers, this is likely unsurprising.

I used to keep my Go projects and other code in separate directories, but eventually this become quite natural to adopt the "Go way".

Inside of ~/Code/src is a directory for every host that I clone repositories from. Inside their, orgs/usernames. Inside them, individual repositories.

It looks like this:

shell
├── aur.archlinux.org
│  ├── fluxlang
│  ├── pulumi-bin
│  └── yay
├── github.com
│  ├── chaoss
│  │  └── augur
│  ├── influxdata
│  │  ├── flux
│  │  ├── influxdb
│  │  ├── telegraf
│  ├── pulumi
│  │  └── pulumi
│  ├── rawkode
│  │  ├── dotfiles
│  │  ├── influxdb-examples
│  │  ├── kubernetes-workshop
│  │  ├── modern-life
│  │  ├── php-stat-influxdb
│  │  └── saltstack-dotfiles
└── golang.org
   └── x
      ├── lint
      └── tools

The Actual Cloning

There are two rules when cloning repositories:

  1. Clone Over HTTPs
  2. Never clone a fork directly

Clone Over HTTPS

I'm a rather cautious person. I've got into the habit of only cloning public repositories over HTTPs so that I never accidentally push to main. Even if I don't own the repository, i've made this my default and it keeps me sane.

NB: This is a "whenever possible" rule. For private repositories, you will need to use ssh cloning; so always adopt the rule below too.

Never Clone a Fork Directly

If you fork a repository, always clone the origin first. As an example. I have a fork of InfluxDB. I clone this with git clone https://github.com/influxdb/influxdb . I then add my fork as a remote with git remote add rawkode git@github.com:rawkode/influxdb . Now, when you've made your awesome changes to some OSS project; you push with git push rawkode .

Simples! 🎉

Tip: GitHub has a cool CLI command called gh that allows you to fork repositories you've cloned with gh repo fork . It automatically adds your fork as the "origin" and renames the canonical source to "upstream". You can change this behaviour with the --remote-name flag.

Working with Git

Now that I've got lots of code available to work on, how do I work with it?

GPG Signing

Edit I don't encourage using Keybase any longer. Signing commits with SSH keys is now possible, since Git 2.34 . This works really well when tied to TPM modules on your computer, such as using Secretive for macOS.

I always ensure that I sign my commits with my GPG key. If you aren't comfortable provisioning your own GPG key, checkout Keybase. Very little is required to configure GPG signing. Some people specify their key in the config, but as I only have one secret key available locally, as you probably will too, it's not required.

toml
[gpg]
  program = gpg
[commit]
  gpgsign = true

Commit Template

My Git commits are terrible. I've been using a template lately to remind myself when the commit screen pops up that I should do better.

toml
[commit]
  template = ~/.git/templates/commit

I've got an old template that I've used for years, but more recently I've been trying to adopt Semantic Commits , such as:

text
feat: add hat wobble
^--^  ^------------^
|     |
|     +-> Summary in present tense.
|
+-------> Type: chore, docs, feat, fix, refactor, style, or test.

Default Editor

I use VSCode for all my editing now, even Git commits 🙂

toml
[core]
  editor = code --wait

Aliases

Here are some of my favourite aliases.

Pull

I really like dislike merge commits. So much so, I always do a pull with a rebase to neatly, and cleanly, merge in missing changes; keeping my commits at the top.

toml
[alias]
  pl = pull --rebase

Cane

Ever committed something and forgot to add a file? Ever committed a fix that wasn't actually the fix and then had to add a new commit with the actual fix? Yep. You need git cane . This will add / stage changes and add them to your previous commit.

toml
[alias]
  cane = commit --amend --no-edit

The Rest

These are all rather simple short cuts.

toml
[alias]
  cm = commit -v
  co = checkout
  ps = push
  st = status 

That's it! That's "How I Git" 🙂

If you found this useful, let me know on Twitter and I'll follow up some with new Git tips.

Thanks for reading 👋🏻