Git was released on April 7, 2005, which is exactly 20 years ago! To celebrate this milestone, I have compiled 20 git tips helping you to become a more effective gitter!

I also did the same on git's 16th and 17th birthday, but I missed the time git could start drinking alcohol:

The tips are not in any particular order, and vary from beginner to advanced. I hope you find them useful!

Git's 20th birthday


0. Set Up Your Personal Info Properly

Start by configuring your name and email globally:

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

Also, you can configure these per repository if you need to use different emails (e.g., work vs. personal):

git config user.email "work.email@company.com"

Bonus: Set up GPG signing too to verify your commits! Signing makes your commits more secure, as it verifies that they were made by you. To learn more, you can refer to my book Docker and Kubernetes Security.

Free Chapter - Docker and Kubernetes Security Book | Mohammad-Ali A'RÂBI

🚀 Exciting news! You can now download the first chapter of my book, "Docker and Kubernetes Security," for FREE! 📘 This chapter introduces you to the fundamentals of containers, Docker, and Kubernetes, covering: ✅ The history of Docker and Kubernetes ✅ Key container concepts like namespaces and cgroups ✅ The difference between containers and virtual machines ✅ Running containers and working with images ✅ An introduction to Kubernetes core components (Pods, Services, Deployments) ✅ A hands-on guide to basic Kubernetes operations I'd love to hear your thoughts—let me know what you think! #Docker #Kubernetes #Security #DevSecOps #CloudNative https://lnkd.in/dw6KXc-d

favicon linkedin.com

1. Use .mailmap to Clean Up Author Names

Git tracks authors by name and email. It's possible that someone mistakenly committed with a different name or email. This can clutter your commit history.

In this situation, we can use git's mailmap feature to unify them. Create a file named .mailmap in the root of your repository and add entries like this:

Proper Name

Now git shortlog and other commands show clean author lists.

Learn more about mailmap here:


2. Always Branch for New Features

Avoid committing directly to main or master. Create small topic branches for features and fixes:

git switch -c feature/new-login

I would personally use my GitHub handle, issue number, and a short description for the branch name:

git switch -c aerabi/1234-new-login

You can later mention the issue number in the commit message, and GitHub or GitLab will automatically link it to the issue. You can also close the issue automatically by adding Fixes #1234 in the commit message:

Add new login page

Closes #1234

Committing like this, the readers can later get the context of the commit by looking at the issue.


3. Cherry-Pick Commits Across Branches

If you want to get one commit from a branch to another one, you can use cherry-picking. First, note the commit hash you want to cherry-pick. This is done by doing a git log and copying the hash of the commit you want.

Then, switch to the branch you want to apply it to:

git cherry-pick

The commit is added to the new branch, and you can continue working from there.


4. Cherry-Pick Commits from Another Repository

You can even cherry-pick commits from another repo:

git remote add other-repo 
git fetch other-repo
git cherry-pick

Remove the remote afterward if you want.


5. Use git switch and git restore Instead of git checkout

Checkout was an overused command back in the day. It was used for switching branches, restoring files, and more. Now, we have git switch and git restore to make things clearer:

git switch branch-name         # To switch branches
git switch -c new-branch       # To create and switch to a new branch
git restore file.txt           # To discard changes to a file
git restore --staged file.txt  # To unstage a file

It's more explicit and user-friendly!

Learn more about the new commands here:


6. Understand Three Types of Merge

  • Three-way merge: Regular merge that creates a merge commit.
  • Fast-forward merge: Happens automatically when there's no divergence, i.e. the branch is ahead of the base branch.
  • Squash merge: Combine all commits into one before merging (great for PRs).

In GitHub and GitLab, you can configure the default merge method for pull requests.

If you're not sure which one to use, use squash merge. It keeps the history clean and makes it easier to understand.

If you're a pro, make rebase and fast-forward your default merge methods. Then, before merging, rebase your branch onto the base branch:

git pull --rebase origin master

Using rebase and fast-forward, you should keep your feature branch history clean.

Learn more here:


7. Stage Changes Selectively with git add -p

Instead of staging everything, selectively stage chunks of changes:

git add -p

Interactive and safe!


8. Undo a Rebase Safely

If you mess up a rebase, you can undo it:

git reflog

Find the commit before the rebase started, then reset:

git reset --hard

Learn more about undoing a rebase here:


9. Interactive Rebase to Clean Up History

Use interactive rebase to reorder, squash, or edit commits:

git rebase -i HEAD~5

It's the secret to beautiful commit histories. Using interactive rebase, you can:

  • Squash commits together
  • Remove commits
  • Reorder commits
  • Reword commit messages

10. Speed Up Rebase with --autosquash

When adding a commit to fix a previous one, you can commit it as a "fixup" or "squash" commit:

git commit --fixup

When doing so, the commit message should start with fixup! or squash!, respectively. This allows you to automatically squash them during a rebase.

When doing an interactive rebase on commits, you can use the --autosquash option:

git rebase -i --autosquash

Git will move those commits automatically to the right place and mark them for squashing or fixing up.

Learn more here:


11. Handle Chains of Branches with --update-refs

If you branch from a branch and rebase the base branch, you usually have to manually rebase all dependent branches. Not with:

git rebase --update-refs

It automatically updates the child branches.

Learn more about this here:


12. Use git stash --keep-index

Need to stash only your unstaged changes? Use:

git stash push --keep-index

It leaves your staged work intact.


13. Make Empty Commits

Sometimes you want to create empty commits for testing or triggering CI/CD pipelines. You can do this with:

git commit --allow-empty -m "Trigger deployment"

If you're using them to create markers for deployment, you can use tags instead:

git tag -a v1.0 -m "Deployment marker for version 1.0"

14. Clean Up Untracked Files

Quickly remove untracked files (be careful!):

git clean -fd

Add -n for a dry run first:

git clean -fdn

This command will show you what would be deleted without actually deleting anything.


15. Fetch All Remotes Simultaneously

If you have multiple remotes:

git fetch --all

Very useful for forks.


16. View Visual Branch History

Use this to see a graph of branches:

git log --oneline --graph --all --decorate

You can also create an alias for it:

git config --global alias.graph "log --oneline --graph --all --decorate"

Then you can do:

git graph

17. Add Aliases to Save Time

Tired of typing long git commands? Add aliases:

git config --global alias.enforce "push --force-with-lease"

Now git enforce is equivalent to git push --force-with-lease, which is used to push changes while ensuring that you don't overwrite any changes made by others.

Never do git push --force!

More on this here:


18. Use git worktree for Multi-Branch Work

Instead of switching back and forth, you can check out multiple branches simultaneously:

git worktree add ../branch-folder branch-name

Worktrees are great for testing multiple branches at once without needing to switch back and forth.

19. Use git bisect to Find Bugs

If you have a bug in your code, you can use git bisect to find the commit that introduced it. This is a binary search through your commit history.

git bisect start
git bisect bad # The current commit is bad
git bisect good  # The last known good commit

Then, git will check out commits in between. You can test each one and mark it as good or bad:

git bisect good # If the commit is good
git bisect bad # If the commit is bad

You can for example run the tests to see if the bug is present. Once you find the commit that introduced the bug, you can reset the bisect:

git bisect reset

This will return you to the original branch.


20. Read the Previous Tips

Happy 20th birthday, git! 🎉

If you want to read more tips, check out my previous articles!


Which tip was new to you? Or do you have your own pro-tip? I'd love to hear!