Git is used by many people in many ways. I am sharing what worked for me!

These git rules achieve:

  • Make your life as dev easier, PRs that are approved quickly
  • Near zero merge conflicts
  • Clean history and logs
  • Ability to see every single line of code’s commit message and reasons for change
  • Easily rollback the code when issues or regressions occur in production

Basics

Think of your git usage as built of two concentric circles. On Inner circle, you modify code locally, and outer circle is when you modify your repo in GitHub or equivalent

Git workflow

Git workflow

Always prefer rebase over merge. These are two different algorithm to achieve the same thing, but rebase give a better history and fewer conflicts. In the world of CI/CD and the best practice of using small batches, the need for merge has been totally eliminated. You should almost always use rebase. Set it as default

1
2
git config --global pull.rebase true # For all repos
git config pull.rebase true # For the current repo

Create the child branch of the remote main in your local workspace. If you are using IntelliJ, try File→New→Project from version control. Otherwise use:

1
git clone <project URL>.

Create your local dev branch for development. Preferably name it “dev_{yourname}_{task/feature/bugfix}. For example:

1
git checkout -b dev_shobhit_unicorn

Commit your changes with

1
2
3
4
git commit -am "message" # includes all changed files in commit, one shot operation
# Or add files individually
git add <path to changed files>
git commit -m "message"

Use amend option to merge your changes to the last commit in the tree. This way, you can keep on adding on changes to the same commit

1
git commit --amend

Make changes only on the local dev branch, use the local main for the pull. Don’t pull changes directly from the remote main, it’s just a simple trick to make life easier.

Pull the change from remote main to the local main

1
git pull --rebase

Merge other’s changes to your dev branch - run from your branch

1
git rebase dev_shobhit_unicorn

Before you push and raise a PR, run the following to check whether your changes will merge cleanly with main

1
git merge --ff-only dev_shobhit_unicorn

If you couldn’t use amend, use this Stack overflow question to merge multiple commits into one. This is a rather involved interaction, but be patient and you would learn in no time. It’s a very powerful tool!

1
git rebase -i HEAD~{count_of_commits}

Use push your changes to remote and create a pull request.

1
2
3
git push -u origin dev_shobhit_unicorn # -u to create remote dev branch. Do it only for the first time

git push -f origin dev_shobhit_unicorn # Push your whole branch up

Pull requests

A pull request should only have one commit and should contain only one logical, but complete, unit of change. Nobody is interested in knowing the number of iterations it took you to complete a coding task. They are for your local branch. When you raise PR to main, squash them together in one commit.

A single commit allows a crisp commit message and makes any git workflow like revert/merge/rebase easier. Always merge commits together before updating the PR. You will thank yourself when you will have to revert one commit that caused regression.

Commit message

Visit How to Write a Git Commit Message now. At a minimum, people should be able to make a sense of why the change was made. Two steps are required:

  • Write the first line as the subject of change, like what we will miss if we do not take this commit.
  • Enter a blank line and then give a detailed explanation of the change.
  • If applicable, add relevant Issue link in the commit message.

A sample commit message from Linux Kernel code

Commit message

Merging to main

Only merge with rebase. This avoids an extra merge commit in history and keeps it clean. You can enforce this behavior by disabling “merge” and “merge with squash” from your GitHub repository’s settings page. Only git admins can do that, so if you don’t see settings tab on GitHub, contact the repository owner.

Additional commands

The following git commands are also very helpful in the day to day git interaction, please read about them before using!

1
2
3
4
5
6
7

git cherry-pick <commit_id> # Pick a commit from some other branch and merge them to your current branch
git push -f origin :<branch_name> # to delete remote branch.
git reset #Use this with care
git log --no-merges # clean view of history
git reflog --date=iso # When you lose a commit
git fsck --lost-found # When you *really* lose a commit

Additional reading

  • The difference between rebase and merge.
  • git for computer scientists.