24 tips for being more productive with git

I posted a tweet with a useful tip for #Git under the hashtag #GitVent every day before Christmas this year. The topics are completely mixed – from git aliases over Window Terminal to filter-repo.

I hope you enjoyed it. Let me know what you think.

Day 1: Git Aliases

Git aliases are a powerful way to help you to type less. Set an alias for commands that you often use.

$ git config --global alias.unstage 'reset HEAD --'
$ git config --global alias.last 'log -1 HEAD'
$ git config --global alias.graph 'log --oneline --graph'

Day 2: Multi-Line Aliases with Arguments

You can also run multiple commands in an alias. Use $1, $2, $3… and $@ for all arguments that are passed to the alias. This example creates a branch, commits all changes, pushes them to the server and creates a pull-request (PR) via the CLI and sets it ti auto-complete:

[alias]
mp = "!f() { \
	git switch -c feature/$1; \
	git add .; \
	git commit -m \"$2\"; \
	git push --set-upstream origin feature/$1; \
	git pr create --title \"$2\" --auto-complete --delete-source-branch; \
};f"

You would call this alias like this:

$ git mp Name-Feature-Without-Blank "Titel for Commit and PR"

For this to work you have to install the CLI from your Git Service (GitHub, Azure Repos…) and create a git alias to create a pr.

Day 3: A better diff experience

A nice tool to get better diffs on the command line is diff-so-fancy. It highlights the changes in the lines and help you spot the differences.

Install it with npm or homebrew and activate it in your git config:

$ git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"

Day 4: Autocorrect yout git commands

This tip is for all people like me that often mistype git commands. Activate autocorrect and git will automatically call the command that is closest to the one you typed:

$ git config --global help.autocorrect 20

Day 5: The git stash

The git stash is a temporary store for changes that you are not yet sure if you want to commit them to a branch or not. The stash is a LIFO list – last in first out. If you have changes in your stash you can directly create a branch out of them:

$ git stash push -m "My Changes"

$ git stash branch <branch-name>

Day 6: Search with git grep

Use git grep to search inside you working directory – or inside specific revisions.

Day 7: Check whitespaces and indentation

You can let git check your code files for whitespace rules. For example indentation (blanks or tabs), trailing spaces and so on. You can enable this using git config --global core.whitespace and set the rules separated by commas.

Day 8: Record your manual merge conflict resolution with rerere

With git rerere (Reuse Recorded Resolution) you can record manual merge conflict resolution and let git apply this resolution each time the conflict occurs.

$ git config --global rerere.enabled true

Day 9: Automatically fix whitespaces

If you have configured your whitespace handling (see day 7 and day 24) you can let git automatically fix it in a git rebase or git apply with the argument --whitespace=fix.

Day 10: Test individual commits with rebase –exec

You can test every individual commit in a branch using the git rebase --exec <test command> <ref> command. If you are using dotnet and you want to test all commits from the beginning you could run:

$ git rebase --exec "dotnet test" --root

Day 11: Use GitVersion for semantic versioning from git

Use GitVersion to create semantic versions from your git workflow. You can use tags, branch names, merge commit messages or a config files. This works not only in .NET. You can use it as a json document in all languages (Java, C++, JavaScript and so on).

Day 12: Append changes to your last commit with –amend

If you forgot some changes in you last commit you can add them using git commit --amend.

Day 13: Force-Push to a single branch

The git push is the critical moment when you have modified commits (rebase, amend, reset and so on). If you force push changes that other people have pulled and committed changes upon, this will result in a lot of conflicts. To make sure you only force-push to your own branch use the plus sign (+) before your branch name instead of the --force argument:

$ git push origin +<branch-name>

Day 14: Restore files in your working directory

Use git restore to restore files in your working directory.

In this tweet I mistyped the hashtag. Thats why I could not find my tweet and I created a special tweet for you (after day 21).

Day 15: Use the git time machine to travel back in time

Use the git reflog as your time machine to undo all changes – event rebases and resets.

$ git reflog
# look up index before the changes you want to undo
$ git reset --hard 'HEAD@{index}'

Day 16: Configure your default editor (or learn VIM)

In the comments to one of my tweets someone mentioned that he problems using vim – and exiting it. If you want to learn vim use vimtutor – and exit vim with :wq. If not configure another editor (I recommend Visual Studio Code):

$ git config --global core.editor "code --wait"

Day 17: Use Carbon to make pretty images of code

Do you like the images of my code I used for my tweets? They are dome with https://carbon.now.sh/.

Day 18: Use the new git version on Linux

Linux normally has git already preinstalled – but not the latest version. To get the latest version with apt you have to figure another repository:

$ sudo add-apt-repository ppa:git-core/ppa

Day 19: Use VSCode as a diff and merge tool

Visual Studio Code is a great diff and merge tool. Set it up im your .gitconfig like in the image in the tweet:

[merge]
  tool = code

[mergetool "code"]
  cmd = code --wait $MERGES

[diff]
  tool = code

[difftool "code"]
  cmd = code --wait --diff $LOCAL $REMOTE

Day 20: Rebase your changes when pulling from a remote

A git pull does a git fetch and a git merge in the background. You can change this behavior to a rebase: git pull --rebase. If you want this to be the default you can set it in your configuration like this:

$ git config --global pull.rebase true

Day 21: GitHub Mobile

GitHub Mobile is available for Android and iPhone. I’m really impressed how good pull-requests can be done from a mobile device. Check it out!

Special: Filter-Repo

When I thought I forgot day 14 I asked for a topic to tweet – and Sebastian asked me to post something on how to remove strings – like secrets – entirely from the history. Thats why I created the special about git filter-repo.

Install Filter-Repo with the package manager of your choice.

To remove text like passwords inside your code files you can use expressions. Just write your password inside a expressions.txt file and call filter-repo like this:

$ git filter-repo --replace-text expressions.txt

This will replace your password with the text ***REMOVED***.

If your secrets are in a separate file and you want to remove it completely you can use invert-paths:

$ git filter-repo --invert-paths --path secrets.txt

Day 22: Toggle Windows Terminal

If you use Windows Terminal you can toggle it if you pin it to the task bar. Just hold the Windows-key and push the number of the position in the task bar. I always have the terminal at position one – so WIN+1 toggles my terminal.

Day 23: Rename master

Since git 2.28 you can set the default branch to something different then master:

$ git config --global init.defaultBranch main

If you want to rename your branch in existing repositories use the git branch -m command:

$ git branch -m master main
$ git push -u origin main

Day 24: Different whitespace handling per file type

In the .gitattributes you can set different whitespace rules for each file type. The git can check these or automatically fix it (rebase or apply).

I hope you enjoyed the #GitVent and find some of the tips useful. If you want to read more about git – my book Git für Dummies will be available January 27th (in German only).

I wish you all a merry Christmas!

Leave a comment