Git the way I use it

And here comes the ultimate Git article … naw, it is only my modest collection of hacks, workflows and tips.

git tips

Branch naming schema

<prefix>/<ticket-id>-<concise-description>

Prefixes I like to use

  • fix --> smaller fix
  • hotfix --> needs to be deployed ASAP
  • bug --> hunting down bugs
  • feature --> new functionality
  • pre-rails4 --> changes to release before upgrading to Rails 4

Ticket ID

It can be useful in case of using a ticketing system like Jira. Or even referring to a branch when consulting with a colleague.

Concise description

Naming things is hard and yet very important.

Imagine an automated merge commit with the following message:
Merge pull request #513 from organization-account/feature/QB-413

What feature has been merged? All I can tell: it refers to a Jira ticket with an ID of QB-413.

Rename branch in local and in remote

If you are on the branch you want to rename:

git branch -m new-name
git push origin :old-name new-name
git push origin -u new-name

Manipulating the timestamp of a commit

If one accidentally makes commits at work on a public hobby project and for any reason one wants the world to believe that one did those commits after work in his free time:

time_stamp="2019.05.14 18:28:13"; GIT_COMMITTER_DATE=$time_stamp git commit --amend --date=$time_stamp --no-edit;

The power of rebasing

Given the following scenario: Developer A pushes new commits to the master branch. Developer B needs to pull those changes in order to push his new changes.

Options developer B has

  • pull with merge
  • pull with rebase

Pulling with merge

git pull <remote> <branch>

Git performs:

  • git fetch to pull the latest changes from the specified remote
  • git merge to join the received changes with the changes of the current branch

As a result we will have an extra merge commit and the history tree will have an extra parallel line.

enter image description here

Pulling with rebase

git pull --rebase <remote> <branch>

Git performs:

  • git fetch to pull the latest changes from the specified remote
  • reapplies the local changes on top of the incoming ones

As a result we will have a clean straight history line without any extra merge commit.

enter image description here

As always, rebasing is not a silver bullet, it is very useful for small changes, however merging can prove to be better for long term changes.

Set upstream for local branches

git push --set-upstream origin new-branch
This tells git to link your current local branch to the remote one. The change happens only locally. As a reward we don’t need to specify the origin and the branch name the next time doing a push, just type git push or use an alias gp.

Using multiple SSH keys

Common practice at work to have a separate corporate GitHub account for every developer. In my case I have my own personal one too and sometimes I fancy to pull code from my own repos. But in GitHub one SSH key can’t belong to two different accounts. As a solution I have two SSH keys, one for each accounts plus some extra config.

Global SSH config

# ~/.ssh/config
Host github.com-own
	HostName github.com
	User git
	IdentityFile ~/.ssh/id_rsa_own

Host bitbucket.org-own
	HostName bitbucket.org
	User git
	IdentityFile ~/.ssh/id_rsa_own

Local Git repo config in the project folder

Things to pay attention to:

  • For successful authentication we need to use the domain defined in the global SSH config:
    github.com-own
  • The local user config differs from the global one
# .git/config

[remote "origin"]
	url = git@github.com-own:tothpeter/development-cheat-sheet.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[user]
	name = Peter Toth
	email = tothpeter08@gmail.com

Command-line aliases

I use iTerm2 with Oh My Zsh including its Git plugin which provides tons of aliases out of the box.

Plus I defined the following ones according to my own taste:

Alias Command I use it for
gitx open -a SourceTree . opening current project in a Git GUI
gl git log --oneline --graph --all --decorate showing history in a visual branch
gr git remote -v listing remotes
gs git status seeing if there is any merging, rebasing etc going on
gp git push pushing current branch to origin
gpl git pull pulling the current branch from origin
gplr git pull --rebase pulling the current branch
gplm git fetch origin master:master pulling master from origin without changing branch
nah git reset --hard && git clean -df reverting back to a clean state by removing all untracked files and all changes
gu git reset --soft HEAD^ undoing the last commit keeping its changes

Mini workflow

Scenario: Developer A merges new changes into the remote master. Developer B works on a feature branch locally and wants to use the new changes.

Developer B can easily achieve it by using my beloved aliases:

  • gplm -> Pull remote changes to local master without changing branch
  • grbm -> Rebase current branch onto master

If you have any tips, please don’t hesitate to share!

Comments