Real-World Git Practices You Need to Know
Tags: git, github
Published: 2023-11-06 14:17:54

In this post, we will go through some real world git practices that can help your git workflow more efficient and organized. We'll cover tips like avoiding extra merge commits, squashing commits, syncing forked repositories, and using stash to save changes.

## Avoid Extra Merge Commits

We have a new branch `feature/something` ready and now needs go to production. To do this, we must first merge these changes to the `develop` branch and then merge `develop` with the `main` branch.

While we working on our feature branch other developers updated `develop` branch already. We need to make our branch up-to-date with `develop` branch.

Using traditional merge method will create an extra merge commit in your branch. Even, there could be multiple merge commits if `develop` changes frequently so you have to catch up with latest updates by making multiple merges.

The history of your branch will be unclear and hard to track. Instead of using traditional `git merge` we can utilize `git rebase` to avoid extra merge commits.

First, we need to pull the latest changes from `develop` branch.

`git checkout develop`

`git pull`

`git checkout feature/something`

`git rebase develop`

We used rebase to avoid extra merge commit in our `feature/something` branch. Rebasing will put `develop` branch commits under our `feature/something` commits. In other terms, our feature branch commits will be at the very top of commit log.

If there are merge conflicts, fix all of them and then run:

`git rebase --continue`

You might need to use `git push -f` to force push after rebasing.

And now you have up to date feature branch ready to merge `develop`. Create PR to develop and merge if all reviews passed.

## Override Previous Commit

If you have pushed a commit and then realized that you need to make a small change that should be included in the commit's context. You can use the `git commit --amend --no-edit` command to modify the most recent commit with the same message or `git commit --amend -m "<your message here>"` to override the message as well.

You might need to use `git push -f` to force push the overrides.

This will allow you to add the small change and update the commit message if necessary. This strategy can be applied, for instance, if you forgot to apply linting or add a comment or update the commit message and so forth. 

However, if you have already pushed the commit to a branch that maintained by multiple developers, you should avoid amending the commit as it can cause problems for other users who have already based work on the original commit. 

In this case, it's better to create a new commit that includes the small change and push that to the remote repository.

## Squash Commits

Sometimes, the number of commits in a pull request can become very large due to back-and-forth changes. This can make it difficult to manage the project, and if a rollback is needed, it can be a struggle to find a stable version where the feature or bug fix is spread out across multiple commits.

If you find yourself in a situation where there are more commits than necessary, try to squash them into a single commit and then merge it. You can find the **"Squash and Merge"** option in GitHub when merging the PR.

## Forked Repository

If you have forked a repository and worked on a feature or bug fix, and you are ready to create a pull request, you may find that your branch is outdated because the original repository has new commits. In this case, you need to update your branch to be up-to-date before you can create a pull request.

The steps to fetch the latest changes from original repository are as follows:

`git fetch upstream` - To fetch changes from the upstream repository (in this case, a forked repository) into your own local repository.

`git checkout master` - Check out the `master` branch or `main` to rebase it with upstream.

`git rebase upstream/master` - To apply the changes made in the current branch on top of the changes made in the `upstream/master` branch, effectively updating the current branch with the latest changes from `upstream/master`.

`git log` - (optional) To view the latest commits and compare them with the upstream (forked repository) to ensure they are aligned.

Now that you have an up-to-date master branch with upstream, you can create a new branch from it.

Alternatively, you can checkout your working branch and rebase it with your master branch now that it has been updated with upstream changes.

## Stash

Suppose you have made changes to some files, and you need to checkout another branch to review some changes or pull the latest commits. Before moving to another branch, Git will require you to commit your changes. 

However, if you are not ready to commit your current changes yet, you can save them as a stash.

`git stash`

Your changes will be saved in the stash list, allowing you to apply them later to any branch you want. To apply a specific stash, you can use the command `git stash apply <stash>` where `<stash>` is the name of the stash you want to apply. You can find the name of the stash by running `git stash list` and identifying the stash you want to apply.